-1

I have a list of objects:

List<Volume_Detail__c> listVolumesDetails = new List<Volume_Detail__c>([SELECT Id,Year__c,January_Volume__c, April_Volume__c,Volume__c  FROM Volume_Detail__c WHERE Volume__r.Id IN :volumeIds ]);

listVolumesDetails variable debug log:

(Volume_Detail__c:{Id=a0K7Z000007IRtNUAW, Year__c=2023.00, January_Volume__c=0.00, April_Volume__c=0.00, Volume__c=a0J7Z00000UZyvxUAD},

Volume_Detail__c:{Id=a0K7Z000007IRtSUAW, Year__c=2021.00, January_Volume__c=0.00, April_Volume__c=0.00, Volume__c=a0J7Z00000UZyvxUAD},

Volume_Detail__c:{Id=a0K7Z000007IRtTUAW, Year__c=2022.00, January_Volume__c=200.00, April_Volume__c=200.00, Volume__c=a0J7Z00000UZyvxUAD},

Volume_Detail__c:{Id=a0K7Z000007IRu6UAG, Year__c=2023.00, January_Volume__c=0.00, April_Volume__c=0.00, Volume__c=a0J7Z00000UZz8IUAT},

Volume_Detail__c:{Id=a0K7Z000007IRu7UAG, Year__c=2024.00, January_Volume__c=100.00, April_Volume__c=0.00, Volume__c=a0J7Z00000UZz8IUAT},

Volume_Detail__c:{Id=a0K7Z000007IRu8UAG, Year__c=2025.00, January_Volume__c=100.00, April_Volume__c=0.00, Volume__c=a0J7Z00000UZz8IUAT},

Volume_Detail__c:{Id=a0K7Z000007IRu9UAG, Year__c=2026.00, January_Volume__c=0.00, April_Volume__c=20.00, Volume__c=a0J7Z00000UZz8IUAT}

I want to calculate for example for the year 2023, the total of January_Volume__c and the total of April_Volume__c, How can I proceed with that as a best practice in apex?

Thank you.

0

1 Answer 1

1

You can use a map to store the sum of the January_Volume__c and April_Volume__c fields for each year. You can use the Year__c field as the key and the sum as the value. You can then access the map by the desired year to get the sum. For example, you can use this code:

Map<Decimal, Decimal> mapOfYearAndJanVolume = new Map<Decimal, Decimal>();
Map<Decimal, Decimal> mapOfYearAndAprVolume = new Map<Decimal, Decimal>();
for (Volume_Detail__c vd : listVolumesDetails) {
        Decimal year = vd.Year__c;
        if (mapOfYearAndJanVolume.containsKey(year)) {
                Decimal currentTotal = mapOfYearAndJanVolume.get(year);
                Decimal newTotal = currentTotal + vd.January_Volume__c;
                mapOfYearAndJanVolume.put(year, newTotal);
        } else {
                mapOfYearAndJanVolume.put(year, vd.January_Volume__c);
        }

        if (mapOfYearAndAprVolume.containsKey(year)) {
                Decimal currentTotal = mapOfYearAndAprVolume.get(year);
                Decimal newTotal = currentTotal + vd.April_Volume__c;
                mapOfYearAndAprVolume.put(year, newTotal);
        } else {
                mapOfYearAndAprVolume.put(year, vd.April_Volume__c);
        }
}

System.debug('The total of January 2023 :: ' + mapOfYearAndJanVolume.get(2023));
System.debug('The total of April 2023 :: ' + mapOfYearAndAprVolume.get(2023));

You can also use the AggregateQuery. To use the AggregateResult object and the GROUP BY and SUM clauses. The AggregateResult object stores the results of an aggregate query, such as the sum of a field or the count of records. The GROUP BY clause groups the records by one or more fields, such as the Year__c field. The SUM clause calculates the sum of a numeric field, such as the January_Volume__c and April_Volume__c fields. For example, you can use this code:

List<AggregateResult> listAggregateResults = [SELECT Year__c, SUM(January_Volume__c) AS January_Total, SUM(April_Volume__c) AS April_Total FROM Volume_Detail__c WHERE Volume__r.Id IN :volumeIds GROUP BY Year__c];
for (AggregateResult ar : listAggregateResults) {
        System.debug('The total for the year ' + ar.get('Year__c') + ' is ' + (ar.get('January_Total') + ' and ' + ar.get('April_Total')));
}

======================================

You can do this for all months:

#1:

Map<Decimal, Map<String, Decimal>> mapOfYearAndMonthVolume = new Map<Decimal, Map<String, Decimal>>();
List<String> months = new List<String>new List<String>{'January_Volume__c', 'February_Volume__c', 'March_Volume__c', 'April_Volume__c','May_Volume__c','June_Volume__c','July_Volume__c','August_Volume__c', 'September_Volume__c','October_Volume__c','November_Volume__c','December_Volume__c' };

for (Volume_Detail__c vd : listVolumesDetails) {
        Decimal year = vd.Year__c;
        if (!mapOfYearAndMonthVolume.containsKey(year)) {
                mapOfYearAndMonthVolume.put(year, new Map<String, Decimal>());
        }
        Map<String, Decimal> mapOfMonthAndVolume = mapOfYearAndMonthVolume.get(year);
        for (String month : months) {
                Decimal volume = (Decimal)vd.get(month);
                if (mapOfMonthAndVolume.containsKey(month)) {
                        Decimal currentTotal = mapOfMonthAndVolume.get(month);
                        Decimal newTotal = currentTotal + volume;
                        mapOfMonthAndVolume.put(month, newTotal);
                } else {
                        mapOfMonthAndVolume.put(month, volume);
                }
        }
}

System.debug('The total of January 2023 :: ' + mapOfYearAndMonthVolume.get(2023).get('January_Volume__c'));
System.debug('The total of April 2023 :: ' + mapOfYearAndMonthVolume.get(2023).get('April_Volume__c'));

#2

List<AggregateResult> listAggregateResults = [SELECT Year__c, SUM(January_Volume__c) AS January_Total, SUM(February_Volume__c) AS February_Total, SUM(March_Volume__c) AS March_Total,SUM(April_Volume__c) AS April_Total,SUM(May_Volume__c) AS May_Total,SUM(June_Volume__c) AS June_Total,SUM(July_Volume__c) AS July_Total,SUM(August_Volume__c) AS August_Total,SUM(September_Volume__c) AS September_Total,SUM(October_Volume__c) AS October_Total,SUM(November_Volume__c) AS November_Total, SUM(December_Volume__c) AS December_Total FROM Volume_Detail__c WHERE Volume__r.Id IN :volumeIds GROUP BY Year__c];
for (AggregateResult ar : listAggregateResults) {
        System.debug('The total for the year ' + ar.get('Year__c') + ' is as below:');
        System.debug(' January = ' + (ar.get('January_Total'));
        System.debug(' February = ' + (ar.get('February_Total'));
        System.debug(' March = ' + (ar.get('March_Total'));
        System.debug(' April = ' + (ar.get('April_Total'));
        System.debug(' May = ' + (ar.get('May_Total'));
        System.debug(' June = ' + (ar.get('June_Total'));
        System.debug(' July = ' + (ar.get('July_Total'));
        System.debug(' August = ' + (ar.get('August_Total'));
        System.debug(' September = ' + (ar.get('September_Total'));
        System.debug(' October = ' + (ar.get('October_Total'));
        System.debug(' November = ' + (ar.get('November_Total'));
        System.debug(' December = ' + (ar.get('December_Total'));
}
5
  • 2
    The three letter abbreviation for April is is Apr, not Apl. One should always strive to use standard abbreviations, if using abbreviations.
    – sfdcfox
    Nov 23, 2023 at 13:30
  • Thanks for the support , really appreciate it. if i want to make more dynamic is it possible to include a list of static months to do the same work for all the months ? : : List<String> enumMonths = new List<String>{'January_Volume__c', 'February_Volume__c', 'March_Volume__c', 'April_Volume__c','May_Volume__c','June_Volume__c','July_Volume__c','August_Volume__c', 'September_Volume__c','October_Volume__c','November_Volume__c','December_Volume__c' };
    – user137770
    Nov 24, 2023 at 11:10
  • @NBO I have added code for all months in the answer. Please check. Nov 24, 2023 at 11:32
  • yeah for the first suggestion i mean if we repeate it for 12 month it will be too much i think not sure if we can replace the api name of the months dynamically
    – user137770
    Nov 24, 2023 at 11:58
  • @NBO I have added code for all months for #1 also. Please check. Nov 24, 2023 at 12:53

You must log in to answer this question.