Automatic Posting

TDataSet will automatically posted a modified record when scrolling between rows. However, when the dataset is closed a modified record is “cancelled” and the changes lost. This gives rise to two problems:

  1. 1.In some cases, it may be better to cancel any changes when scrolling rather than post. A good example of this is when using a TDBGrid and you scroll beyond the end of the grid. In this case, a new row is automatically added. If the user ignores this and scrolls back, the append should be cancelled and not saved. 

  2. 2.Automatic posting on scroll is arguably inconsistent with no similar behaviour on dataset close. Instead, this behaviour has to be added explicitly in an OnBeforeClose event handler. 

IBX (v 1.2.3) attempts to improve upon this by adding the “OnValidatePost” event and the “DataSetCloseAction” property.

The OnValidatePost Event

TOnValidatePost = procedure (Sender: TObject; var CancelPost: boolean) of object;  

This event is called as the first action in the Post method. If it returns with “CancelPost” set to true, then the “Cancel” method is called and the “Post” terminated. The event handler can thus decide if the Post should be cancelled by checking the actual field values, even prompting the user to decide.

In terms of event sequencing, the event  occurs before an OnBeforePost Event. Thus when the dataset is scrolled and the current record is in the “modified” state, then the following events will occur:

or

Note that trying to call “Cancel” in an OnBeforePost handler does not work as the Post still proceeds and, with IBX, an error will be reported.

An exception could be raised in either the OnValidatePost handler or in the OnBeforePost handler to report an actual error in the record.

The DataSetCloseAction Property

TDataSetCloseAction = (dcDiscardChanges, dcSaveChanges);

The property is used in the TIBCustomDataSet.OnBeforeClose method i.e.

procedure TIBCustomDataSet.DoBeforeClose;

begin

  inherited DoBeforeClose;

  if State in [dsInsert,dsEdit] then

  begin

    if FInTransactionEnd and (FCloseAction = TARollback) then

       Exit;

 

    if DataSetCloseAction = dcSaveChanges then

      Post;

      {Note this can fail with an exception e.g. due to

       database validation error. In which case the dataset remains open }

  end;

end;      

If the dataset is still in the insert or edit state after any OnBeforeClose handler is called then “Post” is called if the property is set to “dcSaveChanges”. The exception is when the dataset is being automatically closed due to a transaction rollback.

If the DataSetClose action is “dcDiscardChanges” (default) then no action occurs and the changes are lost. i.e. the previous behavour.

For backwards compatibility reasons,  dcSaveChanges must be explicitly set in the Object Inspector.