Is this expected behaviour? Consider the code below against sports2000. If the named buffers are scoped to the IP then the buffers are only in scope if they have been explicitly found in that iteration of the query. If not then the buffer is out of scope again.
Progress 11.5.1 on Windows
If on the other hand I move the definitions to the definitions of the .p then the records are in scope as necessary.
BLOCK-LEVEL ON ERROR UNDO, THROW. DEFINE TEMP-TABLE tt-Test NO-UNDO FIELD custnum LIKE s2k.Customer.CustNum FIELD ordernum LIKE s2k.Order.Ordernum FIELD linenum LIKE s2k.OrderLine.Linenum INDEX idxbb IS PRIMARY custnum ordernum linenum. RUN PopulateTT. RUN DoBreakBy. PROCEDURE DoBreakBy: DEFINE BUFFER lb-Customer FOR s2k.Customer. DEFINE BUFFER lb-Order FOR s2k.Order. DEFINE BUFFER lb-OrderLine FOR s2k.OrderLine. FOR EACH tt-Test BREAK BY custnum BY ordernum BY linenum: IF FIRST-OF(tt-Test.custnum) THEN DO: FIND lb-Customer NO-LOCK WHERE lb-Customer.custnum EQ tt-Test.custnum NO-ERROR. END. IF FIRST-OF(tt-Test.ordernum) THEN DO: FIND lb-Order NO-LOCK WHERE lb-Order.Ordernum EQ tt-Test.Ordernum NO-ERROR. END. IF FIRST-OF(tt-Test.linenum) THEN DO: FIND lb-OrderLine NO-LOCK WHERE lb-OrderLine.OrderNum EQ tt-Test.Ordernum AND lb-OrderLine.linenum EQ tt-Test.linenum NO-ERROR. END. MESSAGE AVAIL lb-Customer SKIP AVAIL lb-Order SKIP AVAIL lb-OrderLine VIEW-AS ALERT-BOX. END. END PROCEDURE. PROCEDURE PopulateTT: FOR EACH s2k.OrderLine NO-LOCK, FIRST s2k.Order OF s2k.OrderLine NO-LOCK: CREATE tt-Test. ASSIGN tt-Test.custnum = s2k.Order.CustNum tt-Test.OrderNum = s2k.Order.OrderNum tt-Test.linenum = s2k.OrderLine.Linenum. END. END PROCEDURE.
If I whack a "DO FOR lb-Customer, lb-Order, lb-OrderLine" around the for each with the buffers scoped to the IP it works as expected too.
That is expected behaviour.
The buffers will scope to the lowest block in which they are referenced.
When you define them in the IP, they belong to the IP. As they are only referenced in the FOR block, that is the outer most block with scoping capability that reference the buffer and it will control the scope, i.e. the record will go out of scope after each iteration.
But if you reference the buffer before the FOR in the IP or after the END of the FOR block in the IP, the IP will control scope and the records from previous iterations will remain in the buffer.
But if you do not define them in the IP, the IP will share the globally (implicitly or explicitly) defined buffers of the external procedure, which will then manage scope in order to enable sharing of the buffer between the main block and all the IPs. You can however explicitly fix the scope by using a "DO FOR", in which case references to the buffer outside the block should give an error.
Thanks Simon. Makes sense. And I suppose I did know that, just took us by surprise when some code wasn't working.
Yes, I guess when we tell the newbies "You still need to learn what I've already forgotten.", we speak about these type of things.