Need to retain the form's state on Delphi 7 - delphi-7

I'm currently working with Borland Delphi 7 and I need to retain the Checkboxes on a Form checked when I close it, for the next time the user wants to make a new filter.
Edit:
I have a form, "ordenes de servicios" that shows me Service Orders and their stats. I have many filters, and the date filter option opens up a new form, with checkboxes, so I can choose options as "begin date", "end date" and such. This form, "filtroDatas", when closed send for the "ordenes de servicios" a String that, roughly explaining, is a "WHERE" clause for a query in a Oracle Database. Currently, "filtroDatas", when closed, does not retain the checkboxes and dates used before, but i need to make it retain them. Looking up for data sheets on how the .FormClose works, i have the "caHide" option to just "hide" the form, but it does not retains information. The caMinimize is an invalid option, because the form should "dissapear" from sight.
Note: This is a legacy code that I can't alter too much. I though to do some reverse engeneering, but how the form is summons
procedure TfrmFiltrosData.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
(Owner as TfrmOrdensDeServico).HabilitaDesabilitaTimers(True);
qryFiltrosOs.Close;
Action := caHide;
//frmFiltrosData := nil;
end;
I tried caMinimize as well, but it didn't work.
Can some one shed some light on the matter?

As I understand it, you want to remember the checked status of various check boxes and other information such as dates.
One method, and I stress one method but not the only method is to use an Ini Files.
For example, in your Form Create you can read in the previous data like this;
PROCEDURE TForm1.FormCreate(Sender: TObject);
VAR
MyIni: TMemIniFile;
BEGIN
MyIni := TmemInifile.create('inifile.ini');
WITH MyIni DO
BEGIN
TRY
checkbox1.Checked := readbool('Checkboxes_State', 'CheckBox1', False);
checkbox2.Checked := readbool('Checkboxes_State', 'CheckBox2', False);
checkbox3.Checked := readbool('Checkboxes_State', 'CheckBox3', False);
FINALLY
free;
END;
END;
END;
Note that I have not included a full path for the ini file, you should.
The above reads the SECTION, ID, VALUE and sets a default value if it doesn't exist.
If you want to save the status of your check boxes, edit boxes, or whatever, in your Form Close do something similar to this;
PROCEDURE TForm1.FormClose(Sender: TObject; VAR Action: TCloseAction);
VAR
MyIni: TMemIniFile;
BEGIN
MyIni := TmemInifile.create('inifile.ini');
WITH MyIni DO
BEGIN
TRY
writebool('Checkboxes_State', 'CheckBox1', Checkbox1.Checked);
writebool('Checkboxes_State', 'CheckBox2', Checkbox2.Checked);
writebool('Checkboxes_State', 'CheckBox3', Checkbox3.Checked);
UpdateFile;
FINALLY
free;
END;
END;
END;
When your form is created the values are read and when you exit the status is written.
NOTE:
TMemIniFile requires you add Uses IniFiles to either your INTERFACE or IMPLEMENTATION section, depending on your needs. In the case of the above examples I've used IMPLEMENTATION.
There are various other methods associated with TMemIniFile;
ReadString / WriteString
ReadDate / WriteDate
ReadInteger / WriteInteger
You can also read an entire section in one go if need be.
With regard to dates, as David has explained in this answer Delphi inifiles ReadDateTime you need to be aware of local format settings. Dates can easily screw things up if you think you're working with a MONTH but are actually fiddling with the DAY.
If you consider later upgrading your app to run on a Mobile platform you might want to consider XML Files.
I hope this has been helpful. I have a feeling I've forgotten something, but someone will point it out if I have.

Related

Modifying graphical elements with PL/SQL - Oracle Apex

