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
Gita09Gita09 

Trigger to count number of contacts associated with an account

Hi All,

I want to display number of contacts associated with an account using triggers.

for this I had created a lookup field like noofcontacts__c in account  object. and Wrote code as

trigger numberofcontacts on contact(after insert, after update, after delete) {
    Map<Id, List<Contact>> AcctContactList = new Map<Id, List<Contact>>();
    Set<Id> AcctIds = new Set<Id>();   
    List<schema.Account> AcctList = new List<schema.Account>();
    List<schema.Contact> ConList = new List<schema.Contact>();
   
    if(trigger.isInsert || trigger.isUPdate) {
        for(Contact Con : trigger.New) {
            if(String.isNotBlank(Con.AccountId)){
                AcctIds.add(Con.AccountId); 
            }  
        } 
    }
   
    if(trigger.isDelete) {
        for(Contact Con : trigger.Old) {
            AcctIds.add(Con.AccountId);    
        } 
    }          
   
    if(AcctIds.size() > 0){
        ConList = [SELECT Id, AccountId FROM Contact WHERE AccountId IN : AcctIds];
       
        for(Contact Con : ConList) {
            if(!AcctContactList.containsKey(Con.AccountId)){
                AcctContactList.put(Con.AccountId, new List<Contact>());
            }
            AcctContactList.get(Con.AccountId).add(Con);     
        }                          
      
           
        AcctList = [SELECT noofContacts__c FROM Account WHERE Id IN : AcctIds];
        for(Account Acc : AcctList) {
            List<schema.Contact> ContList = new List<schema.Contact>();
            ContList = AcctContactList.get(Acc.Id);
            Acc.Number_of_Contacts__c = ContList.size();
        }   
       
      
        update AcctList;   
    }

}
 I am   getting an error as "Variable doesnot exist:id".

Kindly support and suggest.

Thanks
Jen BennettJen Bennett
It's easier to read the code if you use the <> and paste code in there, then you can also refer to the line in the code the error is pointing to. There is a blog post out there that might help you out:
http://www.infallibletechie.com/2013/09/trigger-to-count-number-of-contacts.html
Gita09Gita09
Hi,

Thank you for response.

With the help of this link only,we wrote that code.

Iam getting same error now.

Kindly suggest and support.









Peter_sfdcPeter_sfdc
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: 
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;

}

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. 



Ravi NarayananRavi Narayanan
trigger updateAccount on Account (before Update) {

List<Contact> Contactlist=[select id,name,phone,accountid from contact where accountID In :trigger.new ];
map<id,integer> countMap=new map<id,integer>();
integer i=1;
for(contact c:contactlist)
{
       if(countmap.containskey(c.accountid))
       {
           i=countmap.get(c.accountid)+1;
           countmap.put(c.accountid,i);
       }
       else
       {
              countMap.put(c.accountid,i);
       }
}

for(account a:trigger.new)
{
try{
        if(countmap.containskey(a.id))
            a.Contact_Count__c=countMap.get(a.id);
   }
   catch(exception e)
   {
  
   }
}
}
Jen BennettJen Bennett
Try adding the ID to your SELECT statement here:
AcctList = [SELECT noofContacts__c FROM Account WHERE Id IN : AcctIds];
Peter_sfdcPeter_sfdc
ID should be implicitly retrieved in SOQL queries that occur in Apex. But it would be good to check that out. 
Gita09Gita09
Hi Peter,

Thank you for response.

I had used your logic.But,I am getting same error as" Variable doesnot exist :id"

Awaiting for your response.

KbhaskarKbhaskar
hi,
the below code works well for me.
trigger noofcontacts on Contact (after insert,after delete) {


set<id>accid=new set<id>();

list<contact>contactlist=new list<contact>();
list<contact>listcon=new list<contact>();
list<account>acclist=new list<account>();
list<account>listacc=new list<account>();
map<id,integer>mapCount=new map<id,integer>();


if(trigger.isinsert)                              //insert   con
{
for(contact con:trigger.new)
{
accid.add(con.accountid);
}
}

if (trigger.isdelete)                          //delete  con
{
for(contact con:trigger.old)
{
accid.add(con.accountid);
}
}

acclist=[SELECT id,name FROM account WHERE id in:accid];
contactlist=[SELECT id,name,accountid FROM contact WHERE accountid in:accid];

for(account acc:acclist){
listcon.clear();
for(contact c:contactlist){
if(c.accountid==acc.id){
listcon.add(c);

mapCount.put(c.accountid,listcon.size());
}
}
}

if(acclist.size()>0){

for(Account a:acclist)
{
if(mapCount.get(a.id)==null)
a.No_of_Contact__c =0;

else

a.No_of_Contact__c =mapCount.get(a.id);
listacc.add(a);
}
}


if(listacc.size()>0)

update listacc;
}
User-added image 

 
Angela Toedtman 6Angela Toedtman 6
Kbhaskar would you happen to have a test class for this you can share?  Please?
Gowrishankar SubramanianGowrishankar Subramanian
A slightly modified version of Kbhaskar's code above. Uses inner query instead of multiple SELECT queries. 
 
trigger FindContactsCount on Contact (after insert, after update, after delete) {
    
   List<Contact> modContacts = Trigger.isDelete ? Trigger.old:Trigger.new;
    Set<Id> accIds  = new Set<Id>();
    for (Contact c: modContacts)  {
        accIds.add(c.AccountId);
    }
   List<Account> modAccounts = [Select Name, (Select Id from Contacts)  from Account WHERE Id in: accIds ];

    for (Account a: modAccounts) {
       List<Contact> s = a.Contacts;
       System.debug('Account:' + a.Name + ' No. of Contacts: '+ s.size()); 
       a.No_of_Contacts__c = s.size();
    }
}




User-added image
Pathan SPathan S
Any one post through workflow to count number of contacts associated with an account in salesforce?
Akanksha sharma 15Akanksha sharma 15
hi all,
As we have count total no of account associated with account .But i want to update the field when there is reparenting (Suppose i have created c1 on account a1 so  count is 1 but i do some change i changed the account from a1 to a2 on same contact c1 and then after saved it i am getting the same count on count field so anyone can can suggest how can i achieve this?
 
Sagar MauryaSagar Maurya
Hi @akanksha,

Please find below code that will cover all the scenarios-

trigger ContactTrigger on Contact(after insert,after update, after delete){
if(trigger.isAfter){
        Map<Id, Account> accounts = new Map<Id, Account>();
        
        for(Contact con : Trigger.isdelete? Trigger.old: Trigger.new){
             accounts.put(con.AccountId, new Account(Id=con.AccountId,NoOfContacts__c=0));
            if(trigger.isUpdate){                
                for(Contact co: trigger.Old){
                    if(co.AccountId!=con.AccountId){
                        accounts.put(co.AccountId, new Account(Id=co.AccountId,NoOfContacts__c=0));
                    }
                }
            }
        }
        
        for(AggregateResult result : [Select count(id) cou, AccountId Account From Contact Where AccountId IN : accounts.keySet() Group By AccountId]){
            accounts.put((Id)result.get('Account'), new Account(Id = (Id)result.get('Account'), NoOfContacts__c = Integer)result.get('cou')));
        }        
        update accounts.values();
    }
}

Hope the above code helps.

Thanks.
Rupesh BRupesh B
trigger CountofCNTonAccount on Contact (after insert,after delete) {
    if (trigger.isInsert && trigger.isAfter){
        Account acc = new Account();
        acc=[select id,NumberofLocations__c	from account where id=:trigger.new[0].accountId];
        list<contact> contsize = new list<contact>();
        contsize = [ select id,lastname from contact where accountId = :trigger.new[0].accountId];
        acc.NumberofLocations__c = contsize.size();
        update acc;
    }
    if(trigger.IsDelete && trigger.isAfter){
        Account acc = new Account();
        acc=[select id,NumberofLocations__c	from account where id=:trigger.old[0].accountId];
        list<contact> contsize = new list<contact>();
        contsize = [ select id,lastname from contact where accountId = :trigger.old[0].accountId];
        acc.NumberofLocations__c = contsize.size();
        update acc;
        
    }    
}

NumberofLocations__c  is the Count of the number of contacts associated with the account.
Hope this code helps you!!
Thanks.
ASIF ALIASIF ALI
This is very Simple , And Working fine;

trigger countContacts on Contact (after insert, after update, after delete) 
{
    list<contact> conList = new list<contact>();
    list<account> accList = new list<account>();
    set<ID> accIDs = new set<ID>();
    if(trigger.isInsert || trigger.isUpdate)
    {
        for(contact con : trigger.new)
        {
            if(String.isNotBlank(con.accountId))
            {
                accIds.add(con.accountId);
            }
        }
    }
    if(trigger.isDelete)
    {
        for(contact con : trigger.old)
        {
            accIDs.add(con.AccountId);
        }
    }
    if(accIDs.size()>0)
    {
        conList = [select name, id, accountId from contact where accountId IN:accIDs];
        accList = [select name, id , number_of_contacts__c from account where ID IN:accIDs];
    }
    for(account acc : accList)
    {
       acc.Number_of_contacts__c = conList.size();
    }
    update accList;

}
Mahesh Shimpi 4Mahesh Shimpi 4
How to test this?
 
Rohit KumawatRohit Kumawat
Hi @Mahesh Shimpi 4,

First you have to create one custom field, which you have used in your trigger for example field name as 'Number of Contacts' in the Account object.
After creating the custom field, just open any account record.
And in related contact list just create new contacts for that perticular account record.
once contacts are created or updated the account record also will be updated due to trigger  and the number of contacts asscoiated with the account in the contact related list . the total number of count of contacts in the list will show as the value of that account field 'Number of contacts'

for example:
Yoy have created 3 contacts asccoiated with an account record

so the value of the custom field in account object record aslo Number of contact = 3 .
Tharun Kumar dontha 22Tharun Kumar dontha 22
Hello 100% working, which works on insert, update and delete
ContactTrigger :
trigger Count_No_Contacts on Contact (before insert, after insert, after update, after delete) {
    ContactHandler handler = new ContactHandler();
    if(Trigger.isAfter && Trigger.isInsert){
        handler.countContacts(Trigger.new); }
    
    if(Trigger.isAfter && Trigger.isUpdate)  {
        handler.countContacts(Trigger.new);    }
    
    if(Trigger.isAfter && Trigger.isDelete)    {
        handler.countContacts(Trigger.old);    }
}
============================================
public class ContactHandler 
{
    List<Account> accountList = new List<Account>();
    List<Account> accountListUpdated = new List<Account>();
    public void countContacts(List<Contact> newList)   {
        for (Contact con : newList)  {
            system.debug('ContactsAccountID'+con.AccountId);
            accountList = [SELECT Id,Name,TrailApp_DonTes__Number_of_Contacts__c, (SELECT Id, Name FROM Contacts) 
                           FROM Account WHERE Id =: con.AccountId];
        }
        for (Account acc : accountList)  {
            acc.TrailApp_DonTes__Number_of_Contacts__c = acc.Contacts.size() ;
            accountListUpdated.add(acc);
        }
        update accountListUpdated;
    }
}
 
niranjan gaddam 6niranjan gaddam 6
trigger Nofcontacts on Contact (after insert,after update,after delete) {
set<id> accid=new set<id>();
    list<Account> accUpdate=new list<Account>();
    
    for(contact con:trigger.new){
        accid.add(con.accountid);
        
    }
    
    for(Account acc : [select id,no_of_contact__c,(select id from contacts) from account where id in :accid]){
         
       
            acc.no_of_contact__c=acc.contacts.size();
             accUpdate.add(acc);
         
    }
    update accUpdate;
}
kushagra gupta 23kushagra gupta 23
can someon explain why I am getting Variable does not exist: accountid at line 35 column 42? while I am trying to  write a program
Tharun Kumar dontha 22Tharun Kumar dontha 22
Hi 
@kushagra can u paste ur code, where u r getting the error
 
trigger Count_No_Contacts on Contact ( after insert, after update, after delete) 
{
    ContactHandler handler = new ContactHandler();
    if(Trigger.isAfter && Trigger.isInsert){
        handler.countContacts(Trigger.new); }
    
    if(Trigger.isAfter && Trigger.isUpdate)  {
        handler.countContacts(Trigger.new);    }
    
    if(Trigger.isAfter && Trigger.isDelete)    {
        handler.countContacts(Trigger.old);    }
}


public class ContactHandler 
{
    List<Account> accountList = new List<Account>();
    List<Account> accountListUpdated = new List<Account>();
    public void countContacts(List<Contact> newList)   {
        for (Contact con : newList)  {
            system.debug('ContactsAccountID'+con.AccountId);
            accountList = [SELECT Id,Name,TrailApp_DonTes__Number_of_Contacts__c, (SELECT Id, Name FROM Contacts) 
                           FROM Account WHERE Id =: con.AccountId];
        }
        for (Account acc : accountList)  {
            acc.TrailApp_DonTes__Number_of_Contacts__c = acc.Contacts.size() ;
            accountListUpdated.add(acc);
        }
        update accountListUpdated;
    }
}


 
pradeep Arukalapradeep Arukala

@Tharun kumar 22

your code works for single records.. can u please execute by entering 2 contacts with 2 Accounts on one go like below 

 

List<Contact> cons = new List<Contact>();
contact con = new contact();
con.lastName = 'Test1';
con.AccountId ='0012w000002rWuRAAU';
cons.add(con);

contact cond= new contact();
cond.lastName = 'Test2';
cond.AccountId= 'AccountId1';
cons.add(cond);
contact cone= new contact();
cone.lastName = 'Test4';
cone.AccountId= 'AccountId2';
cons.add(cone);

insert cons;


 

 

 

 

sagar077sagar077
Hello, Please me on this requirement.

Count Account with Different Industry(on account picklist fields is there)(e,g. For Industry Electronics we have 3 Accounts) using Map.

plz help me i am new in apex collection.
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 
Venkata GangulaVenkata Gangula
Hi Gita and sagar, please find the below trigger to display the count of contacts on the related field in Accounts.

This is the code written in very simple manner and can be easily understood

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

    set<id>accid=new set<id>();
    
    
    if(trigger.isinsert || trigger.isupdate || trigger.isundelete || contact.accountid!=null) 
    {
        for(contact con:trigger.new) 
        {
            accid.add(con.accountid);
        }
        
        list<account> acclist= new list<account>([select id,name,Number_of_Contacts__c,(select id, name from contacts) from account where id IN:accid ]);
        for(account acc:acclist)
        {
            acc.Number_of_Contacts__c= acc.contacts.size();
        }
        update acclist;
    } 
    }

if you find the answer as helpful, mark it as a solution and best answer so that other users with the same issue might be benefitted. Thank you
Jeniffer WilliamJeniffer William
HP Officejet 4650 Setup is the webpage that helps you to set up your Officejet with the help of our experts. Call us for instant help +1-888-701-0906 or visit our website https://123-hpcomsetup.com/.
Shubham Jain 338Shubham Jain 338
Hi, PFA the working code.

trigger TriggerContact on Contact (after insert, after update, after delete, after undelete) {
    
    List<Contact> contactList = Trigger.isDelete ? Trigger.Old : Trigger.New;
    Set<Id> accountIdSet = new Set<Id>();
    for (Contact con : contactList) {
        if (Trigger.isUpdate) {
            if (con.AccountId != Trigger.oldMap.get(con.Id).AccountId) {
                if (con.AccountId != null && Trigger.oldMap.get(con.Id).AccountId == null) {
                    accountIdSet.add(con.AccountId);
                } else if (con.AccountId == null && Trigger.oldMap.get(con.Id).AccountId != null){
                    Id accountId = Trigger.oldMap.get(con.Id).AccountId;
                    accountIdSet.add(accountId);
                } else {
                    accountIdSet.add(con.AccountId);
                    Id accountId = Trigger.oldMap.get(con.Id).AccountId;
                    accountIdSet.add(accountId);
                }    
            }
        } else if (con.AccountId != null) {
            accountIdSet.add(con.AccountId);
        }
    }
    if (accountIdSet.size() > 0) {
        List<Account> accountList = [SELECT Id, Contact_Count__c, (SELECT Id FROM Contacts) FROM Account WHERE Id IN :accountIdSet];
        if (accountList.size() > 0) {
            for (Account acc : accountList) {
                acc.Contact_Count__c = acc.Contacts.size();
            }
            update accountList;
        }
    }
}
Zeeshan Sayed 4Zeeshan Sayed 4
Very easy method which you can refer
if u find helpfull please give Thums up

trigger CountContactOnAcc on Contact (before insert,before update) {
    
    if(trigger.Isupdate || trigger.IsInsert){
        Set<id> AccIds = new Set<Id>();
        List<Account> UpdtAccList = new List<Account>();
        for(COntact c : trigger.new){
            AccIds.add(c.accountid);
        }
        List<Account> accList = [select id,name,total_employee__c,(select id,name from contacts) from Account where id in : AccIds];
        
        for(Account a :accLIst){
            a.total_employee__c = a.contacts.size();
            UpdtAccList.add(a);
        }
        update UpdtAccList;
    }
}
Todkar AishwaryaTodkar Aishwarya

Hi,

The below code is working for all listed operations:

  • Inserting Contact with an Account
  • Updating/Switching Accounts on Contacts ( this will update the count on both the Accounts )
  • Removing Account from Contact
  • Deleting Contact
  • Undeleting Contact
Contact Trigger
trigger ContactTrigger on Contact( after insert, after update, after delete, after undelete ) {

    if( Trigger.isAfter ) {

        if( Trigger.isInsert ) {
            ContactTriggerHandler.updateCount( trigger.new, null );
        }
        else if( Trigger.isUpdate) {
            ContactTriggerHandler.updateCount( trigger.new, trigger.oldMap );
        }
        else if( Trigger.isUndelete) {
            ContactTriggerHandler.updateCount( trigger.new, null );
        }
        else if( Trigger.isDelete ) {
            ContactTriggerHandler.updateCount( trigger.old, null );
        }
    }
}

Contact Trigger Handler
public class ContactTriggerHandler {

    public static void updateCount( List<Contact> listContacts, Map<Id,Contact> mapOldContacts ) {

        Set<Id> setAccountId = new Set<Id>();
        if( mapOldContacts == null || mapOldContacts.isEmpty() ) {
            for( Contact objCont : listContacts ) {
                if( objCont.AccountId != null ) {
                    setAccountId.add( objCont.AccountId );
                }
            }
        }
        else if( mapOldContacts != null && !mapOldContacts.isEmpty()) {
            for( Contact objCont : listContacts ) { 
                if( objCont.AccountId != null 
                && mapOldContacts.get( objCont.Id ).AccountId != objCont.AccountId ) {
                    setAccountId.add( objCont.AccountId );
                    if( mapOldContacts.get( objCont.Id ).AccountId != null ) {
                        setAccountId.add( mapOldContacts.get( objCont.Id ).AccountId );
                    }
                }
                else if( objCont.AccountId == null && mapOldContacts.get( objCont.Id ).AccountId != objCont.AccountId ) {
                    setAccountId.add( mapOldContacts.get( objCont.Id ).AccountId );
                }
            }
        }
        if( !setAccountId.isEmpty() ) {
            List<Account> listAccount = new List<Account>();
            for( Account objAcc : [ SELECT 
                                        Id
                                        , ( SELECT Id FROM Contacts)
                                    FROM
                                        Account
                                    WHERE
                                        Id In : setAccountId ] ) {
                objAcc.Number_Of_Contacts__c = objAcc.Contacts != null && ( !objAcc.Contacts.isempty() ) ? objAcc.Contacts.size() : 0;
                listAccount.add( objAcc );
            }

            if( !listAccount.isEmpty() ) {
                update listAccount;
            }
        }
    }
}

Thanks!
 
AvinashNAvinashN
Try below code :) 

