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
pintoo rajputpintoo rajput 

Trigger to count number of Contacts associated with an Account ???

trigger should work for after insert , after update, after delete, after undelete 
 Thanks  in advance
Amit Chaudhary 8Amit Chaudhary 8
Please try below code
trigger countcontacts on Contact (after insert, after delete) {
    Set<Id> aId = new Set<Id>();
    
    if(Trigger.isInsert){
        System.debug('Insert contact for trigger.new - '+Trigger.New);
        for(Contact opp : Trigger.New){
            aId.add(opp.AccountId);
        }
        List<Account> acc = [select id,count_of_contacts__c from Account where Id in:aId];
        List<Contact> con = [select id from contact where AccountId in :aId];
        
        for(Account a : acc){
            a.count_of_contacts__c=con.size();
        }
        update acc;
        System.debug('Number is '+acc);
    }
    
    if(Trigger.isDelete){
        System.debug('delete contact for trigger.old - '+Trigger.Old);
        for(Contact opp : Trigger.old){
            aId.add(opp.AccountId);
        }
        List<Account> acc = [select id,count_of_contacts__c from Account where Id in:aId];
        List<Contact> con = [select id from contact where AccountId in :aId];
        
        for(Account a : acc){
            a.count_of_contacts__c=con.size();
            
        }
        update acc;
        System.debug('Number is '+acc);
    }
Let us know if this will help you

Thanks
Amit Chaudhary
 
Vasani ParthVasani Parth
Hi Pintoo,

Here you go,
trigger ContactsOnAccount on Contact (after insert, after delete,after undelete,after update) {
    Set<Id> aId = new Set<Id>();

    if(Trigger.isInsert || Trigger.isUndelete){
        for(Contact opp : Trigger.New){
            aId.add(opp.AccountId);
        }
        List<Account> acc = [select id,No_of_Contacts_in_SFDC__c from Account where Id in:aId];
        List<Contact> con = [select id from contact where AccountId in :aId];

        for(Account a : acc){
            a.No_of_Contacts_in_SFDC__c=con.size();

        }update acc;
    }

    if(Trigger.isDelete){
        for(Contact opp : Trigger.old){
            aId.add(opp.AccountId);
        }
        List<Account> acc = [select id,No_of_Contacts_in_SFDC__c from Account where Id in:aId];
        List<Contact> con = [select id from contact where AccountId in :aId];

        for(Account a : acc){
            a.No_of_Contacts_in_SFDC__c=con.size();

        }update acc;
    }

    if(Trigger.isUpdate){
       Set<Id> OldAId = new Set<Id>(); 
        for(Contact opp : Trigger.new){
        if(opp.AccountId != Trigger.oldMap.get(opp.id).AccountId || opp.Primary_Contact__c != Trigger.oldMap.get(opp.id).Primary_Contact__c)
            aId.add(opp.AccountId);
            OldAId.add(Trigger.oldMap.get(opp.id).AccountId);

        }
        if(!aId.isEmpty()){
        //for new Accounts
        List<Account> acc = [select id,No_of_Contacts_in_SFDC__c from Account where Id in:aId];
        //For New Account Contacts
        List<Contact> con = [select id from contact where AccountId in :aId];

        /*
        This is For Old Contacts Count
                              */

        //for Old Accounts
        List<Account> Oldacc = [select id,No_of_Contacts_in_SFDC__c from Account where Id in:OldAId];

        //For Old Account Contacts
        List<Contact> OldCon = [select id from contact where AccountId in :OldAId];

        //For New Accounts
        for(Account a : acc){
            a.No_of_Contacts_in_SFDC__c=con.size();

        }update acc;

        //For Old Accounts
        for(Account a : Oldacc){
            a.No_of_Contacts_in_SFDC__c=OldCon.size();

        }update Oldacc;
        }
    }
}

Please mark this as the best answer if this helps
Rakesh51Rakesh51
trigger ContactTrigger on Contact (after insert, after update, after delete, after undelete) {
    //---> above handling all states which could see a contact added to or removed from an account
   
    //---> on delete we use Trigger.Old, all else, Trigger.new
    List<Contact> contacts = Trigger.isDelete ? Trigger.old : Trigger.new;

    //---> the Set class rocks for finding the unique values in a list
    Set<Id> acctIds = new Set<Id>();
   
    for (Contact c : contacts) {
     //yes, you can have a contact without an account
        if (c.AccountId != null) {
            acctIds.add(c.AccountId);
        }
    }
   
    List<Account> acctsToRollup = new List<Account>();
    
    //****** Here is the Aggregate query...don't count in loops, let the DB do it for you*****
    for (AggregateResult ar : [SELECT AccountId AcctId, Count(id) ContactCount 
                               FROM Contact 
                               WHERE AccountId in: acctIds 
                               GROUP BY AccountId]){
        Account a = new Account();
        a.Id = (Id) ar.get('AcctId'); //---> handy trick for updates, set the id and update
        a.Contact_Count__c = (Integer) ar.get('ContactCount');
        acctsToRollup.add(a);
    }
    
    //----> probably you'll want to do a little more error handling than this...but this should work. 
    update acctsToRollup;

}
There are a couple of things I would do differently. But the main thing I would suggest is using an aggregate SOQL query to count the child contacts. See comments below: Maps are super useful, but in this instance (always increment/decrement according to changes in child) you can't beat a simple aggregate SOQL query. 
 
pintoo rajputpintoo rajput
Thanks to all
@Rakesh51 your code is not working when we are transferring the contact from one account to another account..
@Vasani Parth can you please help me to understand why we we are using Primary_Contact__c?
 
Sam MalhotraSam Malhotra
trigger ContactCount on Contact (after insert, after update, after delete) {
      Map<Id, List<Contact>> mapAcctIdContactList = new Map<Id, List<Contact>>();
      Map<Id, List<Contact>> mapAcctIdDelContactList = new Map<Id, List<Contact>>();
    Set<Id> AcctIds = new Set<Id>();    
    List<Account> listAcc = new List<Account>();
    
    if(trigger.isInsert) {
        for(Contact Con : trigger.New) {
            if(String.isNotBlank(Con.AccountId)) {
                if(!mapAcctIdContactList.containsKey(Con.AccountId)) {
                    mapAcctIdContactList.put(Con.AccountId, new List<Contact>());
                }
                mapAcctIdContactList.get(Con.AccountId).add(Con); 
                AcctIds.add(Con.AccountId);
            }   
        }  
    }
    
    if(trigger.isUpdate) {
        for(Contact Con : trigger.New) {
            if(String.isNotBlank(Con.AccountId) && Con.AccountId != trigger.oldMap.get(Con.Id).AccountId) {
                if(!mapAcctIdContactList.containsKey(Con.AccountId)){
                    mapAcctIdContactList.put(Con.AccountId, new List<Contact>());
                }
                mapAcctIdContactList.get(Con.AccountId).add(Con); 
                AcctIds.add(Con.AccountId);
            } else if(String.isBlank(Con.AccountId) && String.isNotBlank(trigger.oldMap.get(Con.Id).AccountId)) {
                if(!mapAcctIdDelContactList.containsKey(Con.AccountId)){
                    mapAcctIdDelContactList.put(Con.AccountId, new List<Contact>());
                }
                mapAcctIdDelContactList.get(Con.AccountId).add(Con);   
                AcctIds.add(trigger.oldMap.get(Con.Id).AccountId);
            }
        }  
    }  

    if(trigger.isDelete) {
        for(Contact Con : trigger.Old) {
            if(String.isNotBlank(Con.AccountId)){
                if(!mapAcctIdDelContactList.containsKey(Con.AccountId)){
                    mapAcctIdDelContactList.put(Con.AccountId, new List<Contact>());
                }
                mapAcctIdDelContactList.get(Con.AccountId).add(Con);    
                AcctIds.add(Con.AccountId); 
            }
        }  
    }   
    
    if(AcctIds.size() > 0) {
        listAcc = [SELECT Id, Contact_Count__c FROM Account WHERE Id IN : AcctIds];
        
        for(Account acct : listAcc) {
            Integer noOfConts = 0;
            if(mapAcctIdContactList.containsKey(acct.Id)) {
                noOfConts += mapAcctIdContactList.get(acct.Id).size();
            }
            if(mapAcctIdDelContactList.containsKey(acct.Id)) {
                noOfConts -= mapAcctIdDelContactList.get(acct.Id).size();
            }
            acct.Contact_Count__c = acct.Contact_Count__c == null ? noOfConts : (acct.Contact_Count__c + noOfConts);
        }
        
        update listAcc;    
    }
}
Forrest MulduneForrest Muldune
Vasani,

would you happen to have an Apex test class for your trigger?
Francis CrumpFrancis Crump
Thanks Rakesh
sagar077sagar077
Create an Apex Trigger that will count the number of contacts associated with an account(create a field at account level). Must update the count in insertion and deletion of a contact.

CODE-

trigger CountonAccountofcontact on Contact (after insert,after delete)
{
    Set<Id> mysetid = new Set <Id>();
        if(Trigger.isinsert)
        {
            System.debug('Insert new contact for trigger.new '+ Trigger.new);
            for(Contact contac :trigger.new)
                {
                    mysetid.add(contac.Accountid);
                }
            List<Account> Acc = [Select Id,Number_Of_Contact_Count__c from Account where Id in : mysetid];
            List<Contact> Con = [Select Id from Contact where Accountid in : mysetid];
            for(Account A: Acc)
                {
                    A.Number_Of_Contact_Count__c = Con.size(); 
                }
            update Acc;
            System.debug('Number of count is ' + Acc);
        }

     if(Trigger.isdelete)
        {
            System.debug('The Delete Contact Name For Trigger.old'+ Trigger.Old); 
            for(Contact contac : Trigger.Old)
                {
                    mysetid.add(contac.Accountid);
                }          
            List<Account> Acc = [Select id,Number_Of_Contact_Count__c from Account where id in: mysetid];
            List<Contact> Con = [Select id from Contact where Accountid in : mysetid];
           
            for(Account A :Acc)
                {
                    A.Number_Of_Contact_Count__c = Con.size();
                }
                update Acc;
            System.debug('The Update number is '+ Acc);
        }
    }

NOTE- This code is running but I want for After Update event also and Plz Help me in that 
 
Suraj Tripathi 47Suraj Tripathi 47
Hi pintoo,
"Try this code."
trigger CountAccountRelatedcontacts on Contact (after insert, after delete) {
    Set<Id> conId = new Set<Id>();
    if(Trigger.isInsert){
        for(Contact con : Trigger.New){
            conId.add(con.AccountId);
        }
        List<Account> accList = [select id,count_of_contacts__c from Account where Id in:conId];
        List<Contact> conList = [select id.lastname from contact where AccountId in :conId];
        
        for(Account a : acc){
            a.count_of_contacts__c=con.size();
        }
        update acc;
    }
    
    if(Trigger.isDelete){
        for(Contact con : Trigger.old){
            conId.add(con.AccountId);
        }
        List<Account> accList = [select id,count_of_contacts__c from Account where Id in:conId];
        List<Contact> conList = [select id.lastname from contact where AccountId in :conId];
        
        for(Account a : acc){
            a.count_of_contacts__c=con.size();
            
        }
        update acc;
    }

If you find your Solution then mark this as the best answer. 

Thank you!

Regards 
Suraj Tripathi