質問

I have a batch program that I need to aggregate (rollup) several currency fields by a specific contact and fund. I need a fresh set of eyes on this as I can't figure out how I need to correctly rollup the fields by the contact and fund.

Here is my current code in the batch program:

    for (My_SObject__c obj : (List<My_SObject__c>)scope) {
        if(!dbrToContactMap.isEmpty() && dbrToContactMap.size() > 0) {
            if(dbrToContactMap.containsKey(obj.DBR__c)) {
                List<Id> contactIds = dbrToContactMap.get(obj.DBR__c);
                for(Id contactId : contactIds) {
                    My_Rollup__c rollup = new My_Rollup__c();
                    rollup.Fund_Name__c = obj.FundName__r.Name;
                    rollup.DBR__c = obj.DBR__c;
                    rollup.Contact__c = contactId;
                    rollup.YearToDate__c = obj.YearToDate__c;
                    rollup.PriorYear__c = obj.PriorYear__c;
                    rollupsToInsert.add(rollup);
                }
            }
        }
    }       
    if(!rollupsToInsert.isEmpty() && rollupsToInsert.size() > 0) {
        insert rollupsToInsert;
    }

I'm iterating over the scope of records, which is about 275,000 records that are returned. I have a map that returns a list of contacts by the key field in my scope.

Now, currently, as I loop over each contact, I put those into a list and insert. The problem is I need to aggregate (rollup) by fund and contact.

For example, let's say the map returns the contact for "John Doe" ten times for the specific key field. So, there are going to be 10 related records on "John Doe's" contact record.

The problem is that the same fund can be in those 10 records, which need to be aggregated.

So, if "Fund A" shows up 5 times and "Fund B" shows up 3 times and "Fund C" shows up 2 times, then I should only have 3 related records in total on the "John Doe" contact record that are aggregated (rolled up) by the fund.

I haven't been able to figure out how to do the rollup by fund in my list.

Can anyone help?

Any help is appreciated.

Thanks.

役に立ちましたか?

解決

The key here is to use a stringified index key for your map, instead of using a raw Sobject ID. Think of this as a composite foreign key, where the combined values from a Fund and a DBR are joined. Here is the basic idea:

Map<String, My_Rollup__c> rollupMap = new Map<String, My_Rollup__c>();

for (My_SObject__c obj : (List<My_SObject__c>) scope)  {
    // .. stuff ..

    String index = '' + new String[] {
        '' + obj.FundName__r.Id,
        '' + obj.DBR__c,
        '' + contactId
    };

    // Find existing rollup, or create new rollup object...
    My_Rollup__c rollup = rollupMap.get(index);

    if (rollup == null) {
        rollup = new My_Rollup__c();
        rollupMap.put(index, rollup);
    }

    // Aggregate values..
}

// And save
if (rollupMap.isEmpty() == false) {
    insert rollupMap.values();
}

The result is that you combining all the different "keys" that makeup a unique rollup record into a single stringified key, and then using that stringified key as the index in the map to enforce uniqueness.

The example above is incomplete, but you should be able to take it from here.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top