trigger ContactTrigger on Contact (after insert,after update, after delete, after undelete) {
    
    if(Trigger.isAfter)
    {        
        Map<Id,Integer> mapAcctIdAndContSize=new Map<Id,Integer>();
        List<Account> lstAct = new List<Account>();
        if(Trigger.isInsert || Trigger.isUndelete || Trigger.isUpdate){
            for( Contact ctNew : Trigger.New)
            {
                if(ctNew.AccountId != null  )
                {
                    List<Contact> lstContactNew = [Select Id,AccountId from Contact Where AccountId =: ctNew.AccountId];  
                    if(lstContactNew != null)
                    {
                        mapAcctIdAndContSize.put(ctNew.AccountId, lstContactNew.size());
                    }
                }
            }
        }
        if( Trigger.isDelete || Trigger.isUpdate)
            for( Contact ctOld : Trigger.Old)
            {
                if(ctOld.AccountId != null  )
                {
                    List<Contact> lstContactOld = [Select Id,AccountId from Contact Where AccountId =: ctOld.AccountId];  
                    if(lstContactOld != null)
                    {
                        mapAcctIdAndContSize.put(ctOld.AccountId, lstContactOld.size());
                    }
                }
            }   
            for( Id actId : mapAcctIdAndContSize.keySet())
            {
                Account act = new Account();
                act.Id = actId;
                act.Count_Contact__c = mapAcctIdAndContSize.get(actId);
                lstAct.add(act);
            }
            if(lstAct.size()>0)
            {
                update lstAct;
            }
    }
    
}
Karan_JainKaran_Jain
I think This code help you ....

Trigger 

trigger contactOntrigger on Contact (After insert  , after update , After delete  , After undelete) {
    if(Trigger.isAfter){ 
            if(Trigger.isInsert){
                contactHandler.countContact(trigger.new);
            }
            else if(trigger.isUpdate){
               contactHandler.countContact(trigger.old);
               contactHandler.countContact(trigger.new);
            }
            else if(trigger.isdelete){
             contactHandler.countContact(trigger.old);
            }
            else if(trigger.isUndelete){
             contactHandler.countContact(trigger.new );               
            }
            
        }
}
Handler Class

public class contactHandler {
    public static void countContact(List<Contact> conlist )
    {
           set<Id> sid = new Set<id>();
        for(contact c : conlist){
                    if(c.accountid!= null){
                    sid.add(c.AccountId);
                }
                }
                Map< id , Integer> mMap = new Map<id , Integer>();
           for(Account ac : [select name , (select lastName from contacts ) from account where id In:sid])
            {
                mMap.put(ac.Id , ac.contacts.size());
            }

                Set<id> s = new Set<id>(mMap.keyset());
                list<Account> ac = new List<Account>();
           for(Id ids : s){
                   ac.add(new Account(id = ids , KaranJain__countOfContact__c = mMap.get(ids)));
            }
        update ac;
     }
 this code work on any condition 
sachin tomar 11sachin tomar 11
// this code is verry easy and short.
trigger contactrigger on Contact (after insert,after delete,after update,after undelete)

     list<account> acclist=[select id,name,(select AccountId,name from contacts ) from account];        
        for(integer i=0;i<acclist.size();i++)
        {
            acclist[i].No_of_related_contact__c=acclist[i].contacts.size();
            
        } 
        update acclist;
}

       
       
   
 
vaani krvaani kr
Hi Gita09 ,
  
    your question is : display number of contacts associated with an account using triggers.

  Whenever we are inserted contact in the related account, the no of contacts to be incremented,if you deleted then decremented. Both are related objects so we are using (after trigger) here.
after trigger we have four events:  after insert,after update ,after delete, after undelete
after insert: After insertion of contact we have to update in account object with field name: total no of contacts
after update: After  contact  account namewe have to update (may be u have to change the accoun name) in account object with field name: total no of contacts
after delete: After seleteof contact we have to update in account object with field name: total no of contacts
after undelete: After undelete of contact we have to dat the contact in account object with field name: total no of contacts

first we have to create a field in account object:Total no of contact which is number field because count is number

below trigger write down:

trigger ContactTrigger on Contact (after insert,after update,after delete,after undelete) {
//Total_Contact_Counts__c  
    ContactTriggerHelper helper = new ContactTriggerHelper();
    
    set<id> accIds = new set<id>();
    if(trigger.isafter && (trigger.isinsert || trigger.isupdate || trigger.isundelete)){
        for(contact con : Trigger.new){
            if(con.accountid != null){
                accIds.add(con.accountid);
            }
        }
    }
    if(trigger.isafter && (trigger.isupdate || trigger.isdelete)){
        for(contact con : Trigger.old){
            if(con.accountid != null){
                accIds.add(con.accountid);
            }
        }
    }
    if(accIds != null){
      helper.updatetotalcount(accIds);
    }
}

public class ContactTriggerHelper {
    public void updatetotalcount(set<id> accIds)  
    {
        list<Account> lstaccs =[select id,name,Total_Contact_Counts__c,(select id, name from contacts) from Account where id in :accIds];
        for(account acc : lstaccs)
        {
            acc.Total_Contact_Counts__c = acc.contacts.size();
        }
        update lstaccs;
    }
}

