Hello,
I have a dataset where i want to fill the top-buffer myself. If all tables are coming from the database, all works as expected, but if i don't supply a data-source for ttOrder but instead create the same ttOrder record myself, i don't get the same results.
See the example below. If lCustomFill is false, you will get results, if it is true and thus creating the order record yourself, you won't get the same result.
What am i missing?
DEFINE VARIABLE lCustomFill AS LOGICAL INITIAL false.
DEFINE TEMP-TABLE ttOrder NO-UNDO LIKE Order.
DEFINE TEMP-TABLE ttOline NO-UNDO LIKE OrderLine.
DEFINE TEMP-TABLE ttItem NO-UNDO LIKE Item.
DEFINE DATASET dsOrder FOR ttOrder, ttOLine, ttItem
DATA-RELATION drOrderLine FOR ttOrder, ttOLine RELATION-FIELDS (OrderNum,OrderNum)
DATA-RELATION drLineItem FOR ttOLine, ttItem RELATION-FIELDS (ItemNum,ItemNum)
.
IF lCustomFill THEN
DATASET dsOrder::ttOrder:SET-CALLBACK-PROCEDURE ("BEFORE-FILL", "ipBeforeFillOrder").
ELSE DO:
DEFINE QUERY qOrder FOR Order.
DEFINE DATA-SOURCE srcOrder FOR QUERY qorder Order KEYS (Ordernum).
BUFFER ttOrder:ATTACH-DATA-SOURCE(DATA-SOURCE srcOrder:HANDLE,?,?).
QUERY qOrder:QUERY-PREPARE("FOR EACH ORDER WHERE OrderNum EQ 7").
END.
DEFINE DATA-SOURCE srcOLine FOR OrderLine KEYS (Ordernum).
DEFINE DATA-SOURCE srcItem FOR Item KEYS (Itemnum).
BUFFER ttOLine:ATTACH-DATA-SOURCE(DATA-SOURCE srcOLine:HANDLE,?,?).
BUFFER ttItem :ATTACH-DATA-SOURCE(DATA-SOURCE srcItem :HANDLE,?,?).
DATASET dsOrder:FILL().
FOR EACH ttOrder:
DISP ttOrder.
END.
FOR EACH ttItem:
DISP ttItem.
END.
BUFFER ttOrder:DETACH-DATA-SOURCE().
BUFFER ttOLine:DETACH-DATA-SOURCE().
BUFFER ttItem :DETACH-DATA-SOURCE().
PROCEDURE ipBeforeFillOrder:
DEFINE INPUT PARAMETER DATASET FOR dsOrder.
FIND Order 7 NO-LOCK.
CREATE ttOrder.
BUFFER-COPY Order TO ttOrder.
END PROCEDURE.
The magic is really a combination of the existence of a Data-Source and the Data-Relations.
The DataSet begins a FILL operation with the top-level buffer(s) and cascades the FILL to all the child buffers described by the Data-Relations. FYI: a 'top-level' buffer or 'top-buffer' is one that is NOT a child of any Data-Relation.
With a Data-Source attached to a member buffer, the DataSet issues a FILL and monitors the Data-Source for indication it should continue the FILL.
Without
a Data-Source attached, the internal DataSet FILL mechanism expects application logic to exist that will perform the remainder of the work. Creating a TT record alone does not indicate to the Dataset that the child FILL operation should occur.
What needs to happen: fill all 'children' of each top-level buffer. That relationship is described by the Data-Relations.
Only those Data-Relations which contain ttOrder as a parent-buffer and are active need to be filled.
Examples to perform this might be, replace your internal "ipBeforeFillOrder" procedure with the following:
<snip>
</snip>
Hope that helps somewhat.
Hello,
I have a dataset where i want to fill the top-buffer myself. If all tables are coming from the database, all works as expected, but if i don't supply a data-source for ttOrder but instead create the same ttOrder record myself, i don't get the same results.
See the example below. If lCustomFill is false, you will get results, if it is true and thus creating the order record yourself, you won't get the same result.
What am i missing?
DEFINE VARIABLE lCustomFill AS LOGICAL INITIAL false.
DEFINE TEMP-TABLE ttOrder NO-UNDO LIKE Order.
DEFINE TEMP-TABLE ttOline NO-UNDO LIKE OrderLine.
DEFINE TEMP-TABLE ttItem NO-UNDO LIKE Item.
DEFINE DATASET dsOrder FOR ttOrder, ttOLine, ttItem
DATA-RELATION drOrderLine FOR ttOrder, ttOLine RELATION-FIELDS (OrderNum,OrderNum)
DATA-RELATION drLineItem FOR ttOLine, ttItem RELATION-FIELDS (ItemNum,ItemNum)
.
IF lCustomFill THEN
DATASET dsOrder::ttOrder:SET-CALLBACK-PROCEDURE ("BEFORE-FILL", "ipBeforeFillOrder").
ELSE DO:
DEFINE QUERY qOrder FOR Order.
DEFINE DATA-SOURCE srcOrder FOR QUERY qorder Order KEYS (Ordernum).
BUFFER ttOrder:ATTACH-DATA-SOURCE(DATA-SOURCE srcOrder:HANDLE,?,?).
QUERY qOrder:QUERY-PREPARE("FOR EACH ORDER WHERE OrderNum EQ 7").
END.
DEFINE DATA-SOURCE srcOLine FOR OrderLine KEYS (Ordernum).
DEFINE DATA-SOURCE srcItem FOR Item KEYS (Itemnum).
BUFFER ttOLine:ATTACH-DATA-SOURCE(DATA-SOURCE srcOLine:HANDLE,?,?).
BUFFER ttItem :ATTACH-DATA-SOURCE(DATA-SOURCE srcItem :HANDLE,?,?).
DATASET dsOrder:FILL().
FOR EACH ttOrder:
DISP ttOrder.
END.
FOR EACH ttItem:
DISP ttItem.
END.
BUFFER ttOrder:DETACH-DATA-SOURCE().
BUFFER ttOLine:DETACH-DATA-SOURCE().
BUFFER ttItem :DETACH-DATA-SOURCE().
PROCEDURE ipBeforeFillOrder:
DEFINE INPUT PARAMETER DATASET FOR dsOrder.
FIND Order 7 NO-LOCK.
CREATE ttOrder.
BUFFER-COPY Order TO ttOrder.
END PROCEDURE.
Flag this post as spam/abuse.
Depending on the use case, it might be easier to use a temp-table as the source-table for the first ProDataset table.
That source temp-table could be filled in the BEFORE-FILL callback for the dataset.
You will end up with the twice the data for that temp-table: Once in the source table and once in the ProDataset table.
But it might help keeping code more standard.
The magic is really a combination of the existence of a Data-Source and the Data-Relations.
The DataSet begins a FILL operation with the top-level buffer(s) and cascades the FILL to all the child buffers described by the Data-Relations. FYI: a 'top-level' buffer or 'top-buffer' is one that is NOT a child of any Data-Relation.
With a Data-Source attached to a member buffer, the DataSet issues a FILL and monitors the Data-Source for indication it should continue the FILL.
Without
a Data-Source attached, the internal DataSet FILL mechanism expects application logic to exist that will perform the remainder of the work. Creating a TT record alone does not indicate to the Dataset that the child FILL operation should occur.
What needs to happen: fill all 'children' of each top-level buffer. That relationship is described by the Data-Relations.
Only those Data-Relations which contain ttOrder as a parent-buffer and are active need to be filled.
Examples to perform this might be, replace your internal "ipBeforeFillOrder" procedure with the following:
<snip>
</snip>
Hope that helps somewhat.
Hello,
I have a dataset where i want to fill the top-buffer myself. If all tables are coming from the database, all works as expected, but if i don't supply a data-source for ttOrder but instead create the same ttOrder record myself, i don't get the same results.
See the example below. If lCustomFill is false, you will get results, if it is true and thus creating the order record yourself, you won't get the same result.
What am i missing?
DEFINE VARIABLE lCustomFill AS LOGICAL INITIAL false.
DEFINE TEMP-TABLE ttOrder NO-UNDO LIKE Order.
DEFINE TEMP-TABLE ttOline NO-UNDO LIKE OrderLine.
DEFINE TEMP-TABLE ttItem NO-UNDO LIKE Item.
DEFINE DATASET dsOrder FOR ttOrder, ttOLine, ttItem
DATA-RELATION drOrderLine FOR ttOrder, ttOLine RELATION-FIELDS (OrderNum,OrderNum)
DATA-RELATION drLineItem FOR ttOLine, ttItem RELATION-FIELDS (ItemNum,ItemNum)
.
IF lCustomFill THEN
DATASET dsOrder::ttOrder:SET-CALLBACK-PROCEDURE ("BEFORE-FILL", "ipBeforeFillOrder").
ELSE DO:
DEFINE QUERY qOrder FOR Order.
DEFINE DATA-SOURCE srcOrder FOR QUERY qorder Order KEYS (Ordernum).
BUFFER ttOrder:ATTACH-DATA-SOURCE(DATA-SOURCE srcOrder:HANDLE,?,?).
QUERY qOrder:QUERY-PREPARE("FOR EACH ORDER WHERE OrderNum EQ 7").
END.
DEFINE DATA-SOURCE srcOLine FOR OrderLine KEYS (Ordernum).
DEFINE DATA-SOURCE srcItem FOR Item KEYS (Itemnum).
BUFFER ttOLine:ATTACH-DATA-SOURCE(DATA-SOURCE srcOLine:HANDLE,?,?).
BUFFER ttItem :ATTACH-DATA-SOURCE(DATA-SOURCE srcItem :HANDLE,?,?).
DATASET dsOrder:FILL().
FOR EACH ttOrder:
DISP ttOrder.
END.
FOR EACH ttItem:
DISP ttItem.
END.
BUFFER ttOrder:DETACH-DATA-SOURCE().
BUFFER ttOLine:DETACH-DATA-SOURCE().
BUFFER ttItem :DETACH-DATA-SOURCE().
PROCEDURE ipBeforeFillOrder:
DEFINE INPUT PARAMETER DATASET FOR dsOrder.
FIND Order 7 NO-LOCK.
CREATE ttOrder.
BUFFER-COPY Order TO ttOrder.
END PROCEDURE.
Flag this post as spam/abuse.
Depending on the use case, it might be easier to use a temp-table as the source-table for the first ProDataset table.
That source temp-table could be filled in the BEFORE-FILL callback for the dataset.
You will end up with the twice the data for that temp-table: Once in the source table and once in the ProDataset table.
But it might help keeping code more standard.
Thank you for your reply, that clarifies a lot. I didn't realize i should do the fill on the ttOrder myself, but i makes sense.