I can think of two use cases when applying running totals to a grid on a form. Taking the LedgerTransAccount form (Account Transactions) as an example:
Running totals by transaction date
Add a real field to the grid, with a 'XXX_RunningBalanceMST' DataMethdod with the 'LedgerTrans' DataSource.Add the following method to the LedgerTrans table:
public AmountMST XXX_RunningBalanceMST()
{
LedgerTrans ledgerTrans;
;
select sum(AmountMST) from ledgerTrans
where ledgerTrans.AccountNum == this.AccountNum
&& ( (ledgerTrans.TransDate < this.TransDate)
|| (ledgerTrans.TransDate == this.TransDate && ledgerTrans.RecId <= this.RecId) );
return ledgerTrans.AmountMST;
}
Add the cache method to the form datasource (LedgerTrans) init() method, after the super(); call.
ledgerTrans_ds.cacheAddMethod(tablemethodstr(LedgerTrans, XXX_RunningBalanceMST));
Running totals by user defined filters, dynalinks and ordenations:
This time add a disply method directly to the datasource.//BP Deviation Documented
display AmountMST XXX_runningBalanceMST2(LedgerTrans _ledgerTrans)
{
QueryRun qr = new QueryRun(ledgerTrans_qr.query());
LedgerTrans localLedgerTrans;
AmountMST amountMST;
;
while (qr.next())
{
localLedgerTrans = qr.get(tablenum(LedgerTrans));
amountMST += localLedgerTrans.AmountMST;
if (localLedgerTrans.RecId == _ledgerTrans.RecId)
{
break;
}
}
return amountMST;
}
This is definately the slowest procedure. I'd avoid applying this modification to be honest.
We would have to implement our own caching on the results, using a map, with RecId as our key and the result as the value. Initialise/empty the map in the executeQuery() method and check if the _ledgerTrans.RecId key exists in the map before launching into the loop in the method. The optimisation is undertaken here.
EDIT: Includes user filters on the form columns:-
//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;
}
Thanks to Jan B. Kjeldsen for the heads-up.
No hay comentarios:
Publicar un comentario