Try OpenEdge Now
skip to main content
ProDataSets
ProDataSet Attributes and Methods : Sample procedures: using attributes and methods
 

Sample procedures: using attributes and methods

This section extends the example procedures from DynamicProDataSet Basics to make them more truly dynamic. It then shows small sections of code to illustrate the use of each of the methods and attributes.
To modify the example, create a copy of DynamicDataSet.p and name the new procedure DynamicDataSet2.p. Modify the parameter list to eliminate the pcBuffers parameter and to reorder the others to base the ProDataSet definition on the database tables it is filled from. For example:
/* DynamicDataSet2.p -- creates a dynamic DataSet and Data-Sources, fills it
   for a key value passed in, and returns it. */

DEFINE INPUT PARAMETER pcSources AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER pcSourceKeys AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER pcFields AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER pcKeyValue AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER DATASET-HANDLE phDataSet.
Also, you need another handle variable to point to a series of dynamic temp-tables you will create for the database sources, as shown:
DEFINE VARIABLE hTable AS HANDLE NO-UNDO.
Modify the block of code that walks through the buffer handle list in DynamicDataSet.p to walk through the list of database source tables and create a dynamic temp-table LIKE each in turn.
Prepare each temp-table definition and then add the table's default buffer handle to the ProDataSet. The following block of code replaces the code beginning with DO iEntry = 1 TO NUM-ENTRIES(pcBuffers):
DO iEntry = 1 TO NUM-ENTRIES(pcSources):
  CREATE TEMP-TABLE hTable.
  hTable:CREATE-LIKE(ENTRY(iEntry, pcSources)).
  hTable:TEMP-TABLE-PREPARE("tt" + ENTRY(iEntry, pcSources)).
  phDataSet:ADD-BUFFER(hTable:DEFAULT-BUFFER-HANDLE).
END.
As with other parts of these procedures, you can use the same temp-table handle variable for each of the temp-tables because once it has been added to the ProDataSet, the ProDataSet structure keeps track of the handle's value and position within the ProDataSet. You are then free to reuse the same handle variable to create another new dynamic temp-table that will have its own value for that handle.
There is one more small change. The pcKeyValue parameter used to retrieve data related to a single top-level table is changed to accept an expression such as "= 1" or "< 10", by removing the equal sign literal (" = ") from the QUERY-PREPARE method. This lets you have one or more top-level records in the ProDataSet.
This will help illustrate some of the object attributes as we go along. For example:
hQuery:QUERY-PREPARE("FOR EACH " + ENTRY(1, pcSources) +
                     " WHERE " + ENTRY(1, pcSourceKeys) + pcKeyValue).
The rest of the procedure remains the same. Now the dependency on static temp-table definitions has been removed, and there is no need to pass any handles in the parameter list that would not survive being passed across the AppServer boundary.
Copy DynamicMain.p to a new variant called DynamicMain2.p. In this new procedure, you can delete the static temp-table definitions because you are making everything dynamic. This is why dynamicDataSet2.p now creates them as dynamic temp-tables instead of receiving their handles.
You will need several variables along the way to hold various attributes and other values, so define them at the top of the procedure, as shown:
DEFINE VARIABLE hBuffer AS HANDLE  NO-UNDO.
DEFINE VARIABLE hQuery AS HANDLE  NO-UNDO.
DEFINE VARIABLE hRelation AS HANDLE  NO-UNDO.
DEFINE VARIABLE iBuffer AS INTEGER NO-UNDO.
Change the RUN statement to run DynamicDataSet2.p, and rearrange the parameters to match. Change the pcKeyValues parameter "1" to be "= 1", as shown:
RUN DynamicDataSet2.p
  (INPUT "Customer,Order,SalesRep",
   INPUT "CustNum,OrderNum,SalesRep",
   INPUT "CustNum,CustNum",
   INPUT "= 1",
   OUTPUT DATASET-HANDLE hDataSet).
Create a dynamic query that you will use in several parts of the procedure:
CREATE QUERY hQuery.
Remove all the rest of the code (the DISPLAY blocks) except for the final DELETE OBJECT statement.
At this point, you can add a series of blocks of code following the CREATE QUERY statement to illustrate how to access the ProDataSet dynamically.
This first example is a block of code that retrieves the number of buffers in the ProDataSet. For each one, it retrieves its buffer handle and then does a dynamic FIND-FIRST method on that handle to position to the first record in that temp-table. (FIND-FIRST is, of course, a standard ABL dynamic buffer method.) The MESSAGE statement shows the first two fields in each buffer:
/* This block shows how to access the DataSet's buffers and the data in their
   temp-table records. */
DO iBuffer = 1 TO hDataSet:NUM-BUFFERS:
  hBuffer = hDataSet:GET-BUFFER-HANDLE(iBuffer).
  hBuffer:FIND-FIRST().
  MESSAGE "Buffer " hBuffer:NAME SKIP
    hBuffer:BUFFER-FIELD(1):NAME
    hBuffer:BUFFER-FIELD(1):BUFFER-VALUE SKIP
    hBuffer:BUFFER-FIELD(2):NAME
    hBuffer:BUFFER-FIELD(2):BUFFER-VALUE
    VIEW-AS ALERT-BOX.
END.
When you run this, you can confirm that the dynamic temp-tables have the same data as the static temp-tables did before, as shown:
A ProDataSet buffer that is not the child of a relation is referred to as a top-level buffer. There might be more than one top-level buffer in a ProDataSet. The NUM-TOP-BUFFERS attribute gives you the number of those buffers, as shown in the following syntax:

Syntax

[ integer-var = ] dataset-handle:NUM-TOP-BUFFERS
The GET-TOP-BUFFER method returns the handle of one of those buffers using its index within the list of top-level buffers, as shown with this syntax:

Syntax

[ handle-var = ] dataset-handle:GET-TOP-BUFFER( buffer-index )
This example code for DynamicMain2.p shows that ttCustomer and ttSalesRep are both top-level buffers, because they do not participate in a relation:
/* This block shows the attribute and method that access the list of DataSet
   buffers that are not children in a relation.*/
DO iBuffer = 1 TO hDataSet:NUM-TOP-BUFFERS:
  hBuffer = hDataSet:GET-TOP-BUFFER(iBuffer).
  MESSAGE "Buffer " iBuffer hBuffer:NAME
    VIEW-AS ALERT-BOX.
END.
This code output proves the point: