+ Start a Discussion
Denyel's DevDenyel's Dev 

Apex Trigger to Count Related Records

Lowly Admin here who doesn't know a bit of code...I have a custom object Location__c and I need to count the number of Products (Standard object called Product2) associated with that Location. I want the total to appear in a field on the Location object called Current_Lot_Inventory. Would any of you gracious developers be willing to help me out with the Apex needed?
Best Answer chosen by Denyel's Dev
RKSalesforceRKSalesforce
Hello Denyel's,

Please use below updated code:
Trigger Product2RecordCount on Product2(After Insert, After Update, After Delete, After UnDelete){
    
    List<ID> locationIds = New List<ID>();
    
    If(Trigger.IsInsert || Trigger.IsUpdate || Trigger.IsUnDelete){
        For(Product2 c: Trigger.New){
            if(c.Location__c  != null){
                locationIds.add(c.Location__c);
            }  
        }
    }
    If(Trigger.IsDelete){
        For(Product2 c: Trigger.Old){
            locationIds.add(c.Location__c);
        }
    }
     
    List<Location__c> LocationListToUPdate = New List<Location__c>();
     
    For(Location__c lct: [Select Current_Lot_Inventory__c, (Select ID FROM Products__r) FROM Location__c WHERE ID = :locationIds]){
		lct.Current_Lot_Inventory__c= lct.Products__r.size();
		LocationListToUPdate.add(lct);
    }
     
     
    try{
        Update LocationListToUPdate;
    }
     Catch(Exception E){
        System.Debug('Error Message: ' + e.getMessage());
    }
}

This code is working for me. 

Regards,
Ramakant 
 

All Answers

ManidManid
Dev I think without code also you can perform. Create a master-detail relation between two objects and by using rollup summary you can get the count of number of childs . try this
Aparna Hegde 1Aparna Hegde 1
Hi Denyel,

Assuming the Location__c and Product 2 are related to each other through a lookup, you can tweak the below code to suit your requirement

trigger Test on Product2 (after insert, after update) {
Set<Id> LocId = new Set<Id>();
integer no_of_products;
Location__c Loc = new Location__c();
for(Product2 P:trigger.new){
no_of_products = [Select count() from Product2 where LocationId :=P.LocationId];
Loc = [select Id from Location__c where Id:=LocationId];
Loc.Current_Lot_Inventory=no_of_products;
}
update Loc;
}

Hope this helps! Good Luck!

Cheers,
Aparna Hegde
RKSalesforceRKSalesforce
Hi Denyels,

Assuming that there is lookup relationship between Location__c and Product2 and on Product2 there is Lookup Field with API Name Location_c.
Please use below code to achieve this :
Trigger Product2RecordCount on Product2(After Insert, After Update, After Delete, After UnDelete){
    
    List<ID> locationIds = New List<ID>();
    
    If(Trigger.IsInsert || Trigger.IsUpdate || Trigger.IsUnDelete){
        For(Product2 c: Trigger.New){
            if(c.Location__c  != null){
                locationIds.add(c.Location__c.Id);
            }  
        }
    }
    If(Trigger.IsDelete){
        For(Product2 c: Trigger.Old){
            locationIds.add(c.Location__c.Id);
        }
    }
     
    List<Location__c> LocationListToUPdate = New List<Location__c>();
     
    For(Location__c lct: [Select Current_Lot_Inventory__c, (Select ID FROM Products) FROM Location__c WHERE ID = :locationIds]){
		lct.Current_Lot_Inventory__c= lct.Products.size();
		LocationListToUPdate.add(lct);
    }
     
     
    try{
        Update LocationListToUPdate;
    }
     Catch(Exception E){
        System.Debug('Error Message: ' + e.getMessage());
    }
}

Hope this will work. Please let me know if helped by marking best answer.

Regards,
Ramakant  
Denyel's DevDenyel's Dev
Hello Ramakant,
I tried to add this as a Trigger on the Location object but I got the following:
Error: Compile Error: A non foreign key field cannot be referenced in a path expression: Location__c at line 8 column 35
RKSalesforceRKSalesforce
Hello Denyel's,

Please use below updated code:
Trigger Product2RecordCount on Product2(After Insert, After Update, After Delete, After UnDelete){
    
    List<ID> locationIds = New List<ID>();
    
    If(Trigger.IsInsert || Trigger.IsUpdate || Trigger.IsUnDelete){
        For(Product2 c: Trigger.New){
            if(c.Location__c  != null){
                locationIds.add(c.Location__c);
            }  
        }
    }
    If(Trigger.IsDelete){
        For(Product2 c: Trigger.Old){
            locationIds.add(c.Location__c);
        }
    }
     
    List<Location__c> LocationListToUPdate = New List<Location__c>();
     
    For(Location__c lct: [Select Current_Lot_Inventory__c, (Select ID FROM Products__r) FROM Location__c WHERE ID = :locationIds]){
		lct.Current_Lot_Inventory__c= lct.Products__r.size();
		LocationListToUPdate.add(lct);
    }
     
     
    try{
        Update LocationListToUPdate;
    }
     Catch(Exception E){
        System.Debug('Error Message: ' + e.getMessage());
    }
}

This code is working for me. 

Regards,
Ramakant 
 
This was selected as the best answer
Denyel's DevDenyel's Dev
I don't get any errors if I add this Trigger to the Product2 object but don't I need the trigger to appear on the Location__c object? I want to count the Products related to a Location. 
RKSalesforceRKSalesforce
You Don't need to add this trigger on your Parent Object(In this  case Location__c) Because you need to get the count of Products.
Your Trigger should be fired on DML operation on Products because you need a count of products so we need to write a trigger on your Product.

Regards,
Ramakant
Denyel's DevDenyel's Dev
It works, you rock!!!
Madhusudan reddy 13Madhusudan reddy 13
Hi Ramakant, what will happen if i update child recode with removing parent record?
It will not update the count on parent