Hi,
I have found the parent/child form works best when combined with some compilmentary functionality like persistent relationship, table buffering, transactions, and referential integrity. To have this functionality available the tables must be in a database container. This all works together if you have your parent/child table set up in a database container, have a persistent relationship defined, are using table buffering wrap in transactional processing.
When you begin a transaction in the child table by pressing the edit button, this starts a transaction. If buffering is set to optomistic 5 table buffering, you can add as many transaction as you like and until they are committed they will have a negative record number (e.g. -1, -2, -3, etc.) When the user finishes he can select the revert button to cancel all entries and a table revert occurs with rollback. If the user selects the save button, a table update is performed. If the tableupdate returns .T. an end transaction occurs and your done with that entry. If the tableupdate returns .F. then a transaction rollback occurs with an error message indicating a trigger failed error.
I think this is kind of how it works.
Consider the following code:
select the_child_alias
set EXCLUSIVE off
set MULTILOCKS on
=cursorsetprop("Buffering",5)
&& no need to set up a relation to the parent because there is a parent
&& child persitent relation already defined in the DBC. This is for referential
&& integrity checking only. In all other situations you must define the
&& relationship between parent/child.
do while .T.
begin transaction
&& this is where you would get input for the insert below
insert into the_child_alias (main_key,descript,amount) values ;
(1111,"payment",150)
&& Note, if the insert was not wrapped inside a transaction, and the
&& main_key did not reference back to a valid parent record, the insert
&& command would fire a trigger calling RI code in the DBC and the
&& record would not be inserted and an error message "trigger failed"
&& would occur at this point.
lee=tableupdate() && trigger fires
if lee=.T.
wait window "success"
end transaction
exit
else
wait window "Please go back an enter a correct main_key"
rollback
endif
enddo
Transaction processing is great where you must create many transaction like a payroll run. A table update could be issued after each record is insert. If all record insert correctly, then an end transaction can be issued. If any transaction fails, a rollback can be done. This avoid messy situations where you don't know which transactions commited and which transactions failed.