Define FILL events
- Last Updated: February 11, 2026
- 5 minute read
- OpenEdge
- Version 13.0
- Documentation
There are three levels of FILL events:
- Events for the ProDataSet itself
- Events for one of the ProDataSet's temp-table buffers
- Events for each individual record created in a temp-table
Because the FILL can apply (either explicitly or by cascading) to the
whole ProDataSet or to individual temp-table buffers, there are separate events for each of
those levels.
The ProDataSet is passed into each event procedure as an INPUT parameter
BY-REFERENCE. This allows the event procedure to operate on the
ProDataSet using static ABL to reference its buffers and fields, without the ProDataSet
being physically copied. This also means that because the ProDataSet is not copied, changes
made to the ProDataSet by the event procedure are made to the same copy all procedures are
using.
These are the FILL events for the ProDataSet and its members:
-
BEFORE-FILLon a ProDataSet handle — Fires at the very beginning of aFILLon the ProDataSet before any records are read or populated. It lets you make a server or database connection or do other preparatory work. Alternatively, you could use the event to intercept and fully replace the default behavior, in a case where the data relationships are such that the standard Data-Relations cannot define them, or where there are perhaps no standard Data-Source objects at all, because the data comes from a non-database source. -
BEFORE-FILLon a ProDataSet temp-table buffer handle — Fires at the very beginning of a fill for a ProDataSet's temp-table. This lets you do preparatory work for the individual table. For the parent table in a set of related tables where theFILLevent is applied to this top-level table, it could be the same kind of connection code as for the ProDataSet as a whole. Or you could prepare the query for a top-level table in itsFILLevent. For a child table, the event is fired once for each parent record that is created, and gives you the opportunity to adjust the query for the child table, or possibly cancel the fill for children of that parent altogether. -
AFTER-FILLon a ProDataSet handle — Fires at the very end of aFILLof a ProDataSet and can be used to adjust the contents of the ProDataSet, possibly to reject the entireFILLoperation or to detach Data-Sources or disconnect from other resources. -
AFTER-FILLon a ProDataSet temp-table buffer handle — Fires at the end of aFILLof a ProDataSet buffer's temp-table and can be used to adjust the contents of the table, detach the Data-Source, and so on. As with theBEFORE-FILLevent on a buffer, for a child table the event is fired once for each parent record that is created.
You use the SET-CALLBACK-PROCEDURE method to register each of these events
for a ProDataSet handle or a ProDataSet buffer handle, which identifies the code to run for
each object.
The lowest event level is for the individual record, fired once for each record created in
each table during a FILL. These are the ROW-FILL events
for the ProDataSet temp-table buffer:
-
BEFORE-ROW-FILLon a ProDataSet temp-table buffer handle — Fires before the row is created in the temp-table, but after the Data-Source records for it have been read. For example, this code can examine the database buffers or other information and decide not to create the record using theRETURN NO-APPLYstatement. -
AFTER-ROW-FILLon a ProDataSet temp-table buffer handle — Fires after a row is created in the temp-table. For example, the code can modify field values in the row by supplying values for calculated fields. It can also perform filtering and reject a row simply by deleting it, if the logic determines that it should not be part of the ProDataSet. The event procedure cannot modify record currency using the ProDataSet's buffers in any other way. It can use a separately defined buffer for the temp-table (or for other tables in the ProDataSet) to modify the ProDataSet in other ways. The code canRETURN ERRORto abort the entireFILLorRETURN NO-APPLYto cancel the cascade of theFILLoperation down to children of this current record, if any.
The following figure illustrates the order in which these nested events are triggered, using a single parent-child relationship as an example. Multiple levels of nesting would result in multiple levels of nesting of the events for each table. If there are multiple top-level tables, the process is repeated for each top-level table. Events for top-level tables are triggered in the order in which the tables are defined in the ProDataSet definition or added to a dynamic ProDataSet.

This is the sequence shown in the above figure:
- The ProDataSet
BEFORE-FILLevent fires first, before any record reads begin. - The table
BEFORE-FILLevent for the top-level table fires once before each row in that table is populated. - A nested table
BEFORE-FILLevent fires once for each parent row, before any rows in the child table are populated. - A
BEFORE-ROW-FILLevent fires once for each row in the table before it is populated, but after the corresponding records in the Data-Source have been read into their database buffers. - An
AFTER-ROW-FILLevent fires once for each row in the table after it has been created and its field values assigned. - The
AFTER-FILLevent on a nested table fires once for each parent row, after all the rows in the child table have been created and populated. - The
AFTER-FILLevent on a parent table fires once for each parent row, after it and all of its children have been populated. - The
AFTER-FILLevent on the ProDataSet itself fires last of all, after all rows have been populated.
If a callback procedure attempts to raise error for a FILL event, either
through the traditional RETURN ERROR or through the structured
UNDO, THROW, the ProDataSet ERROR attribute is set to
true. Error is not raised to the caller.
As a recursive ProDataSet FILL is proceeding, it creates a clone of the
relevant buffers, relations, queries and Data-Sources for each level of recursion. As a new
record is added to the ProDataSet, it fires FILL events on the recursed,
cloned buffer. From inside the event handler, you might want to see previous iterations of
the buffer; its parent, grandparent, great-grandparent, and so on. These iterations are
available through several attributes:
-
CURRENT-ITERATIONreturns the level of iteration for the cloned buffer handle. -
GET-ITERATIONreturns the buffer handle at a specified recursion level. -
NUM-ITERATIONSindicates how many levels deep you are in a recursiveFILL.
For more information about recursive Data-Relations, see Recursively fill a ProDataSet.