by Dr. Peter Wayne
| You may have some carefully constructed field rules that you want your Xbasic program to respect. Can you keep those field rules, or are they lost? |
One of Alpha Five's great strengths is its large collection of field
rules, which let you do everything from case conversion to posting. When
you open a table with Xbasic, however, you override all of Alpha Five's
field rules except for the validation-level field rules and autoincrement
rules. But what if you don't want to rewrite the transformation rules or
posting rules? Can you make your script obey the table's field rules?
Let me illustrate the problem with a simplified inventory application
with 2 sample tables, stock and sales_from_stock. The stock
table has 2 fields, item, C3 and on_hand, N4. The sales_from_stock
table also has 2 fields, item, C3 and sold, N2. As sales
are recorded in the sales_from_stock table, the on_hand
quantity is automatically decremented by the amount recorded in sold.
The automatic updating of the on_hand quantity is done with a
simple Posting field rule in the sales_from_stock table:
Figure 1. Creating a Posting rule for the sold field.
The full posting rule is:
| Posting Option | Value |
|---|---|
| Table | stock.dbf |
| Field | Stock->on_hand |
| Target Linking Key | Item |
| Source Linking Key | Item |
| Operation | Subtract |
| Condition | (none) |
| Undo on Delete | Yes |
Table 1. Options for Posting field rule.
Let's enter a few items into the stock table:
Figure 2. Entries in stock.dbf.
Now we'll create a form for sales_from_stock and make an
entry:
Figure 3. An entry in sales_from_stock.dbf: the Sales_from_stock form.
After this entry is saved, the posting rule on sold will reduce
the on_hand field in the first record in stock from 30 to
27.
What if we need to make entries into sales_from_stock from an
Xbasic program? This script is a fairly straightforward way to make the
same entry as shown in Figure 3:
dim sales as p
sales=table.open("sales_from_stock")
sales.enter_begin()
sales.item="001"
sales.sold=3
sales.enter_end(.t.)
sales.close()
Script 1. Table-level entry into sales_from_stock.
The problem with Script 1 is that our posting rule is no longer
enforced. We would have to explicitly code the posting to the stock
table. In this example, it would not be a very big effort to code the
post, but under other circumstances it could be burdensome:
Wouldn't it be simpler if we could just make the Xbasic script recognize
the field rules? Well, we can. If we use
the form-level entry methods, then Alpha Five believes that our Xbasic
script is simply another user. We'll write an Xbasic script to open
the Sales_from_stock form, make a new record, and close the form:
f=form.load("Sales from stock")
f.new_record()
f:item.value="001"
f:sold.value=3
f.commit()
f.close()
Script 2. Form-level script to enter a new sale.
Compare Script 2 to Script 1. If you run Script 2 you will see that it
physically displays the form, fills it out, and then closes it. When this
script runs, the posting rule is executed.
You may find the temporary displaying and filling out of the Sales
from stock form distracting (I do!). You can eliminate most of the
distraction by using the command, ui_freeze(.t.), which prevents
the display from being updated. Here is the final script:
ui_freeze(.t.)
f=form.load("Sales from stock")
f.new_record()
f:item.value="001"
f:sold.value=3
f.commit()
f.close()
ui_freeze(.f.)
Script 3. Enter a new sale and prevent display of the form.
There is still a bit of screen flicker at the ui_freeze(.f.)
command, but the Sales from stock form is not displayed.
| Alpha Five v. 4 enforces field rules differently. |
Now for the good news. In Alpha Five v. 4, it won't be necessary to use the form-level new_record() and commit() methods to enforce field rules. You can use the table-level record entry methods, enter_begin() and enter_end(), with any table that has an associated form. So we can rewrite Script 3 as
dim f as p
dim sales as p
f=form.load("Sales from stock")
sales=:Sales_from_stock:Tables:Sales_from_stock.this
sales.enter_begin()
sales.item"001"
sales.sold=3
sales.enter_end(.t.)
f.close()
Script 4. An Alpha Five version 4 script that respects field rules
In the second line of Script 4, the first :Sales_from_stock:
refers to the form which has been loaded. That form in turn
contains a :Tables: object, which is in itself a container for the
Sales_from_stock table. Adding the final this attaches the
sales pointer to the sales_from_stock table.
It's not just posting field rules that can be enforced by these
techniques. By writing to an invisible form or by accessing the tables
associated with an invisible form, you can force Alpha Five to execute
transformation rules (such as case conversion), default value rules, and
even custom record and field-level event scripts. Now that
is power!
7/24/98 - pkw
Don't forget, we need your feedback to make this site better!