it's work fine;
Tushar KhorateTushar Khorate
Have you tried this If not then try this trigger for example then you will do your requirement also...!
Prework: Make 'Count of Contacts' field with type as Number on Account Object.
trigger CountOfContactsRelatedToAccount on Contact (after insert, after delete, after Undelete) {
    Set<Id> accId = new Set<Id>();
    if(Trigger.isInsert || Trigger.isUndelete){
        for(Contact con : Trigger.new){
            accId.add(con.AccountId);
        }
    }
    if(Trigger.isDelete){
        for(Contact con : Trigger.old){
            accId.add(con.AccountId);
        }
    }
    List<Account> accList = [Select Id,Name,Count_of_Contacts__c,(Select id from contacts) from Account where Id IN : accId];
    for(Account acc :accList){
        acc.Count_of_Contacts__c = acc.contacts.size();
    }
    update accList;
}

Your Problem is similar like this.
If you found this helpful, Kindly mark it as best answer so others can see this who want help.
Thanks,
Tushar
Mahesh GowriMahesh Gowri
Hi Guys, I have checked for insert, update and delete operations. the below code is working 100 Percent.

Handler:
==========
public class ContactHandler 
{
    List<Account> accountList = new List<Account>();
    List<Account> accountListUpdated = new List<Account>();
    public void countContacts(List<Contact> newList)   {
        for (Contact con : newList)  {
            system.debug('ContactsAccountID'+con.AccountId);
            accountList = [SELECT Id,Name,Count_Of_Contacts_Associated__c, (SELECT Id, Name FROM Contacts) 
                           FROM Account WHERE Id =: con.AccountId];
        }
        for (Account acc : accountList)  {
            acc.Count_Of_Contacts_Associated__c = acc.Contacts.size() ;
            accountListUpdated.add(acc);
        }
        update accountListUpdated;
    }
}

trigger:
=============
trigger ContactTrigger on Contact (before insert, after insert, after update, after delete) {
    ContactHandler handler = new ContactHandler();
    if(Trigger.isAfter && Trigger.isInsert){
        handler.countContacts(Trigger.new); }
    
    if(Trigger.isAfter && Trigger.isUpdate)  {
        handler.countContacts(Trigger.old);
        handler.countContacts(Trigger.new);
                                             }
    
    if(Trigger.isAfter && Trigger.isDelete)    {
        handler.countContacts(Trigger.old);    }
}
Shubham Jain 338Shubham Jain 338
Hi,

trigger TriggerContact on Contact (after insert, after update, after delete, after undelete) {
    
    List<Contact> contactList = Trigger.isDelete ? Trigger.Old : Trigger.New;
    Set<Id> accountIdSet = new Set<Id>();
    for (Contact con : contactList) {
        if (Trigger.isUpdate) {
            if (con.AccountId != Trigger.oldMap.get(con.Id).AccountId) {
                if (con.AccountId != null) accountIdSet.add(con.AccountId);
                if (Trigger.oldMap.get(con.Id).AccountId != null) accountIdSet.add(Trigger.oldMap.get(con.Id).AccountId);
            }
        } else if (con.AccountId != null) {
            accountIdSet.add(con.AccountId);
        }
    }
    if (accountIdSet.size() > 0) {
        List<Account> accountList = [SELECT Id, Contact_Count__c, (SELECT Id FROM Contacts) FROM Account WHERE Id IN :accountIdSet];
        if (accountList.size() > 0) {
            for (Account acc : accountList) {
                acc.Contact_Count__c = acc.Contacts.size();
            }
            update accountList;
        }
    }
}
Shivam Singh 96Shivam Singh 96
Hi,

**********     Trigger to count the number of contacts associated with an account.​​​​​​    **********

trigger ConTrigger on Contact (after insert, after update, after undelete , after delete ) {
    
    List<Contact> conlist = new List<Contact>();
    
    if( Trigger.isInsert || Trigger.isUndelete ) 
    {
        conlist.addAll(Trigger.new);
    }
     if( Trigger.IsDelete) 
    {
       conlist.addAll(Trigger.old);
    }
      if( Trigger.IsUpdate) 
    {
       conlist.addAll(Trigger.new);
       conlist.addAll(Trigger.old);
    }
    
    Set<id> accId = new  Set<id>();
    
    for(Contact con : conlist) 
    {
        accId.add(con.accountId);
    }
    
    List<Account> accList = [Select Name,Number_Of_Contact__c, (select Name from Contacts) from Account WHERE Id IN :accId];
    
    for(Account acc : accList) 
    {
        acc.Number_Of_Contact__c = acc.contacts.size();
    }
    
    update accList;
}

