function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
jaw999jaw999 

Bulkify Roll Up Summary Trigger

I just need to do a trigger version of a Roll up summary. Made it easily for single use but mass Apex updates overload. Here's my un-bulked code below. Any help would be apprecieated.

Assigned_Team__c is a related object to Account that I want to count. 

 

trigger CountCov on Account (before insert, before update) {
    Account [] a = Trigger.new;
    String aid = null;    
    Aid = a[0].id;

        Integer i = [select count() from Assigned_Team__c where Account__c = :aid and Name != 'None'];

    a[0].Coverage_count__c = i;
    }

 

Best Answer chosen by Admin (Salesforce Developers) 
Naidu PothiniNaidu Pothini
trigger CountCov on Account (before update)
{
    if(trigger.isBefore && trigger.isUpdate)
    {
        Map<Id, AggregateResult> arMap = new Map<Id, AggregateResult>([SELECT Account__c Id, Count(Id) cnt FROM Assigned_Team__c WHERE Account__c IN :Trigger.newMap.keySet() AND Name != 'NONE' GROUP BY Account__c]);

        for(Account a : trigger.new)
  	{
   	    if(arMap.containsKey(a.id))
	    {
	       a.Coverage_count__c = Integer.valueOf((arMap.get(a.Id)).get('cnt'));
	    }
	    else
	    {
	        a.Coverage_Count__c = 0;
	    }
	}
    }
}

 try this.

All Answers

Bhawani SharmaBhawani Sharma
You can do an aggregate query like

for(AggregateResult agg : [Select Count() cCount, Account__c accId from Assigned_Team__c where Account__c IN: Trigger.newMap.keySet() group by Assigned_Team__c]) {
accountsList.add(new Account(Id = Id.valueOf(String.valueOf(agg.get(accId))), Coverage_count__c = agg.get('cCount')));
}
update accountList;
jaw999jaw999

thanks - but not quite compiling - what am i missing?

 

