John,
While Paradox supports calculated fields, the results are generated on the fly, e.g as you select new record, modify field values, and so on.
As rbooker points out, you need to add some code to your form to save the result of the calculated field into your table when it updates.
However, due to the way the event model works, it's a two step process: Detect the change and then save it to the table.
There are a number of ways to approach it (as well as a number of issues to work with). Here's a very simple demonstration:
1. Change your working directory to the one containing the samples provided with Paradox, e.g. the one containing LINEITEM.DB.
2. Create a new form and place LINEITEM in the data model. Accept all defaults.
3. Add a field to the form and define it as a calculated field with the following calculation:
Code:
[LINEITEM.Qty] * [LINEITEM.Selling Price]
Consider changing the label to something like "Calculation" to keep things straight visually.
4. In the newvalue event of your calculated field, add the following code:
Code:
if Total.locked then
self.postAction( userAction )
endif
5. In the action event of your calculated field, add this code:
Code:
var
numTotal Number
endVar
if eventInfo.id() = userAction then
numTotal = Qty.Value * Selling_Price.Value
if numTotal <> Total.Value then
Total.Value = numTotal
endIf
endIf
6. Save and run your form.
If you change the selling price or the quantity of an item, the total will update. Note that you have to move off the field for the value to update.
Now, you need to be careful when you do this. It's very easy to wreak havoc with the event model. This example avoids that in two ways:
1. The update code is not triggered unless the record is actually locked, e.g. the Locked property of the Total field is TRUE.
2. The update process is not executed until after the events that triggered it (e.g. your movement) has processed. This is done with postAction(), which tells Paradox to trigger an event after it's done doing whatever it thinks it needs to.
Having said all that, this isn't the most efficient way to implement this. A better approach is to design your form so there is a record object containing the Total field. Put another way, you should be using a table frame or a multi-record object (MRO).
As you might expect, the Record object lets you control the way Paradox reponds to record oriented events, such as saving changes to disk and so on.
Once you've got a record object to work with, you'll want to rework this to:
a) Always trigger a dataPostRecord when Paradox attempts to save changes
b) Update the underlying Total field when changes to the record are saved.
You can do both by adding code to the record object's action event:
Code:
var
siAction smallInt
numTotal number
endVar
siAction = eventInfo.id()
switch
case siAction = dataUnlockRecord :
self.action( dataPostRecord )
case siAction = dataPostRecord :
doDefault
numTotal = Qty.Value * Selling_Price.Value
if numTotal <> Total.Value then
Total.Value = numTotal
endIf
endSwitch
You can use this approach instead of the earlier one, however, the totals will only update when the record is saved. Most users prefer to see the total update on the fly.
If you simple can't use a Table Frame or an MRO, you can also do this on the Form's action() event, but it gets more complicated because you have to determine the table that generated the unlock request.
Generally, it's best to always use a Table Frame or MRO whenever possible.
As I said, it's simple request with a lot of considerations.
Hope this helps...
-- Lance
P.S. The code is off the top of my head, so there might be a typo or two. Apologies in advance.