Use the COPY-DATASET method for successive FILLs
- Last Updated: January 17, 2024
- 4 minute read
- OpenEdge
- Version 12.8
- Documentation
This second COPY-DATASET example
provides a variation on the earlier PickOrder procedure.
As it stands, PickOrder.w and its support procedure OrderSupport.p retrieve
a set of Order headers, and then in follow-on calls,
the OrderLines for those Orders.
All the items are retrieved along with the first set of OrderLines.
When you select a different set of Orders, the
target ProDataSet is emptied and you start over again.
To
show a possible use for COPY-DATASET, you start by
making some changes to the way PickOrder works, which
will cause a problem that must be corrected.
To update your code:
- Create a copy of PickOrder.w called PickOrderCopy.w.
-
Create a variation on dsOrder.i called dsOrderNoRepos.i,
which does not have the
REPOSITIONkeyword on theItemrelation, as shown:/* dsOrderNoRepos.i -- include file definition of DATASET dsOrder with no REPOSITION qualifier. */ 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).This will be used in the
OrderSupportprocedure when it fills the ProDataSet, so that rather than retrieving allItemsregardless of their relationship to theOrderLines(which is whatREPOSITIONdoes on aFILL), it will retrieve only thoseItemsthat match one of theOrderLinesbeing filled at the same time. -
Create a copy of OrderSupport.p called OrderSupportCopy.p.
Include dsOrderNoRepos.i in place of dsOrder.i,
as shown:
/* OrderSupportCopy.p -- FILL events for OrderDset.p */ {dsOrderTT.i} {dsOrderNoRepos.i} -
Edit the internal procedure
fetchOrderDetailin OrderSupportCopy.p to eliminate the second parameter, which is the flag indicating whetherItemshave been retrieved already or not. In this variation, you will always retrieveItemsfor the currentOrderLines(and only thoseItems). TheFILL-MODEfor thettItemtable needs to be changed toMERGE. APPENDmode is correct for thettOlinetable, because there will not be any duplicateOrderLinesfor a given set ofOrders (althoughMERGEmode would work just as well).MERGEmode is needed for thettItemtable in case the sameItemis used in more than oneOrderLine.MERGEmode eliminates the duplicates. For example:PROCEDURE fetchOrderDetail: DEFINE INPUT PARAMETER piOrderNum AS INTEGER NO-UNDO. /* DEFINE INPUT PARAMETER lFillItems AS LOGICAL NO-UNDO. */ DEFINE OUTPUT PARAMETER DATASET FOR dsOrder BY-VALUE. hDataSet:EMPTY-DATASET. cSelection = "OrderNum = " + STRING(piOrderNum). /* We need to reset the FILL-MODE from its initial setting of NO-FILL for these two tables. */ hDataSet:GET-BUFFER-HANDLE(2):FILL-MODE = "APPEND". /* ttOline */ hDataSet:GET-BUFFER-HANDLE(3):FILL-MODE = "MERGE". /* ttItem */ /* IF lFillItems THEN "APPEND" ELSE "NO-FILL". */ hDataSet:FILL(). END PROCEDURE. - Back in PickOrderCopy.w, change the Main Block to run OrderSupportCopy.p instead of OrderSupport.p
-
Change the
SalesRep LEAVEtrigger in PickOrderCopy.w to run the new version offetchOrders, with only two parameters, as shown:RUN fetchOrders IN hOrderProc (INPUT cSelection, OUTPUT DATASET dsOrder). -
Change the
MOUSE-SELECT-DBLCLICKtrigger for thettOrderbrowse, likewise eliminating the second argument tofetchOrderDetail, as shown:RUNfetchOrderDetail IN hOrderProc (INPUT iOrderNum,OUTPUTDATASETdsOrder APPEND). -
Now try running the window procedure. Enter 1 for
the
Customerand tab through the other fill-in fields. You will seeOrders forCustomer 1as before. -
Double-click on the second
Order(number36). You see that only itsItemshave been retrieved to be displayed in theItembrowse:
-
Now double-click on the next
Order, number79. ItsOrderLinesandItemsare retrieved and added to those already in the window procedure's ProDataSet. So far so good. -
Next, double-click on the next
Order, number177. The following error appears:
What went wrong? Because the
APPENDmode on the ProDataSet parameter in theOrderbrowse trigger does not eliminate duplicates, the AVM attempted to add anItemto the window procedure'sttItemtable that was already used in anotherOrderLine, and was therefore already there. This violates the unique index on thettItemtable, and the AVM complains accordingly.Since you cannot get the
APPENDparameter mode to do a merge for you, eliminating duplicates, how can you accomplish this?One way is to use the
COPY-DATASETmethod to combine the data from two ProDataSets, one which is already on the client, and the other which is retrieved into a separate ProDataSet from the support procedure. -
To do this, insert the contents of the include files dsOrderTT.i and dsOrder.i into PickOrderCopy.w's
definitions section, and edit them to give unique names to the second
copy of the ProDataSet and its temp-tables. The temp-tables should
be named
ttOrder2,ttOline2,ttOlineBefore2, andttItem2. The field and index names can stay the same. The new ProDataSet definition should look like this:DEFINE DATASET dsOrder2 FOR ttOrder2, ttOline2, ttItem2 DATA-RELATION OrderLine FOR ttOrder2, ttOline2 RELATION-FIELDS (OrderNum, OrderNum) DATA-RELATION LineItem FOR ttOline2, ttItem2 RELATION-FIELDS (ItemNum, ItemNum).Remember that there is no way to have multiple instances of the same static ProDataSet or temp-table in a single OpenEdge procedure, so the second ProDataSet and its temp-tables need distinct names. You could, of course, also use a dynamic ProDataSet as the second ProDataSet, as shown in the previous example.
-
Now re-edit the
MOUSE-SELECT-DBLCLICKtrigger on theOrderbrowse to remove the code that empties the target ProDataSet, and to receive the additionalOrders,OrderLines, andItemsinto a second ProDataSet that is then copied into the first one. For example:/* DELETE ttOrder. FOR EACH ttOline WHERE ttOline.OrderNum = iOrderNum: DELETE ttOline. END. */ RUN fetchOrderDetail IN hOrderProc (iOrderNum, OUTPUT DATASET dsOrder2). DATASET dsOrder:COPY-DATASET(DATASET dsOrder2:HANDLE, TRUE).The second argument to
COPY-DATASET, the merge-flagTRUE, tells the AVM to merge data from ProDataSetdsOrder2intodsOrderrather than emptyingdsOrderfirst. Now when you rerun the window, retrieveOrders forCustomer 1, and selectOrders36,79, and177in turn, the buffer handle is gone, because new data is being merged into the original ProDataSet and duplicates are automatically eliminated. For example: