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
Evan ZhangEvan Zhang 

Account Trigger: Number of Contacts under Account

Hi! 
I've created a trigger under contacts to populate a custom field on the Account object that says how many contacts are under that one account. It's been uploaded through sandbox, but it doesn't seem to be working. Here's the code I'm using: 

Trigger NumberContacts on Contact(after update,after insert){
    Set<ID> accids=New Set<ID>();
    For(contact c:trigger.new){
        Accids.add(c.AccountId);
    }

    Map<ID,Account> Acc= new Map<ID,Account>([Select ID, No_of_Contacts_SFDC__c from account where id IN:accids ]);
    Map<ID,Account> updateMap = new Map<ID,Account>();
    for(Account ac :Acc.values())
    {
        Integer count = 0;
        for(Contact c:Trigger.New){
            if(ac.Id == c.AccountId)
                count = count + 1;
            
        }
        ac.No_of_Contacts_SFDC__c= count;
        updateMap.put(ac.Id,ac);
    }

    if(!updateMap.isEmpty())
        update updateMap.values();
}

Is there something wrong with the code? The field updates to 1 the first time I add a contact, and then nothing updates after that. Not sure what's going on. Thanks! 
JustAGirlyGeekJustAGirlyGeek
I am not sure about the code itself, but have you seen the Declarative Rollup Summary Tool that will do this rollup for you?

https://andyinthecloud.com/2016/06/19/declarative-rollup-tool-summer-release/
JeffreyStevensJeffreyStevens
Ya - I think it's because your trigger is on the Contact object - and you're only looping through the Contact records that fired the trigger - therefore you're not geting a "full count".

Usually when I do this - I use a process like this...

(trigger - still on after insert, after update on the contact object).

// Collect Account IDs from contacts that fired the trigger.

// Get list of ALL contacts for each account
//      (two ways to do this - 1) Get list<Contact>, or 
//                                         2) Get List of Accounts, with a sub-query of contacts

// Loop through the list of ALL contacts and update the account record
 
Evan ZhangEvan Zhang
Hi @JeffreyStevens,

Thank you so much! Sorry I'm new to triggers, so I'm having a little trouble following. Do you mind typing that out? 

Thanks again! 
SalesFORCE_enFORCErSalesFORCE_enFORCEr
Your logic does not seem to be right. Try this
trigger ContactCount on Contact (after insert, after update) {
    Set<Id> setAccountIds = new Set<Id>();
    List<Account> accountsToUpdate = new List<Account>();
    Map<Id,List<Contact>> mapAccountContact = new Map<Id,List<Contact>>();
    for(Contact con: trigger.new){
        setAccountIds.add(con.AccountId);
    }
    List<Account> accounts = [Select Id, of_Contacts__c, (Select Id,Name from Contacts) from Account where Id IN: setAccountIds];
    for(Account acc: accounts){
        List<Contact> contacts = acc.getSObjects('Contacts');
        mapAccountContact.put(acc.Id,contacts);
    }
    for(Account a: accounts){
        a.of_Contacts__c = mapAccountContact.get(a.Id).size();
        accountsToUpdate.add(a);
    }
    if(!accountsToUpdate.isEmpty())
        update accountsToUpdate;
}
Evan ZhangEvan Zhang
Thank you so much! That did the trick. Will this update if I delete a contact as well?
SalesFORCE_enFORCErSalesFORCE_enFORCEr
It will but you need to add the before delete event and update the logic to work on trigger.old for delete event
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.