AX 2012 R2: Passing table buffer to method changing number of times loop executes

I am confused about passing a table buffer to a method of the same class, running on the same tier. I am probably mixing ideas since they are not clear to me (and AX doesn’t let you see result sets anywhere near as easily as SQL Server does).

In the below X++ code, there is a call that is commented out. When the call is left commented out, the variable outerCnt ends up with a value of about 70 - the loop executes some 70 times.

But if I uncomment the call, outerCnt ends up with a value of just 1 … the loop only executes once instead of ~70 times.

  1. Why would anything that the called method does affect how many times this loop executes?

  2. Instead of passing all rows in the table buffer, how would I pass just the current row that the queryRun.next() has retrieved for its loop?

query = new query(queryStr(AcctDistMult2SameLedgerAcctAET));
queryRun = new queryRun(query);
while (queryRun.Next())
{
accountingDistribution = queryRun.get(tableNum(accountingDistribution), 1);
accountingEvent = queryRun.get(tableNum(accountingEvent), 1);
outerCnt++;
//this.processRow(accountingDistribution);
}

It’s difficult to comment on the behavior of processRow() if we don’t know what code it contains.

Regarding passing the current row, it’s what you’re already doing. It’s true that the buffer contains links to other records in the set, but you normally don’t use them, so it doesn’t cause any troubles.

The processRow() method uses what is passed into it (I assumed just a single AccountingDistribution row) in a join.

private void processRow(AccountingDistribution _accountingDistribution)

while

select sourceDocumentLine, AccountingDate, LedgerDimension, TransactionCurrencyAmount from accountingDistribution

join RecId from _accountingDistribution where

_accountingDistribution.SourceDocumentLine == AccountingDistribution.SourceDocumentLine

&&

_accountingDistribution.ParentDistribution == AccountingDistribution.ParentDistribution

&&

_accountingDistribution.LedgerDimension == AccountingDistribution.LedgerDimension

join RecId, SourceRelationType from sourceDocumentLine where sourceDocumentLine.RecId == accountingDistribution.SourceDocumentLine

join RecId, SourceRelationType, CreatedDateTime from sourceDocumentHeader where sourceDocumentHeader.RecId == sourceDocumentLine.SourceDocumentHeader

{

The _accountingDistribution buffer is not used anywhere else in the method.

I assume that the buffer is being passed by reference and therefore changes made in the processRow() code can affect the buffer state after execution. And I’ve since stepped through execution in the single call to processRow() and the _accountingDistribution buffer runs through all of its rows – it’s not just a single row that gets passed.

I assume that with processRow() running through all of the rows in the table buffer, after the single execution completes, the calling code’s queryRun.next() has no more rows to process. So instead of ~70 iterations (as occurs without the call to processRow()), there is only 1 iteration.

Does that make sense?

In processRow(), you’re assigning a different value to your buffer, so you shouldn’t be surprised it doesn’t contain the same value as before. Changing the data set you’re iterating is rarely a good idea and it wasn’t obviously your intention in this case. Fix your code by using a new variable in your join and get only field values from _accountingDistribution - don’t write anything into it.

I am converting this to X++ from a working T-SQL query and still had T-SQL mixing in there in the back of my head (selecting from a table in T-SQL does not update the table in any way, but selecting “from” a table buffer in X++ does). I didn’t even pick up on my oversight until you mentioned it (then I was like, DOH!). Thanks.

PS: I had just gotten it all to work correctly a different way: since processRow() really only needs 3 RecIds to perform its query, I changed it to accept 3 RecIds as parms instead of the table buffer. But that change didn’t help me understand why my original setup didn’t work - your answer did.