| Subject |
Re: Calculated Field Question |
| From |
Norman Snowden <duluth@msn.com> |
| Date |
Mon, 28 Nov 2022 12:09:19 -0500 |
| Newsgroups |
dbase.getting-started |
Mervyn, thanks to you, Andy and Akshat for your generous response to my calculated field problem. Mervyn, your crystal ball was clear. With this information I should be able to resolve my problem of mixing XDML and OODML code. Interestingly enough, I still have an old computer using Microsoft XP. This original program is loaded and still works fine usig Borland's 16 bit dBASE. Several years ago I used the dBASE modifcation function to modify it to run as 32 bit. It seemed OK, but later I had to change it to include OODML. I am presently working on a particular part of the program.
Thanks again, Norman
Mervyn Bick Wrote:
> On 2022/11/28 06:29, Norman Snowden wrote:
> > I am trying to transfer and use the values of calculated fields ftpmt and stpmt which are generated in pushbutton1 for use in pushbutto2. The values check out OK at the end of pushbutton1, but at the beginning of pushbutton2 the values should be 997.95 and 0 but are an extraneous 5.11 and an inverted 997.95. The ftpmt and stpmt entryfields are included in the Table and data linked.
> >
> > The calculated fields are not shown as rows in the Table and apparently cannot be saved as I tried. They are shown on the Form as non enabled entryfields.
> >
> > I even tried Using m->ftpmt and m->stpmt stored as public variables temftpmt and temstprt in pushbotton1 to be retrieved for pushbutton2. This did not work, the results printed out a 0 0.
>
>
> https://assets.amuniversal.com/d9b7baf032dd013bcb91005056a9545d
>
> I'm afraid the crystal ball is a bit cloudy this morning. :-) While I
> think I know what the problem is I'm having to make some assumptions.
>
> Normally "calculated field" means a field in a rowset that is not
> actually in the table. The field for the rowset is created in the
> query's SELECT command or by adding a field to the fields array and then
> using the field's beforeGetValue event handler to populate it. A value
> is calculated from values in fields actually in the table as each record
> is added to the rowset in memory. Such calculated fields are read-only
> and one can't save changed values to them.
>
> Reading between the lines (or between the clouds in the crystal ball or
> simply from the fact that trying to write to read-only fields would give
> an error :-) ) I assume you actually have blank fields ftpmt and stpmt
> in your table and want to save values that have been calculated in your
> form to these fields. If this is the case we can move on.
>
> The notation m->ftpmt is used in XDML to distinguish between a memory
> variable ftpmt and a field ftpmt in the workarea. Using workareas and
> queries in the same form can be done but as it can lead to problems it
> should really be avoided. I'm assuming you have not used workareas in
> this form and the m->ftpmt is just "force of habit" coding. If I'm
> wrong this will need to be looked at.
>
> Now that you are using OODML you need to rethink some programming
> techniques.
>
> Memory variables have their place but you should try and limit their use
> to within the function where they are used i.e declare them as LOCAL at
> the top of the function. This is NOT written on tablets of stone but you
> should never have problems if you stick to it except where you need to
> use the & macro operator to access the contents of a variable or if you
> need to check the type of a variable. Have a look at the entries for
> LOCAL and PRIVATE in the help file. If you don't specifically declare
> them as LOCAL they are created as PRIVATE by default.
>
> Global variables were best avoided when programming using XDML. They
> should be avoided like the plague with OODML. Just because dBASE still
> makes them available doesn't mean you should use them. If you ever need
> to make values available to other forms in your application rather use
> user-defined properties of the _app object.
>
> To make a calculated value accessible throughout a form save the value
> to a user-defined properties of an object. Usually one would use a
> user-defined property of the form but you could just as easily use the
> object on the form which triggered the function that created the value.
> Where you save the value affects how you retrieve the value as you need
> to specify which object the property belongs to.
>
> In this specific case you have already saved the value to the rowset and
> also made an explicit save() to the table so you don't need to keep the
> value elsewhere.
>
> You code needs to look something like this.
>
> function PUSHBUTTON1_onClick
> local ftpmt, stpmt
> //code to place values in ftpmt and stpmt
> form.lqactsch1.rowset.fields["ftpmt"].value = ftpmt
> form.lqactsch1.rowset.fields["stpmt"].value = stpmt
> form.lqactsch1.rowset.SAVE()
> form.ftpmt = ftpmt //assign to user-defined property of form
> //if the values are only going to be saved to the table later
> form.stpmt = stpmt
> //alternatively assign to user-defined property of pushbutton1
> this.ftpmt = ftpmt
> this.stpmt = stpmt
> return
>
> function PUHBUTTON2_onClick
> local ftmpt, stpmt
> Clear
> ? form.lqactsch1.rowset.fields["ftpmt"].value
> ? form.lqactsch1.rowset.fields["ftpmt"].value
> ftpmt = form.lqactsch1.rowset.fields["stpmt"].value
> stpmt = form.lqactsch1.rowset.fields["stpmt"].value
> //alternatively, if values were save to properties of form
> ftpmt = form.ftpmt
> stpmt = form.stpmt
> //alternatively if values were saved properties of pushbutton1
> ftpmt = form.pushbutton1.ftpmt
> stpmt = from.pushbutton1.ftpmt
> //code to process ftpmt and stpmt
> return
>
> The problem with event driven code is that the programmer has no control
> over what the user does. Your code needs to take into account that the
> user may click pushbutton2 before pushbutton1 in which case there won't
> be values in the two fields.
>
> function PUHBUTTON2_onClick
> local ftmpt, stpmt
> Clear
> ? form.lqactsch1.rowset.fields["ftpmt"].value
> ? form.lqactsch1.rowset.fields["stpmt"].value
> if form.lqactsch1.rowset.fields["ftpmt"].value <> 0 and ;
> form.lqactsch1.rowset.fields["stpmt"].value <> 0
> //Assumes both values would not normally be 0
> ftpmt = form.lqactsch1.rowset.fields["ftpmt"].value
> stpmt = form.lqactsch1.rowset.fields["stpmt"].value
> //code to process ftpmt and stpmt
> else
> msgbox('ftpmt and stpmt have not been calculated yet')
> endif
> return
>
> Mervyn
>
|
|