trigger CountCov on Account (before insert, before update) {
  Account [] a = Trigger.new;
    String aid = null;    
    Aid = a[0].id;
    
    for(AggregateResult agg : [Select Count()  Account__c accId from Assigned_Team__c where Account__c IN: Trigger.newMap.keySet() group by Assigned_Team__c]) {
accountsList.add(new Account(Id = Id.valueOf(String.valueOf(agg.get(accId))), Coverage_count__c = agg.get('cCount')));
}
update accountList;

Error: Compile Error: unexpected token: Account__c at line 6 column 47 

s_k_as_k_a

Try below code

 

trigger CountCov on Account (before insert, before update) {
   if(trigger.isBefore && (trigger.isInsert || trigger.isUpdate))
	{
       Map<Id, Integer> acctToassigntsMap = new Map<Id, Integer>();
	   for (AggregateResult agr :[select count(id) assigmentsCount, account__c from Assigned_Team__c where Account__c in :trigger.newmap.keySet() group by account__c])
		{
           acctToassigntsMap.put((id)agr.get('account__c'), (integer)(agr.get('assigmentsCount');
		}
	   for(Account a : trigger.new)
		{
		   if(acctToassigntsMap.containsKey(a.id) && acctToassigntsMap.get(a.id)!=null)
			   a.Coverage_count__c = acctToassigntsMap.get(a.id);
		}
	}
}

 

jaw999jaw999

thanks! but i ran into an error when inserting new accounts:

 

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger CountCov caused an unexpected exception, contact your administrator: CountCov: execution of BeforeInsert caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.CountCov: line 5, column 1

jaw999jaw999
But i can skip that error b/c I can change to only an Update trigger - never can an account be inserted and need to check/count b/c it will always be zero.
jaw999jaw999
But this is not producing a zero for Accounts with no related Assigned Teams
s_k_as_k_a

Add these line below Map declaration at line 4(below). 

 

set<Id> accountIds = new Set<Id>();
for(account a: trigger.new)
accountIds.add(a.Id);

jaw999jaw999

Was that an insert fix? 

 

s_k_as_k_a

try below modified mode

trigger CountCov on Account (before insert, before update) {
   if(trigger.isBefore && (trigger.isInsert || trigger.isUpdate))
	{
       Map<Id, Integer> acctToassigntsMap = new Map<Id, Integer>();
	   set<Id> accountIds = new Set<Id>();
	   for(account a: trigger.new)
		   accountIds.add(a.Id);	   
	   for (AggregateResult agr :[select count(id) assigmentsCount, account__c from Assigned_Team__c where Account__c in :accountIds group by account__c])
		{
           acctToassigntsMap.put((id)agr.get('account__c'), (integer)(agr.get('assigmentsCount');
		}
	   for(Account a : trigger.new)
		{
		   if(acctToassigntsMap.containsKey(a.id) && acctToassigntsMap.get(a.id)!=null)
			{
			   if(acctToassigntsMap.get(a.id) != 0)
			       a.Coverage_count__c = acctToassigntsMap.get(a.id);
			}
		}
	}
}

 

s_k_as_k_a

yes ,it will work for both before insert and update

jaw999jaw999
Right, working, but does not update with a zero for accounts that have no child Assigned teams. is this possible?
jaw999jaw999
Also, we lost the part where it doesn't count Assigned Teams with the Name "None" -
s_k_as_k_a

To show zero on account for no assignments remove this line

 

if(acctToassigntsMap.get(a.id) != 0)

jaw999jaw999

here is what i have - it won't show a zero and it still counts a team named 'NONE' : thanks again

 

trigger CountCov on Account (before update) {
   if(trigger.isBefore && (trigger.isInsert || trigger.isUpdate))
    {
       Map<Id, Integer> acctToassigntsMap = new Map<Id, Integer>();
       set<Id> accountIds = new Set<Id>();
       for(account a: trigger.new)
           accountIds.add(a.Id);       
       for (AggregateResult agr :[select count(id) assigmentsCount, account__c from Assigned_Team__c where name!='NONE' and Account__c in :accountIds group by account__c])
        {
           acctToassigntsMap.put((id)agr.get('account__c'), (integer)(agr.get('assigmentsCount')));
        }
       for(Account a : trigger.new)
        {
           if(acctToassigntsMap.containsKey(a.id) && acctToassigntsMap.get(a.id)!=null)
            {
              // if(acctToassigntsMap.get(a.id) != 0)
                   a.Coverage_count__c = acctToassigntsMap.get(a.id);
            }
        }
    }
}

 

s_k_as_k_a

add where cluse in soql query   where Name != null 

 

 

jaw999jaw999

Odd. I had an Assigned_Team__c called NONE - or so I thought. Maybe it has a space after so it was ebign counted. Anyway, looks good, thanks.

jaw999jaw999

It seems to work only if i also comment out this other line (work in terms of updating when it should be a zero, though it still puts in a blank instead of a zero)

 

 for(Account a : trigger.new)
        {
        // comment this out too   if(acctToassigntsMap.containsKey(a.id) && acctToassigntsMap.get(a.id)!=null)
            {
              // if(acctToassigntsMap.get(a.id) != 0)
                   a.Coverage_count__c = acctToassigntsMap.get(a.id);

 does that make sense?

Naidu PothiniNaidu Pothini
trigger CountCov on Account (before update)
{
    if(trigger.isBefore && trigger.isUpdate)
    {
        Map<Id, AggregateResult> arMap = new Map<Id, AggregateResult>([SELECT Account__c Id, Count(Id) cnt FROM Assigned_Team__c WHERE Account__c IN :Trigger.newMap.keySet() AND Name != 'NONE' GROUP BY Account__c]);

        for(Account a : trigger.new)
  	{
   	    if(arMap.containsKey(a.id))
	    {
	       a.Coverage_count__c = Integer.valueOf((arMap.get(a.Id)).get('cnt'));
	    }
	    else
	    {
	        a.Coverage_Count__c = 0;
	    }
	}
    }
}

 try this.

This was selected as the best answer
jaw999jaw999
Thanks, this seems to be working and inputs a zero when appropriate.