I am currently trying to migrate Forms' Applications developped ten years ago to Oracle Apex. For some context, the database in which Forms applications are currently running is the Oracle EE 6i, and will be soon upgraded to the 12.2g, hence the need for migration. The data stored within the tables is to big to migrate (like 4To) so we need an alternative to Forms, but we cannot change the DB, and cannot keep Forms (which is let's be honest, outdated a little). I am currently on Oracle XE for my tests and on Apex 20.2.0.00.20 to start my migration (before upgrading).
The thing is, I have some issues with how Apex and Forms are working differently.
I am really blocking on the following issue since my migration:
In Forms, it was really easy to change the color of a button for exemple by calling a Forms method in a certain way depending on a condition (for exemple a SELECT return). Here, in Apex, I am trying to do the same.
I know that there are ten other ways of doing the same, with JS for exemple which I already succeedly do, but when I tried to create my second appplication I realised that compared to Forms, Apex cannot reference/generalise parts of the code(or applications) for different applications (and certainly not for different workspaces). So Javascript is a good solution but not as efficient as PL/SQL which is easier to generalise and will (in my opinion) use less exchange between the db and the client, since stored on the db.
That is why I decided to rely on PL/SQL Stored Procedure which will be specified in the database and called directly in each application where I need the process/computations.But I cannot find the same as in Forms, with my graphical methods helping me do what I need.
I am open to alternative of PL/SQL package/procedure/function if it can keep the same propreties (generalisation and minimum echange between client and db). These are important point since I have around 200 applications to migrate, starting with what we can call 'brick' which will compose the other simpler applications.
Btw: CSS is an option I studied, like HTML with PL/SQL dynamic content but I read that it was either not simple enough to integrate, or that it could be deprecated, so if it is the solution you are using, I could use a really detailled explaination or an exemple.
To give you an instance:
I click on a button triggering a PL/SQL stored procedure
Procedure checks some conditions in the db (like if a process is currently running)
PL/SQL update a table, change a variable in procedure and returns 'green'
The button becomes green, a message is displayed ('You have permission to do this!')
PS: if there are Apex Method modifying the graphical aspect, could I have a documentation ?
Thank you a lot for helping me resolve this issue, I have been stuck for days...
I tried Javascript bu the generalisation was too much a problem. I tried the HTML injecting but didn't work, I tried updating CSS but was not what I expected. I tried different PL/SQL method but couldn't find a way to connect PL/SQL with Apex/CSS/HTML...
It takes a bit of getting used to how APEX works, but everything can be done and once you get up to speed, you'll find there pretty simple ways to get things done. To achieve what you describe, this is what you'd do.
Create a dynamic action on click of button
Add the following actions to the dynamic actions
an action of type "execute pl/sql". This is your "Procedure checks ...". In this pl/sql code you can set page item values (make sure to reference those in "items to return" so the new values is set in the session. There is no reason to have 2 different pl/sql procedures, you can just put them in 1 block. This procedure would return the "green" - but more about this later.
an action to add a class to the button under certain conditions.
Note that the "green" is not something you should decide. In apex, there are a lot of layout modifier classes pre-defined. In your case, it makes sense to use the "success" modifier (which happens to be green).
To check how you want the button to look, there is a tool called the "button builder", you can use that to see what classes you should add/remove to change the look of the button.
Note that 20.2 is not a recent version. It was released in 2020. Since then 4 more releases have been made available: 21.1,21.2,22.1 and 22.2. It is advised to be on the latest version.
Here is a basic example. I have a page with a select list (P117_SELECTLIST), a hidden item to hold the button status (P117_BUTTON_STATE) and a button (MYBUTTON). The select list has 2 static values:
The dynamic action for serverside code is :
Note the items to submit and return values. P117_SELECTLIST is submitted so the pl/sql process picks that up from the client and P117_BUTTON_STATE is returned to the client so it is available for any future use.
Then I have 4 classes to set the button style. One to add success class, one to remove success class, one to add warning class, one to remove warning class. Below is the first one. The only think different in those 4 actions in the class name and the client condition. It can probably done with javascript directly as well with only 1 action.
I'd strongly suggest to update the db version to a version that supports the latest version of apex. It will save you a lot of development worries. Most people of forums only have the latest version available.

APEX - Switching to a page through code

i am currently writing an apolication in ORACLE APEX, i am writing some validation on a login so that when you enter your username and password and click submit it will check to see whether you have changed your password,if yes then it will direct you to the main front page however if not i want it to link to a change password page, i currently have some code which looks like:
BEGIN
FOR c1 IN (SELECT user_name FROM wwv_flow_users) LOOP
IF APEX_UTIL.CHANGE_PASSWORD_ON_FIRST_USE(p_user_name => c1.user_name) THEN
htp.p('User:'||c1.user_name
||' requires password to be changed the first time it is used.');
/*f?p=&APP_ID.:8:&SESSION;*/
END IF;
END LOOP;
END
however i am unsure as to how correct this is, as I am rather new to the topic, this is what i have picked up from looking at oracles API's and from looking round other sources to try and come to a successful conclusion.
Any help would be greatly appreciated
Many thanks
J
You're mixing two different Apex features: validations and branches.
If you want to check for a data entry error, you use a Validation - and generally the same page will be returned to the user so they can correct their error.
If you want to branch to another page, you use a Branch. If you want to branch to different pages depending on a condition, you can create multiple Branches, each with a condition. The first branch that satisfies its condition will be used.
In addition, if you want to do some processing before the branch, you create a Process. Typically a Process is run after the validations are done but before the branches are done.
In your case, you could put your code in a Process, and set a hidden item with a flag that is used by the Branches to work out which page to branch to.

apex retrieve default item value

Is it possible to get default item value using plsql? I have a validation and in case it fails I want to reset item to its default value.
I tried using apex_util.set_session_state('P_ITEM_NAME', null) but that did not have any noticeable effect.
How can default item be retrieved or item itself be reset?
When creating a page process, there is a condition called "Inline validation errors displayed", maybe this will help? In this process you can reset items to null, then when page loads, item values will return to their default values.
UPD:
Create process:
Process Point: On Load Before header
Condition: Inline Validation Errors Displayed
Process source:
begin
for i in (
select t.ITEM_DEFAULT, t.item_name
from apex_application_page_items t
where t.application_id = :APP_ID
and t.page_id = :APP_PAGE_ID
) loop
apex_util.set_session_state(i.item_name, i.item_default);
end loop;
end;
This will return all page items to their default values.
This solution some ugly, but i don't know another solution for this problem.
:P_ITEM_NAME := null;
The difference here is the ":" infront of the item. Using it like this will give access to the item. Using apostrophes isn't needed I believe.
If this doesn't work with your version try without the ;.
So you can use:
:P_ITEM_NAME
To get the value.
I could not find any function that would return me default value using an item. However I could use default item setting to mimic this. Page processes do not run when page has validation errors, so I added conditional page process that performs the same checks as my validation and when these checks indicate that validation fails it just clears item state.
This is ugly as it requires checks to be duplicated and it seems that it is necessary to replicate almost same page controls through all pages where such reset mechanism is necessary.

Oracle Forms Builder - change to window in another form

We have two forms so far, and need to switch from window1 in from1 (which is login screen) to windowX in formX using button (trigger code below):
begin
show_window('windowX');
go_block('some_block_in_formX');
end;
This gives error FRM-41052: Cannot find Window: invalid ID
So question is, should I add formX into show_window parameter in certain way or is there another approach? Thank you.
Please note, that forms are in different files.
that forms are in different files.
If the forms are different files, you need to call the other form using open form/call form/newform - whatever suits your needs.
show_window/go_block sequence can be used only when you're moving to different windows/blocks of the same form - and the error message
error FRM-41052: Cannot find Window: invalid ID
is complaining that it can't go to that Window because it's in a different form.
Each form effectively has a private namespace for all its windows, blocks, items, etc - and your code always runs within the context of a single form.
To solve this, you'll need a form parameter, plus some code in the other form, e.g.:
in formX, add a parameter ACTION
in form1, pass the value 'XYZ' to ACTION
in formX, in the WHEN-NEW-FORM-INSTANCE trigger, check if :PARAMETER.ACTION = 'XYZ', and if so, do your show_window and go_block. Copy the same code to your WHEN-WINDOW-ACTIVATED trigger.
Of course, you'll need to think about the name of the parameter (e.g. ACTION) and value ('XYZ') that will make sense to people maintaining your forms in the future.

Getting a blank data report vb6

I am new to vb6. I am working to create the invoice generation application. I am using data report to show the generated invoice.
The step by step working of process is:
Entering the data in to Invoice and ItemsInvoice tables.
Then getting the maxId using (Adodc) from the data base to show the last generated Invoice.
Then passing the max Id as parameter to the data report which is showing the invoice according to the invoice id.
It is working fine when I first time generate invoice. Now for 2nd invoice without closing application I am getting a blank data report. For data report I am using dataenvironment.
I am guessing the reason the data report is blank is because there was no record for that Id, but actually the record is inserting in the database.
What is going wrong?
I'm not sure how your data set is getting configured, but it sounds like you have a single record in the data and aren't reloading it properly. If your report is manually moving through the recordset and only showing info based on the ID parameter you are passing it and then using the same recordset for the second report, you probably just need to MoveFirst on the recordset to put it back at the beginning.
Load the data environment and refresh the data report.
I am also generating report in the similar fashion. I faced this problem. Here's the solution
Load DataEnvironment1
With DataEnvironment1
'Command1 is the command added to data environment where you fire query or
'set it to point to a table
If .rsCommand1.State <> 0 Then .rsCommand1.Close
.Command1 maxid 'parameter you pass to the recordset
End With
DataReport1.Refresh
DataReport1.Show
Thats it!
You are done. I m sure it will work. Do tell me if it doesn't.
I don't know if the answer will still bother you, but if someone else have the same problem here is a example of how the problem works:
Imagine that there is a gate and a guard looking who is entering, when the first person (the first invoice) comes, the guard registers him, opens the gate (This is the event "Load DataEnvironmet") and then lets the guy pass. The guard believes that no one else would come and lets the door open (the instruction believes that the DataEnvironment ends and the value EOF becomes True), but when the second guy comes (the second invoice) the guard can't ask him who is (has, again, the value and lets it pass without registering him (this is the reason why the second invoice, and subsequent in while invoice would come blank). The solution is to close the gate ("Unload DataEnvironment") after a guy passes (After showing the data report).
The solution is the code given from Sangita above, but just before ending the sub you need to unload the DataEnvironment you were working on.
For me, it works. Sorry if the answer is not what you were looking for (and also if someone else can't understand what I'm writing, my English isn't very good). Just in case I will write the code with the solution
Load DataEnvironment1
With DataEnvironment1
If .rsCommand1.State <> 0 Then
.rsCommand1.Close
End If
.Command1 Value(ID)
End With
DataReport1.Refresh
DataReport1.Show
Unload DataEnvironment1
Try a refresh method like data1.recordset.requery or
Data1.refresh. This should work if you use data controls.

Resources