You need to sign in to do that
Don't have an account?
sourav046
Trigger for Roll up summary
I know this is weird I can achieve this using Roll up summary .But what I want is to achieve this using trigger.
I want to write a trigger on Account ,which is having a field named Count__c .I want to autopopulate the nos of Contacts associated with that Account .
My code is not working thats why seeking help .
Hi Sourav,
You cannot create roll-up summary field on Account.
When ever you want to count the number of contacts, You should write a trigger on Contact not on Account.
Below is the code :
trigger CountOfChild on Contact (after insert, after update, after delete, after undelete)
{
List<Contact> VLstContact;
set<String> vAccId = new set<String>();
if(trigger.isInsert || trigger.isUndelete || trigger.isdelete)
{
if(!trigger.isdelete)
{
VLstContact = trigger.new;
}
else
{
VLstContact = trigger.old;
}
for(Contact vContact : VLstContact)
{
if(vContact.AccountId != null)
{
vAccId.add(vContact.AccountId);
}
}
}
else
{
if(trigger.isUpdate)
{
for(Contact vNewContact : VLstContact)
{
Contact oldContact = trigger.oldMap.get(vNewContact.Id);
if(vNewContact.AccountId != oldContact.AccountId)
{
if(vNewContact.AccountId != null)
{
vAccId.add(vNewContact.AccountId);
}
if(oldContact.AccountId != null)
{
vAccId.add(oldContact.AccountId);
}
}
}
}
}
List<AggregateResult> vLstAggr = [SELECT count(Id) NoOfContacts,AccountId
FROM Contact
WHERE AccountId In :vAccId
GROUP BY AccountId];
Account vAcccount;
list<Account> vLstAccounts = new list<Account>();
for(AggregateResult vAggr : vLstAggr)
{
System.debug('Account Id'+vAggr.get('AccountId'));
System.debug('AggregateResult valuesare'+vAggr.get('NoOfContacts'));
string accId = (string) vAggr.get('AccountId');
decimal countOfChild = (decimal) vAggr.get('NoOfContacts');
vAcccount = new Account(Id = accId , Count_Of_Contact__c = countOfChild);
vLstAccounts.add(vAcccount);
}
update vLstAccounts;
}
I have modified the code, now it works for delete and undelete also.
Rather than writing your own, you might want to take a look at Anthony Victorio's generic solution:
http://www.anthonyvictorio.com/salesforce/roll-up-summary-utility/
I've used this a few times and its a great solution. Adding another roll up summary is a new trigger with very few lines of code.
Hi Bob,
I have used that, Only problem with that solution is if we change the parentId on child, it does not calculate the roll-up on old parent.
I mean to say A1 is the account and intitally C1 is the contact for A1.If the change the parent of C1 to A2, then roll-up is not calculated in A1 but it is calculated on A2.
Thanks for the generic solution.
Where is the code which works for delete and undelete?
Hi, Laxman Rao edited their inital response to cover deletes and undeletes. Just look at the second entry in this thread, above, timestamped:
- editedCan u please post that modified code.
Thanks
Lakshman
trigger CountOfChild on Contact (after delete, after insert, after undelete, after update) {
List<Contact> VLstContact;
set<String> vAccId = new set<String>();
if(trigger.isInsert || trigger.isUndelete || trigger.isdelete)
{
// Check if this is trigger is fired by inser/undelete/update
if(!trigger.isdelete)
{
VLstContact = trigger.new;
}
// If this is fired by delete then get the trigger.old.
else
{
VLstContact = trigger.old;
}
for(Contact vContact : VLstContact)
{
if(vContact.AccountId != null)
{
vAccId.add(vContact.AccountId);
}
}
// This is the case when the contact is updated with some info.
// There may be the case when already created contact is added to the
// Account
} else {
if(trigger.isUpdate)
{
VLstContact = trigger.new;
for(Contact vNewContact : VLstContact){
Contact oldContact = trigger.oldMap.get(vNewContact.Id);
if(vNewContact.AccountId != oldContact.AccountId){
if(vNewContact.AccountId != null) {
vAccId.add(vNewContact.AccountId);
}
}
if(oldContact.AccountId != null){
vAccId.add(oldContact.AccountId);
}
}
}
}
List<AggregateResult> vLstAggr = [SELECT count(Id) NoOfContacts,AccountId FROM Contact
WHERE AccountId In :vAccId GROUP BY AccountId];
Account vAcccount;
list<Account> vLstAccounts = new list<Account>();
for(AggregateResult vAggr : vLstAggr) {
System.debug('Account Id'+vAggr.get('AccountId'));
System.debug('AggregateResult valuesare'+vAggr.get('NoOfContacts'));
string accId = (string) vAggr.get('AccountId');
decimal countOfChild = (decimal) vAggr.get('NoOfContacts');
vAcccount = new Account(Id = accId , Count_Of_Contact__c = countOfChild);
vLstAccounts.add(vAcccount);
}
update vLstAccounts;
}
My child Object is "Assigned_Contractor__c", while the Lookup Parent Object is the standard "Contact" Object.
Error: Variable does not exist: ContactId at line 22 column 29
--------------------------------------------------------------------------------------------------------
trigger AssignedContractorTrigger on Assigned_Contractor__c (after insert, after update, after delete, after undelete) {
List <Assigned_Contractor__c> VLstAssignedContractor;
set <String> vContId = new set <string>();
if (trigger.isInsert || trigger.isUndelete || trigger.isDelete)
{
// Check if this trigger is fired by insert/undellete/update
if(!trigger.isdelete)
{
VLstAssignedContractor = trigger.new;
}
//IF this is fired by delete then get the trigger.old.
else
{
VLstAssignedContractor = trigger.old;
}
for(Assigned_Contractor__c vAssignedContractor : VLstAssignedContractor)
{
if(vAssignedContractor.ContactId != null)
{
vContId.add(vAssignedContractor.ContactId);
}
}
//This is the case when the Assigned Contractor is updatred with some info.
//There may be the case when already created Assigned Contractor is added to the Contact
} else {
if(trigger.isUpdate)
{
vLstAssignedContractor = trigger.new;
for(Assigned_Contractor vNewAssignedContractor : VLstAssignedContractor){
Assigned_Contractor__c oldAssignedContractor = trigger.oldMap.get(vNewAssignedContractor.Id);
if(vNewAssignedContractor.ContactId != oldAssignedContractor.ContactId){
if(vNewAssignedContractor.ContactId != null) {
vContId.add(vNewAssignedContractor.ContactId);
}
}
if(oldAssignedContractor.ContactId != null){
vContId.add(oldAssignedContractor.ContactId);
}
}
}
}
List <AggregateResult> vLstAggr = [SELECT count(id) z, ContactId FROM Assigned_Contractors__c
WHERE ContactId IN : vContId GROUP BY ContactId];
Contact vContact;
list <Contact> vLstContacts = new list <Contact>();
for (AggregateResult vAggr : VLstAggr) {
System.Debug('Contact id'+vAggr.get('ContactId'));
System.Debug('AggregateResult values are ' +vAggr.get('z'));
string conId = (string) vAggr.get('ContactId');
decimal countofChild = (decimal) vAggr.get('z');
vContact = new Contact(id = conId, FY_Total_Assigned_Contractors_YTD__c = countofChild);
vLstContacts.add(vContact);
}
update vLstContacts;
}
Set<Id> AccIds=new Set<Id>();
List<Account> AccListtoUpdate=new List<Account>();
if(Trigger.isInsert||Trigger.isUndelete){
for(Contact con:Trigger.new)
{
AccIds.add(con.AccountId);
}
}
if(Trigger.isUpdate||Trigger.isdelete)
{
for(Contact con:Trigger.old)
{
AccIds.add(con.AccountId);
}
}
for(Account acc:[Select Id ,Total_Contacts__c,(Select Id from Contacts) from Account where Id IN: AccIds])
{
acc.Total_Contacts__c=acc.Contacts.size();
AccListtoUpdate.add(acc);
}
try{
update AccListtoUpdate;
}
catch(Exception e){
System.debug('Exception e'+e.getMessage());
}
}