You need to write trigger on child object. I'm giving you trigger where Parent is Account and Child is contact. Here i have a Picklist field "type" on contact with values "Admin", "Broker" and "Principal". And i have 3 fields(Amin_Con_Count__c,Broker_Con_Count__c and Princiapl_Con_Count__c) on Account with number data type to count each type of contact for an account. An account can have contact with any of the type. So here is the trigger for this case:
trigger ContactTypeCountOnAccount on Contact (after insert, after delete,after undelete,after update)
{
Set<Id> AccID = new Set<Id>();
list<contact> ConAdminList =new list<Contact>();
list<contact> ConBrokerList =new list<Contact>();
list<contact> ConPrincipalList =new list<Contact>();
if(Trigger.isInsert || Trigger.isUndelete)
{
for(Contact con : Trigger.New)
{
AccID.add(con.AccountId);
}
List<Account> acc_list = [select id,Amin_Con_Count__c,Broker_Con_Count__c,Principal_Con_Count__c,(select Type__c from Contacts) from Account where Id in:AccID];
List<Contact> con_list = [select id,Type__c from contact where AccountId in :AccID];
for (contact con: con_list)
{
if(con.Type__c=='Admin')
{
ConAdminList.add(con);
}
if(con.Type__c=='Broker')
{
ConBrokerList.add(con);
}
if(con.Type__c=='Principal')
{
ConPrincipalList.add(con);
}
}
update ConAdminList;
update ConBrokerList;
update ConPrincipalList;
for(Account a : acc_list)
{
a.Amin_Con_Count__c=ConAdminList.size();
a.Broker_Con_Count__c=ConBrokerList.size();
a.Principal_Con_Count__c=ConPrincipalList.size();
}
try
{
update acc_list;
}
catch(DMLException e)
{
for (Contact con : trigger.new)
{
con.addError(e.getDmlMessage(0));
}
}
}
if(Trigger.isDelete)
{
for(Contact con : Trigger.old)
{
AccID.add(con.AccountId);
}
List<Account> acc_list = [select id,Amin_Con_Count__c,Broker_Con_Count__c,Principal_Con_Count__c,(select Type__c from Contacts) from Account where Id in:AccID];
List<Contact> con_list = [select id,Type__c from contact where AccountId in :AccID];
for (contact con: con_list)
{
if(con.Type__c=='Admin')
{
ConAdminList.add(con);
}
if(con.Type__c=='Broker')
{
ConBrokerList.add(con);
}
if(con.Type__c=='Principal')
{
ConPrincipalList.add(con);
}
}
update ConAdminList;
update ConBrokerList;
update ConPrincipalList;
for(Account a : acc_list)
{
a.Amin_Con_Count__c=ConAdminList.size();
a.Broker_Con_Count__c=ConBrokerList.size();
a.Principal_Con_Count__c=ConPrincipalList.size();
}
try
{
update acc_list;
}
catch(DMLException e)
{
for (Contact con : trigger.new)
{
con.addError(e.getDmlMessage(0));
}
}
}
if(Trigger.isUpdate)
{
Set<Id> OldAId_set = new Set<Id>();
for(Contact con : Trigger.new)
{
//For new contacts
if(con.AccountId != Trigger.oldMap.get(con.id).AccountId)
{
AccID.add(con.AccountId);
}
//For old contacts with updated type
if(con.AccountId == Trigger.oldMap.get(con.id).AccountId && con.type__c !=Trigger.oldMap.get(con.id).type__c)
{
AccID.add(con.AccountId);
}
OldAId_set.add(Trigger.oldMap.get(con.id).AccountId);
}
if(!AccID.isEmpty())
{
//for new Accounts
List<Account> acc_list = [select id,Amin_Con_Count__c,Broker_Con_Count__c,Principal_Con_Count__c, (select Type__c from Contacts) from Account where Id in:AccID];
//For New Account Contacts
List<Contact> con_list = [select id,Type__c from contact where AccountId in :AccID];
for (contact con: con_list)
{
if(con.Type__c=='Admin')
{
ConAdminList.add(con);
}
if(con.Type__c=='Broker')
{
ConBrokerList.add(con);
}
if(con.Type__c=='Principal')
{
ConPrincipalList.add(con);
}
}
update ConAdminList;
update ConBrokerList;
update ConPrincipalList;
/* This is For Old Contacts Count */
//for Old Accounts
List<Account> Oldacc = [select id,Amin_Con_Count__c,Broker_Con_Count__c,Principal_Con_Count__c, (select Type__c from Contacts) from Account where Id in:OldAId_set];
//For Old Account Contacts
List<Contact> OldConAdmin = [select id,Type__c from contact where AccountId in :OldAId_set and Type__c='Admin'];
List<Contact> OldConBroker = [select id,Type__c from contact where AccountId in :OldAId_set and Type__c='Broker'];
List<Contact> OldConPrincipal = [select id,Type__c from contact where AccountId in :OldAId_set and Type__c='Principal'];
//For New Accounts
for(Account a : acc_list)
{
a.Amin_Con_Count__c=ConAdminList.size();
a.Broker_Con_Count__c=ConBrokerList.size();
a.Principal_Con_Count__c=ConPrincipalList.size();
}
try
{
update acc_list;
}
catch(DMLException e)
{
for (Contact con : trigger.new)
{
con.addError(e.getDmlMessage(0));
}
}
//For Old Accounts
for(Account a : Oldacc)
{
a.Amin_Con_Count__c=OldConAdmin.size();
a.Broker_Con_Count__c=OldConBroker.size();
a.Principal_Con_Count__c=OldConPrincipal.size();
}
try
{
update Oldacc;
}
catch(DMLException e)
{
for (Contact con : trigger.new)
{
con.addError(e.getDmlMessage(0));
}
}
}
}
}
Please mark it as best answer, if it resolves your issue.
Thank You very much Praveen.
Iam very happy for your valuable reply. But iam asking only simple logic that increment parent field count__c when we insert child record incase lookup relation .please send small program for the above issue only
Regards
Sangeetha
Thank you very much Abhishek,
I need simple logic that only when we insert a record on child parent count field will be increased that it.
Please help me for that
Hi Abhishek,
Thank you for your valuable reply. Iam Very Happy for this reply.If Possible time you have please send this code without map or less lines than this code.(Doubt: without map we can do this?, i dont know that's why iam asking)
Finally very very thanks for giving a valuable reply for me. Thank u so much
Let i know if any doubt in future can i directly ask to you by this mail.Please answer me. thanks in advance
Regards
Sangeetha
Sangetha, we cannot acheive this requirement without using a map. This is the minimum number of lines in order to achieve your requirement. Yes, you can reach me on my mail in case of any urgency.
Please mark this answer as SOLVED if all your dobts are clear in order to avoid confusion to others.
Hello Abhishek, Thanks for this trigger - it's fantastic! I'm looking for a way to modify it to selectively increment/decrement the count based on a field (checkbox) on the child object. Any suggestions?
Yes, it is possible. Can you please open a new question related to this and send the link here. Please mention all the requirement details in your question.
Hi Abhishek, Thanks for the response. I figured it out by adding && checkbox == true to the if statement, but I really appreciate your willingness to help.
Please find the below code which will run only on insert :
Regards,
Abhishek.
All Answers
Please mark it as best answer, if it resolves your issue.
Regards,
Praveen Venkata.
Please find below the code to update count on Parent Object if child is inserted,update,deleted or undeleted :
Please make sure to replace following variables :
- Account : Your Parent Object
- Contact : Your Child Object
- Count__c : Field on Account where you want the no. of child records.
- AccountId : API name of Parent Lookup field on Child object
Please let me know if you any help on this.Regards,
Abhishek.
Please find the below code which will run only on insert :
Regards,
Abhishek.
This is the minimum number of lines in order to achieve your requirement.
Yes, you can reach me on my mail in case of any urgency.
Please mark this answer as SOLVED if all your dobts are clear in order to avoid confusion to others.
Regards,
Abhishek.
Please remove the "}" character that is used at line no. 20.
Thanks,
Abhishek Bansal
Thanks for this trigger - it's fantastic! I'm looking for a way to modify it to selectively increment/decrement the count based on a field (checkbox) on the child object. Any suggestions?
Yes, it is possible. Can you please open a new question related to this and send the link here. Please mention all the requirement details in your question.
Thanks,
Abhishek Bansal.
Thanks for the response. I figured it out by adding && checkbox == true to the if statement, but I really appreciate your willingness to help.