Query OFF-END event
- Last Updated: February 11, 2026
- 5 minute read
- OpenEdge
- Version 13.0
- Documentation
Syntax
There has long been an OFF-END GUI event
for the ABL browse control. Developers can use this to detect the
end of the available data in the query the browse is displaying.
For example, you could then retrieve additional batches of data
and append them to the rows in the table and re-open the query so
that they are added to the browse. The ProDataSet supports an OFF-END event
for its temp-table queries. It takes care of this function for you,
so that you do not need to code an OFF-END browse
trigger block to handle this, or even depend on there being a browse
at all. In addition, ABL queries have a QUERY-OFF-END condition
you can use to detect the end of the query's data when you are navigating
through the data programmatically. The ProDataSet event can respond
to this case as well, when there is no browse to trigger a GUI event.
Regardless of how the end-of-data condition is detected, the query
itself can respond to running out of rows so that an event handler
can react appropriately, whether it is to retrieve more data from
the server or take other action.
The OFF-END event
is available for any query on a ProDataSet temp-table. The OFF-END event
occurs when the query is positioned beyond the last row in the query,
no matter how this is done. This can be because of a browse scroll
to the end of the query, or a GET-NEXT() method
or GET NEXT statement on the query beyond the last
row.
This event can be attached to the query handle using
the same SET-CALLBACK-PROCEDURE method the FILL events
use, with this syntax:
|
Where:
- query-handle is the handle of a static or dynamic query.
- event-procedure is the name of an internal procedure to run that handles the event.
-
procedure-handle is a running procedure instance
containing that event-procedure. As for other
events, the default is
THIS-PROCEDURE.
In
keeping with the calling sequence for the FILL and temp-table
change events, the ProDataSet is passed in as an INPUT parameter
implicitly BY-REFERENCE, providing the event procedure
full access to all the data at no cost (because there is no copying
of data involved). And as with other callback events, your code
can use the APPLY-CALLBACK method to invoke the
event handler programmatically.
A typical use of these events would be to fetch additional batches of data from the server
if not all data has been retrieved and sent to the client. The event handler for
OFF-END can find the last currently available row and pass its key to the
server as a starting point for the next batch. There is an example of using this technique
to provide data batching later in Batch Data with ProDataSets. The event procedure can of course also look at other information in the ProDataSet,
including the current row in other tables (so that the query requesting more data could
identify the parent for example), and whatever else is helpful.
Note that this event
is similar to the existing QUERY-OFF-END query
attribute. The difference is that the QUERY-OFF-END attribute
is a condition that must be tested at a specific place in the application
code, whereas the callback event procedure executes whenever the
condition occurs regardless of where it happens in the application
code or the user interface. This allows a single event handler to
be executed whenever the condition occurs.
There are several pointers on the use of this event:
- The event can be attached only to a query that is on a single buffer for a ProDataSet temp-table; it is not possible to attach the events to a query that involves a join. Because ProDataSet temp-tables can already mask database table joins, this should not normally be a serious restriction.
- The query must be defined as
SCROLLING(so that it has an internal result-list maintained by the AVM). - The query open statement or method should not have the
INDEXED-REPOSITIONkeyword; if present, it is ignored. - The
SET-CALLBACK-PROCEDUREmethod must come before the query is opened for the first time to assure that the event is triggered properly. Once the callback is registered, you can open and close the query as much as you need to and the callback procedure remains attached to theOFF-ENDevent. - If the event handler is able to add a row or rows to the end
of the temp-table, it must
RETURN NO-APPLYin order to prevent theQUERY-OFF-END(or browseOFF-END) condition from occurring. If the event handler returnsNO-APPLY, the application event or code that triggered the event never even knows that the attempt to keep scrolling through the query initially failed. - If the event handler is unable to add more rows to the temp-table,
it should not
RETURN NO-APPLY. That would result in an infinite loop, since theNO-APPLYwill prevent theOFF-ENDcondition from happening when it should. - If you execute a
GET LASTstatement orGET-LAST()method on the query, the event handler is called repeatedly until it does not returnNO-APPLY, signifying that all records have been retrieved. In the case of a very large set of rows this can result in a significant wait while all rows are retrieved. If you need to take advantage of the behavior thatINDEXED-REPOSITIONprovides for you, allowing you to rebuild the query's result-list from the end, for example, so that you can jump directly to the last row, then you cannot use anOFF-ENDevent handler to accomplish this. - The handler will get an error if it does an
OPEN,GET, orREPOSITIONon the query itself, since the application is still in the middle of a query operation likeNEXTorPREVthat is suspended while the event handler executes. Also, any references to a different row in the query's temp-table must be done using a separate buffer. - References to the ABL
SELFkeyword in the event handler evaluate to the query handle. From this the code can access the query's buffer if needed, using the constructSELF:GET-BUFFER-HANDLE. - The query open can have the
PRESELECTkeyword or aBYclause for sorting, but note that in the case of aPRESELECTor non-indexed sort, the handler will be called repeatedly until all records are read before starting the post-select loop. This is not useful when the event handler is used for batching, but it is supported primarily so that dynamic cases do not have to check for special restrictions on the query. - The
OFF-ENDevent fires before theQUERY-OFF-ENDcondition is set, and before any other condition that signals the end of available data. This means, for example, that if there is anOFF-ENDevent on a query, and the end of the rows in the query is reached because of some action (such asGET-NEXT), then theOFF-ENDevent fires. If that event results in more rows being added to the query, then theQUERY-OFF-ENDcondition does not occur. In this way, a singleDO WHILE NOT hQuery:QUERY-OFF-ENDblock, or the act of scrolling down through a browse, can continue until theOFF-ENDfails to add any new rows to the query.
The shows
how to use the OFF-END event to providing batching
for an application window when you need to be able to scroll through
a large number of rows that cannot be retrieved all at once.