Release 10.1A: OpenEdge Development:
ProDataSets

> ## Sample procedure: adding REPOSITION and SYNCHRONIZE

> In Chapter 1, "Introducing the Progress DataSet," you learned about the `REPOSITION` mode for a Data-Relation. You can include this in a `DATASET` definition as a keyword at the end of the relation definition, or you can set it at run time as an attribute (true or false) on the relation.

> When you fill a ProDataSet, `REPOSITION` mode on a relation causes Progress to treat the relation as deactivated and to populate the child table with all records from its Data-Source buffer, or with all those you specify in your own Data-Source query.

> When you are navigating, `REPOSITION` mode causes Progress to reposition its default query on the relation to the correct record rather than reopening the query to select only that record.

> In this section, you will extend the `dsOrderWin.w` example to show the effect of the `REPOSITION` mode on a relation. You’ll also use the `SYNCHRONIZE` method to readjust the queries the browses for `OrderLines` and `Items` use.

> First, open `dsOrder.i` and add the keyword `REPOSITION` at the end of the `LineItem` relation definition, as shown:

>     DEFINE DATASET dsOrder FOR ttOrder, ttOline, ttItem
>         DATA-RELATION OrderLine FOR ttOrder, ttOline
>           RELATION-FIELDS (OrderNum, OrderNum)
>         DATA-RELATION LineItem FOR ttOline, ttItem
>           RELATION-FIELDS (ItemNum, ItemNum) REPOSITION.

> Next, get the window procedure to use the relation queries rather than the static queries the AppBuilder generates. When you created `dsOrderWin.w`, you created two static browses to show the contents of `ttOline` and `ttItem`. The AppBuilder generated queries for the temp-tables for you when you did this, and associated them with preprocessor values, as shown:

>     &Scoped-define OPEN-QUERY-ItemBrowse OPEN QUERY ItemBrowse FOR EACH ttItem
>         NO-LOCK INDEXED-REPOSITION.
>     &Scoped-define OPEN-QUERY-OlineBrowse OPEN QUERY OlineBrowse FOR EACH ttOline
>         NO-LOCK INDEXED-REPOSITION.
>     …
>     &Scoped-define OPEN-BROWSERS-IN-QUERY-dsFrame ~
>         ~{&OPEN-QUERY-ItemBrowse}~
>         ~{&OPEN-QUERY-OlineBrowse}

> You then used the `OPEN-BROWSERS` preprocessor in the `LEAVE` trigger for the `Order Number` field:

>      {&OPEN-BROWSERS-IN-QUERY-{&FRAME-NAME}}

> However, now you want to use the dynamic queries the ProDataSet provides for you so that you don’t have to bother using those the AppBuilder defines.

> In the Main Block of `dsOrderWin.w`, add these lines to associate the two browse objects with the ProDataSet relation queries:

>     MAIN-BLOCK:
>     DO ON ERROR   UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK
>        ON END-KEY UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK:
>       RUN enable_UI.
>       /* Replace the default AppBuilder-generated static queries with
>          the ones that are part of the Data-Relations. */
>       OlineBrowse:QUERY =
>           DATASET dsOrder:GET-RELATION("OrderLine"):QUERY.
>       ItemBrowse:QUERY =
>           DATASET dsOrder:GET-RELATION("LineItem"):QUERY.
>       ItemBrowse:SET-REPOSITIONED-ROW(4, "CONDITIONAL").
>       IF NOT THIS-PROCEDURE:PERSISTENT THEN
>         WAIT-FOR CLOSE OF THIS-PROCEDURE.
>     END.

> The `OrderLine` relation query is filtered automatically for `ttOlines` of the currently selected `ttOrder`. In the case of this sample window, there is only one `ttOrder` in the ProDataSet at a time. As you have seen from other examples, if there is more than one parent, the relation query filters for the current parent.

> Because of the `REPOSITION` qualifier on the relation, the `LineItem` relation query doesn’t select just the `ttItem` for the current `ttOrder`. Instead, this qualifier tells Progress to leave the `ttItem` query open for all `ttItem` records, and to reposition it to the correct `ttItem` for the current `ttOline`.

> The `SET-REPOSITIONED-ROW` method tells Progress to make the selected row the fourth row in the viewport, so it’s in the middle, unless it’s already being displayed (that’s the `CONDITIONAL` part).

> In the `LEAVE` trigger for `iOrderNum`, you need to add statements that close the relation queries that the `ttOline` and `ttItem` browses are now using. If you don’t do this, you might see anomalous behavior when they are reopened for the ProDataSet on another `Order`, as shown:

>     IF iOrderNum NE 0 THEN
>       DO:
>           DATASET dsOrder:GET-RELATION(1):QUERY:QUERY-CLOSE().
>           DATASET dsOrder:GET-RELATION(2):QUERY:QUERY-CLOSE().
>           …

> Remove or comment out the`OPEN-BROWSERS`… preprocessor. In addition, add a line to run the `SYNCHRONIZE` method on the top-level buffer, for `ttOrder`, as shown:

>     DO WITH FRAME dsFrame:
>        ASSIGN iCustNum:SCREEN-VALUE  = STRING(ttOrder.CustNum)
>               cCustName:SCREEN-VALUE = ttOrder.CustName
>               cRepName:SCREEN-VALUE  = ttOrder.RepName
>               dOrderTotal:SCREEN-VALUE = STRING(ttOrder.OrderTotal).
>               /* {&OPEN-BROWSERS-IN-QUERY-{&FRAME-NAME}}   */
>               DATASET dsOrder:GET-BUFFER-HANDLE(1):SYNCHRONIZE().
>     END.

> Since you’ve connected the two browses to the relation queries, you don’t need to use the static ones anymore. But because there’s no browse at the top level, for the `ttOrder` fields, you need to nudge Progress and tell it to go through the steps to reopen or reposition the related queries for the current `ttOrder` record. This is what `SYNCHRONIZE` does.

> When you rerun the window procedure, you can see the effect of the `REPOSITION` relation:

> You can scroll up and down in the `ItemBrowse` to see that Progress has retrieved all `Items` into the temp-table. That’s what `REPOSITION` does at `FILL` time. As you can see, the relation query the browse is using is automatically positioned to the correct `ttItem` each time you select a `ttOline` record. That’s the part that `REPOSITION` does when you’re navigating a filled ProDataSet. If you want one behavior without the other, you can turn the `REPOSITION` attribute on and off at run time.

> Just to reinforce what is happening here, try removing the `REPOSITION` keyword from `dsOrder.i` again and rerunning the window:

> At fill time, Progress is loading only `Items` that are in one or more of your `OrderLines` into `ttItem`. When you view the data, it’s filtering `ttItem` to show only the one `ttItem` for the current `ttOline` in the browse. So there’s really nothing to browse in this case.

Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095