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
BrandiTBrandiT 

Roll-Up Summary to show # of Contacts on Account - using Trigger

I need a Roll-up summary field on Accounts showing the number of related contacts.  Unfortunately, this is a lookup relationship so roll-up summaries are not available. 

 

I found a trigger that was written as a work around to this problem, but since I have no experience with triggers I need help revising the code.

 

I only want the contact counted if a field on the contact (Billing Contact) = True.  The trigger I found will count all contacts.  There may be 20 contacts on the account, but only 5 of them are marked billing contacts.  I only want this trigger to count the 5 contacts marked Billing.

 

How can I modify this code to accomplish this or is there a better way?

 

Thanks so much!!!

 

/* Provide summary of Number of Contacts on Account record */

trigger ContactSumTrigger on Contact (after delete, after insert, after undelete,
after update) {

    Contact[] cons;
    if (Trigger.isDelete)
        cons = Trigger.old;
    else
        cons = Trigger.new;

    // get list of accounts
    Set<ID> acctIds = new Set<ID>();
    for (Contact con : cons) {
            acctIds.add(con.AccountId);
    }
   
    Map<ID, Contact> contactsForAccounts = new Map<ID, Contact>([select Id
                                                            ,AccountId
                                                            from Contact
                                                            where AccountId in :acctIds]);

    Map<ID, Account> acctsToUpdate = new Map<ID, Account>([select Id
                                                                 ,Number_of_Contacts__c
                                                                  from Account
                                                                  where Id in :acctIds]);
                                                                
    for (Account acct : acctsToUpdate.values()) {
        Set<ID> conIds = new Set<ID>();
        for (Contact con : contactsForAccounts.values()) {
            if (con.AccountId == acct.Id)
                conIds.add(con.Id);
        }
        if (acct.Number_of_Contacts__c != conIds.size())
            acct.Number_of_Contacts__c = conIds.size();
    }

    update acctsToUpdate.values();

}

Best Answer chosen by Admin (Salesforce Developers) 
werewolfwerewolf

Just change the where clause on the Contact part, like

 

 [select Id,AccountIdfrom Contact where AccountId in :acctIds and Billing_Contact__c=True]

 

I would note though that if you have a lot of contacts or if you are updating many contacts in bulk, this trigger may break down due to Apex limits. Say for example you add the 1,001th contact to an account -- this trigger will fail because you can't query more than 1000 records at once, and here it's counting all the contacts under each account and so it will hit the limit.  It's OK if your number of contacts per account is low, but be forewarned.  It can be rewritten in such a way that this is not a problem, but that would require breaking it out into a batch method for the initial calculation and then a trigger that just makes incremental changes to the affected accounts. Just so you know.

All Answers

werewolfwerewolf

Just change the where clause on the Contact part, like

 

 [select Id,AccountIdfrom Contact where AccountId in :acctIds and Billing_Contact__c=True]

 

I would note though that if you have a lot of contacts or if you are updating many contacts in bulk, this trigger may break down due to Apex limits. Say for example you add the 1,001th contact to an account -- this trigger will fail because you can't query more than 1000 records at once, and here it's counting all the contacts under each account and so it will hit the limit.  It's OK if your number of contacts per account is low, but be forewarned.  It can be rewritten in such a way that this is not a problem, but that would require breaking it out into a batch method for the initial calculation and then a trigger that just makes incremental changes to the affected accounts. Just so you know.

This was selected as the best answer
BrandiTBrandiT
This worked great!!!  Thanks so much for your help!
BrandiTBrandiT

Ok now I have another question.  I wonder if I could do another trigger to show me the number of contact roles assigned to an account.  Is that possible?  Where would I put the trigger?  There isn't a Contact Role section in setup so would I just add the trigger under accounts and change all references to Contacts to "ContactRoles"?

 

What do you think?

 

Thanks again!

werewolfwerewolf
Not with a trigger, no.  AccountContactRole is not a triggerable object as of this writing.  You could perhaps create a scheduled Apex routine (after Spring '10 when Scheduled Apex is generally available) that goes through your accounts, counts the number of contact roles, and saves them to the parent accounts once a day or once a week or something, but unfortunately there's not much else you can do.
GregDevGregDev

I "copied"  that trigger for my own related object- worked in sandbox, but in production only "fires" if I create a new account.  When I update an existing account the field doesn't get populated.

Any suggestiions

 

trigger CurrConnectionCount on Buddy_Connection__c (after delete, after insert, after undelete,
after update) {
/* Provide summary of Number of Contacts on Account record

trigger ContactSumTrigger on Contact */

Buddy_Connection__c[] cons;
if (Trigger.isDelete)
cons = Trigger.old;
else
cons = Trigger.new;

// get list of accounts
Set<ID> acctIds = new Set<ID>();
for (Buddy_Connection__c con : cons) {
acctIds.add(con.Organisation__c);
}

Map<ID, Buddy_Connection__c> contactsForAccounts = new Map<ID, Buddy_Connection__c>([select Id
,Organisation__c
from Buddy_Connection__c
where Organisation__c in :acctIds]);

Map<ID, Account> acctsToUpdate = new Map<ID, Account>([select Id
,BD_Connections_Current__c
from Account
where Id in :acctIds]);

for (Account acct : acctsToUpdate.values()) {
Set<ID> conIds = new Set<ID>();
for (Buddy_Connection__c con : contactsForAccounts.values()) {
if (con.Organisation__c == acct.Id)
conIds.add(con.Id);
}
if (acct.BD_Connections_Current__c != conIds.size())
acct.BD_Connections_Current__c = conIds.size();
}

update acctsToUpdate.values();

}

 

s shekar 20s shekar 20
Hi is it possible to write trigger on account and can we get the account related contacts. Based on the above scenario,i need to update the field on account No of__ contacts__c 
sai babu 1sai babu 1
WHY DELETED CONTACTS ARE ALSO COUNTED.