If you found this helpful, Kindly mark it as the best answer so others can see this who want help.
Thanks,
Shivam Singh
Ganesh Nazirkar 5Ganesh Nazirkar 5
/*
Here is the complete code we can reduce the trigger by using class as well but i have give comple one shot code its working fine for me.
*****************write a trigger total number of contact on account ******************
//before to start create one custom field on account object - Number_of_Contacts__c

*/
trigger NoContactTrigger on Contact (after update, after insert, after delete, after Undelete) {    
    
    if(trigger.isInsert && trigger.isAfter){
        Set<id> AccIds = new Set<Id>();
        for(Contact con : trigger.new){
            if(con.accountID != null) {
                AccIds.add(con.accountid);
            }
        }
        List<Account> accList = [SELECT Id,(SELECT id FROM contacts) FROM Account WHERE ID IN : AccIds];
        for(Account acc :accList){
            acc.Number_of_Contacts__c = acc.contacts.size();
        }
        update accList;
    }
    if(trigger.isUpdate && trigger.isAfter){
        Set<id> AccIds = new Set<Id>();
        for(Contact con : trigger.new){
            if(con.accountID != null) {
                AccIds.add(con.accountid);
            }
        }
        List<Account> accList = [SELECT Id,(SELECT id FROM contacts) FROM Account WHERE ID IN : AccIds];
        for(Account acc :accList){
            acc.Number_of_Contacts__c = acc.contacts.size();
        }
        update accList;
    }
    if(trigger.isDelete && trigger.isAfter){
        Set<id> AccIds = new Set<Id>();
        for(Contact con : trigger.old){
            if(con.accountID != null) {
                AccIds.add(con.accountid);
            }
        }
        List<Account> accList = [SELECT Id,(SELECT id FROM contacts) FROM Account WHERE ID IN : AccIds];
        for(Account acc :accList){
            acc.Number_of_Contacts__c = acc.contacts.size();
        }
        update accList;
    }
    if(trigger.isUndelete && trigger.isAfter){
        Set<id> AccIds = new Set<Id>();
        for(Contact con : trigger.old){
            if(con.accountID != null) {
                AccIds.add(con.accountid);
            }
        }
        List<Account> accList = [SELECT Id,(SELECT id FROM contacts) FROM Account WHERE ID IN : AccIds];
        for(Account acc :accList){
            acc.Number_of_Contacts__c = acc.contacts.size();
        }
        update accList;
    }
}


 
Siva Kumar MamillapalliSiva Kumar Mamillapalli
Handler Class Method::

public static void ConCountInAccount1(List<Contact> ConList, Map<Id,Contact> OldConMap)

  {
      Set<id> AccIds = New Set<id>();
      for(Contact IUDU:ConList)//IUDU-Insert/UnDelete/Delete/Update
      {
        if(String.isNotBlank(IUDU.AccountId) && OldConMap==Null)
        {  //OldMap=Null Means Here Insert or Undelete or Delete Operation Occuring.
            AccIds.add(IUDU.accountId);
           //Here Adding Inserted/Undeleted/Deleted(That Parameter Passing OldList Too In the Trigger Code) Con.AccountIds
           //Work Around: Contact Inserting/Restoring/Removing 
        }
       else if(String.isNotBlank(IUDU.AccountId) && IUDU.AccountId!=OldConMap.get(IUDU.id).accountId)
        {
            AccIds.add(IUDU.AccountId);
            //Here adding Updated Con.accountIds(which is Not Blank)
            //Work Around: Opened Old Record and Changing AccountName with New Account or another Account in the DataBase 
            //             Or Reparenting Account Lookup Field 
            //So In Above Cases We need to add Both New And Old AccountIds
            AccIds.add(OldConMap.get(IUDU.id).accountId);            
        }
        else if(String.isBlank(IUDU.AccountId) && String.isNotBlank(OldConMap.get(IUDU.id).accountId))
        {
            AccIds.add(OldConMap.get(IUDU.id).accountId);
            //Here Also Adding Updataed Con.AccountIds (New Value is Null and Old Value is Not Empty)
            //Work Around: Opened Old Record and Changing AccountName with Empty/Null value /Removing AccoutName
            //             Then Adding Old AccountId of this Updating Contact(Decreased Con Count in that AccountID)
        }
      }

      List<Account> AccList =[Select Id,No_of_Contacts__c,(Select id from Contacts) from Account WHERE Id IN :AccIds];
      List<Account> UpdatedAccList = New List<Account>();
      for(Account EA: AccList)
      {
          EA.No_of_Contacts__c=EA.Contacts.Size();
          UpdatedAccList.add(EA);
      }
      Update UpdatedAccList;
      
  }


Trigger::
if( Trigger.isAfter && (trigger.isInsert || trigger.isUndelete||trigger.isDelete))
    {
        ContactTriggerHandler.ConCountInAccount1(trigger.IsDelete ? trigger.old:trigger.new,null);
    }
    if( Trigger.isAfter && trigger.IsUpdate)
    {
        ContactTriggerHandler.ConCountInAccount1(trigger.new,trigger.oldMap);
    }
Siva Kumar MamillapalliSiva Kumar Mamillapalli
trigger ContactTrigger on Contact (after insert,after update,after delete,after undelete) 
{
    if(trigger.isafter&&(trigger.isInsert||trigger.IsUnDelete))
    {
       ContactTriggerHandler.conCountInAccount(trigger.new,null);
    }
    if(Trigger.IsAfter&&(Trigger.IsUpdate||Trigger.IsDelete))
    {
       ContactTriggerHandler.conCountInAccount(Trigger.IsUpdate?Trigger.New:Trigger.Old,Trigger.OldMap);
    }
}





