1

Is there an example anywhere of a form that performs running totals in a column located within a grid. The user ordering and filtering of the grid would affect the running totals column.

I can easily perform the above if it was ordering only by transaction date, but including the user ordering and filtering I presume that we would have to use the datasource range() and rangecount() functions (see SysQuery::mergeRanges() for an example) then iterate over these to apply the filtering, then include the dynalinks. The same for the ordering, albeit this is now more complicated.

Any suggestions appreciated. Any appreciations suggested (as in: vote the question up!).

ian_scho
  • 5,906
  • 9
  • 35
  • 51

2 Answers2

2

You could implement it as a form datasource display method using this strategy:

  1. Copy the form's datasource query (no need for SysQuery::mergeRanges):

    QueryRun qr = new QueryRun(ledgerTrans_qr.query());

  2. Iterate and sum over your records using qr, stop after the current record:

    while (qr.next()) { lt = qr.getNo(1); total += lt.AmountMST; if (lt.RecId == _lt.RecId) break; }

    This could be made more performant if the sorting order was fixed (using sum(AmountMST) and adding a where constraint).

  3. Return the total

This is of cause very inefficient (subquadratic time, O(n^2)).

Caching the results (in a map) may make it usable if there are not too many records.

Update: a working example.

Jan B. Kjeldsen
  • 17,817
  • 5
  • 32
  • 50
  • Great answer, Jan. Thank you ever so much for your time. I've just implemented this and I can confirm your observation about the now slower form response. Regards. – ian_scho Aug 16 '12 at 08:14
  • Agggh! I've just been testing and the grid user filters do not seem to have been applied to the query object that we're using. I've tried ledgerTrans_qr.query() and this.query() but neither seem to include the standard column filter value I have added to the grid. Any suggestion most welcome. – ian_scho Aug 16 '12 at 10:50
  • Did you cache the display method results? You should flush the cache when user changes query, `executeQuery()` would be a good place. User filters definitely should show in your query! – Jan B. Kjeldsen Aug 17 '12 at 10:46
  • 1
    Both `this.queryRun().query()` and `ledgerTrans_qr.query()` works! But `this.query()` does not work as this is the initial query. – Jan B. Kjeldsen Aug 17 '12 at 11:39
0

Any observations or criticisms to the code below most welcome. Jan's observation about the method being slow is still valid. As you can see, it's a modification of his original answer.

//BP Deviation Documented
display AmountMST XXX_runningBalanceMST(LedgerTrans _trans)
{
    LedgerTrans localLedgerTrans;
    AmountMST   amountMST;
    ;
    localLedgerTrans    = this.getFirst();
    while (localLedgerTrans)
    {
        amountMST           += localLedgerTrans.AmountMST;
        if (localLedgerTrans.RecId == _trans.RecId)
        {
            break;
        }
        localLedgerTrans    = this.getNext();
    }
    return amountMST;
}
ian_scho
  • 5,906
  • 9
  • 35
  • 51
  • This should work. The query solution given in the pastebin above may be a lot faster though (select field list, caching in map). – Jan B. Kjeldsen Aug 17 '12 at 11:30