Use the SYNCHRONIZE method
- Last Updated: February 11, 2026
- 3 minute read
- OpenEdge
- Version 13.0
- Documentation
The Data-Relation queries in a parent-child
hierarchy are synchronized automatically only when there is a browse
object attached to the query. This attachment is done by assigning
the relation's QUERY attribute to the browse's QUERY attribute.
If you want to synchronize a hierarchy of queries under other circumstances,
you use the SYNCHRONIZE method on any parent buffer
handle:
|
This causes the ProDataSet to traverse the ProDataSet hierarchy starting at buffer buffer-handle. It reopens each relation query for the current parent at each level, just as it happens automatically when you select a record in a browse or perform some ABL action that changes the record position in a parent buffer whose children are attached to browses. The synchronize behavior is not provided automatically in all cases because there are simply too many different ways in which the position could be changed and too many different responses that a developer might want. Always reopening all related queries is not appropriate, because of the expense involved.
You can decide when to synchronize by reacting
to an event such as ON VALUE-CHANGED,
or simply in conjunction with a language statement or method such
as GET-NEXT, and explicitly doing the synchronize
when necessary. Note that this synchronization affects only the
implicit dynamic queries associated with Data-Relations when you
are navigating a ProDataSet that has already been filled. It has
nothing to do with the FILL operation itself, and
using these queries is entirely optional. In many cases (perhaps
even in most cases), your own ABL logic will instead use conventional
nested FOR EACH blocks or queries to navigate through
the levels of a ProDataSet, without using or caring about these
implicit queries at all. This is part of why the overhead of opening them
does not happen unless the relation queries have explicitly been
attached to a browse.
As part of the SYNCHRONIZE() method,
the AVM automatically positions to the first row in each relation
query, in addition to reopening it on children of the current parent
row. This is not done if the query is being browsed (with an ABL
client browse widget) because the browse effectively forces a GET-FIRST already.
Doing
this automatically spares the developer from having to write a GET-FIRST method
on each child query. A typical block of code to navigate through
the children of the current parent looks like this:
|
If you forget the GET-FIRST,
the loop exits immediately because the query is "OFF-END" if
there is no row at all in its buffer.
In addition, this is
the only way to propagate a SYNCHRONIZE() through
multiple parent-child levels. Consider the example of a three-level
ProDataSet with tables ttCustomer, ttOrder,
and ttOrderLine. The application does a SYNCHRONIZE() on
the ttCustomer table when the user selects a different
row in that table. Without doing an implicit GET-FIRST on the ttOrder table
to position it to the first ttOrder for the newly
selected ttCustomer, the relation query for the ttOrderLine table
will not be properly reopened and filtered for OrderLines of
the Customer's first Order, because there
would be no current row in the ttOrder table.
Independent
of all this, you can freely define queries of your own to navigate
the tables in the ProDataSet after it has been filled, or even as
part of custom code to populate one or more tables of a ProDataSet
independent of its FILL method.