public class ContactTriggerHandler 
{//*Trigger to Show Up all Contacts associted with account
 public static void conCountInAccount(List<Contact> conList,Map<Id,Contact> conOldMap)
 {
     Set<Id> allAccIds = New Set<Id>();
     for(Contact EC:conList)
     {
         if(String.isNotBlank(EC.AccountId) && conOldMap==Null)//Insert || Undelete
         {
             allAccIds.add(EC.AccountId);//Here EC.AccountId from TRIGGER.NEW(Check Trigger)
             System.debug('After Insert or Undelete ::New AccountIds Added Into allAccIds');
         }
         else
         {
            if(EC.AccountId!=conOldMap.get(EC.Id).AccountId)//Update
            {
                  if(String.isNotBlank(EC.AccountId))//We Need to check here wheather the newly added accountId is null or Not
                  {
                    allAccIds.add(EC.AccountId);//Here EC.AccountId from TRIGGER.NEW(Check Trigger)
                    System.debug(String.isBlank(conOldMap.get(EC.Id).AccountId)?'After Update::Old AccountIds Null and New AccountIds Added Into allAccIds':'After Update::New AccountIds Added Into allAccIds'); 
                  }
                
                if(String.isNotBlank(conOldMap.get(EC.Id).AccountId))//We Need to check here wheather old accountId is null or Not
                  {
                    allAccIds.add(conOldMap.get(EC.Id).AccountId);
                    System.debug(String.isBlank(EC.AccountId)?'After Update::New AccountIds Null and Old AccountIds Added Into allAccIds':'After Update Old AccountIds also Added Into allAccIds');
                  } 
            }
            else//Delete
            {
               if(String.isNotBlank(EC.AccountId))//Here EC.AccountId from TRIGGER.OLD(Check Trigger)
               {
                  allAccIds.add(EC.AccountId);
                  System.debug('After Delete::Deletable AccountIds Added Into allAccIds');
               }
            }
         }
     }
     List<Account> UpdateAccList =[SELECT Id,Contacts__c,(SELECT Id from Contacts)FROM Account WHERE Id=:allAccIds];
     for(Account EA:UpdateAccList)
     {
       EA.Contacts__c=EA.Contacts.size();
     }
     update UpdateAccList;
     
     
 }
}
Ajeet Chaubey 5Ajeet Chaubey 5
Here is the detailed video on it: https://www.youtube.com/watch?v=t8-2ymkTbOM
Shreya TiwariiShreya Tiwarii
According to me there can be three cases when we update a contact :
  1.  previously accountId was null but then some value is updated
  2.  previously accountId had some value but then it is updated to null
  3. the accountId is changed i.e periviously some othet value and now other
keeping this in mind I wrote this code :
trigger ContactTrigger on Contact (after insert, after update , after delete){
     ContactTriggerHandler.countAllContactOfAccount(trigger.new,trigger.old,trigger.oldMap);
}
and in ContactTriggerHandler these two methods
public static void countAllContactOfAccount(List newContacts,List oldContacts,MapoldMap){
    if(trigger.isAfter){
        List accounts = new List();
        if(trigger.isInsert){
            Set accIds = new Set();
            for(Contact con: newContacts){
                 if(con.AccountId != null)
                 accIds.add(con.AccountId);
             }
             accounts = updateAccounts(accIds);
        }
       if(trigger.isUpdate){
            Set accIds = new Set();
            for(Contact con: newContacts){
                if(oldMap.get(con.Id).AccountId != con.AccountId){
                     if(con.AccountId == null){
                          accIds.add(oldMap.get(con.Id).AccountId);
                     }else if(con.AccountId != null && oldMap.get(con.Id).AccountId == null){
                          accIds.add(con.AccountId);
                     }else {
                          accIds.add(oldMap.get(con.Id).AccountId);
                          accIds.add(con.AccountId);
                     }
                 }
                 accounts = updateAccounts(accIds);
            }
       }
       if(trigger.isDelete){
             Set accIds = new Set();
             for(Contact con: oldContacts){
                 if(con.AccountId != null)
                 accIds.add(con.AccountId);
             }
             accounts = updateAccounts(accIds);
        }

       update accounts;
      }
}

private static List updateAccounts(Set accIds){
     List accounts = [Select id, (Select id from Contacts) from Account where id in : accIds];
     for(Account acc: accounts){
          acc.Total_Contacts_Count__c = acc.Contacts.size();
     }
     return accounts;
}

 
Bhanu Prakash SBhanu Prakash S
You can try this way too, which will make the count as ZERO, if no contacts linked to the account

trigger contactCnt on Contact (after insert, after delete, after update, after undelete) {
    if(trigger.isAfter){
        Set<Id> accIds = new Set<Id>();
        List<Account> accList = New List<Account>();
        for(Contact c: Trigger.new){
            if(c.AccountId!=null)    
                accIds.add(c.AccountId);    
        }
        if(!Trigger.isInsert)
        for(Contact c: Trigger.old){
             if(c.AccountId!=null)
                accIds.add(c.AccountId);    
        }
        List<Account> rslt = [Select Id,(Select id from contacts) from Account where Id=:accIds];
        For(Account a: rslt){
            List<Contact> cs = a.Contacts;
            a.Number_of_contacts__c=cs.size();
            accList.add(a);
        }
       if(accList.size()>0)
            update accList;
    }
}