1

I am trying to sum a value from a list of records. I can achieve this by creating a list in APEX, then represent the list on a Visualforce page without rendering any fields. I have also done this by using aggregate results.

Is there a massive difference between the two? Will it affect any org limits? Is there a difference in performance?

APEX:

public with sharing class CreditorsControlExtension {

    public Accounting_Month__c currentRecord {get;set;}
    public list <Delivery_Note_Line_Item__c> DNLITC {get;set;}
    public decimal LedgerBalanceCreditor {get;set;}
    public Summary[] Summaries { get; set; }

    public CreditorsControlExtension(ApexPages.StandardController controller) {

        currentRecord = [SELECT id,name FROM Accounting_Month__c WHERE id = :ApexPages.CurrentPage().getparameters().get('ID')];

        DNLITC = [SELECT id,name,zAccountingMonth__c,Transaction_Amount_Including_GST__c,Cash_Accrual_Account__c
            FROM Delivery_Note_Line_Item__c WHERE Cash_Accrual_Account__c = '7130'];

        AggregateResult[] results = [SELECT Count(Id) Total, SUM(Transaction_Amount_Including_GST__c) Amount
            FROM Delivery_Note_Line_Item__c WHERE Cash_Accrual_Account__c = '7130'];

        Summaries = new List<Summary>();
        for (AggregateResult ar : results) {
            Summaries.add(new Summary(ar));
        }

    }

    public class Summary {

        public decimal Amount {get; private set;}

        public Summary(AggregateResult ar) {
            Amount = (Decimal) ar.get('Amount');
        }
    }
}

Visualforce:

Variable:

<apex:variable value="{!0}" var="ledgerBalance"/>
    <apex:repeat value="{!DNLITC}" var="dnli">
        <apex:variable var="ledgerBalance" value="{!ledgerBalance + IF(dnli.Transaction_Amount_Including_GST__c = 0,0.00,dnli.Transaction_Amount_Including_GST__c)}"/>
    </apex:repeat>

<b>${!ledgerBalance}</b>

Aggregate:

<apex:repeat value="{!Summaries}" var="summary">
       Aggregate: {!summary.Amount}<br/>
</apex:repeat>

1 Answer 1

5

Yes, there is a difference. You should use Aggregate Result. Using an <apex:variable> and incrementing it in a loop isn't supported behavior, strictly speaking, and you should avoid putting logic in the view layer anyway.

With an assist from @sfdcfox, the documentation states flat out this behavior is not supported:

Note: <apex:variable> does not support reassignment inside of an iteration component, such as <apex:dataTable> or <apex:repeat>. The result of doing so, e.g., incrementing the <apex:variable> as a counter, is unsupported and undefined.

3
  • Hi Adrian, thanks. So when you say it isn't supported, do you mean that although the variable tags are Apex, this isn't their designed intention? Regardless, from a system process perspective, is this doing something really resource intensive? Commented Dec 14, 2018 at 2:14
  • Resource intensive? No. But as you say, it isn't what this tag was designed for, and may demonstrate unstable behavior, or behave differently than you expect. It will also be more difficult to convert to lightning if you ever have to.
    – Adrian Larson
    Commented Dec 14, 2018 at 2:40
  • @TheMikeyBoosh See this question for an example of why apex:variable can go wrong for absolutely no reason. Also, apex:variable can behave weird in apex:component. And my answer on the question from above quotes the docs that say that apex:variable in a loop is undefined behavior.
    – sfdcfox
    Commented Dec 14, 2018 at 3:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .