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
Michael BobeeMichael Bobee 

Apex Trigger to Get Account ID

I have a custom object(ShipTo__c) that has a field (customer_code__c) that holds a value that is common to the account object. When I insert the Ship To record, I would like to use an Apex trigger to get the account id based on the (SELECT id from Account WHERE customer_code__c = XXXX) then populate that value on the custom object to link it to the account object. Am I over-thinking this and should I be joining the tables differently other than trying to SFDC ID's?

trigger SetAccountField on ShipTo__c (before insert, before update) {
    for (ShipTo__c shipto : Trigger.new) {
        String accid = shipto.Customer_Code__c;
        List<Account> account = [SELECT Id FROM Account WHERE Customer_Code__c = :accid];
        shipto.Account__c = account.get(0).Id;
    }
}
Best Answer chosen by Michael Bobee
logontokartiklogontokartik
Actually its not complicated. Its the way the trigger must be writtern in order to manage the bulk design pattern. If you put a SOQL inside a for loop, there is a very high chance of you hitting a SOQL Governor limit. 

All I am doing is 

1. Creating a Customer code set
2. Querying the Account table to get all accounts in one shot (this is only one SOQL statement)
3. Loading them into the Map collection.
4. Again going and verifying the each shipTo record to get the correct Account.


Please review the following link

http://www.sfdc99.com/beginner-tutorials/

if you want to use your code, you can do (i modified it a little). it will work fine for one or 2 records, but if someone updates or inserts more than 100 your trigger breaks

trigger SetAccountField on ShipTo__c (before insert, before update) {
    for (ShipTo__c shipto : Trigger.new) {
        String accid = shipto.Customer_Code__c;
        List<Account> account = [SELECT Id FROM Account WHERE Customer_Code__c = :accid];
        if(account != null && account.size()>0)
             shipto.Account__c = account[0].Id;
    }
}




All Answers

logontokartiklogontokartik
Please try below. 

You are writing a SOQL inside a for loop and your assignment is not correct. 


trigger SetAccountField on ShipTo__c (before insert, before update) {
   
    Set<String> customerCodeSet = new Set<String>(); 
    for (ShipTo__c shipto : Trigger.new) {
       customerCodeSet.add(shipto.Customer_Code__c); 
    }
    Map<String,Account> customerCodeAccMap = new Map<String,Account>();
    for(Account acc : [Select Id,Customer_Code__c from Account where Customer_Code__c IN :customerCodeSet]){
        customerCodeAccMap.put(acc.Customer_Code__c,acc);
    }
    for (ShipTo__c shipto : Trigger.new) {
        if(shipto.Customer_Code__c != null && customerCodeAccMap.containsKey(shipto.Customer_Code__c))
            shipto.Account__c = customerCodeAccMap.get(shipto.Customer_Code__c).Id;
    }
}

Hope this helps.

Michael BobeeMichael Bobee
Actually, it looks like it got twice as complicated than I am even close to understanding. I have only created one small trigger, so this doesn't make any sense. One thing I can tell you is that the ShipTo table will always have a value in the Customer_Code__c field. What does the <String> placeholder represent? Why are there three 'for' loops? I'm only creating one record,- then matching it to the corresponding account based on the value in the Customer_Code__c field. I guess I need to do more reading.
logontokartiklogontokartik
Actually its not complicated. Its the way the trigger must be writtern in order to manage the bulk design pattern. If you put a SOQL inside a for loop, there is a very high chance of you hitting a SOQL Governor limit. 

All I am doing is 

1. Creating a Customer code set
2. Querying the Account table to get all accounts in one shot (this is only one SOQL statement)
3. Loading them into the Map collection.
4. Again going and verifying the each shipTo record to get the correct Account.


Please review the following link

http://www.sfdc99.com/beginner-tutorials/

if you want to use your code, you can do (i modified it a little). it will work fine for one or 2 records, but if someone updates or inserts more than 100 your trigger breaks

trigger SetAccountField on ShipTo__c (before insert, before update) {
    for (ShipTo__c shipto : Trigger.new) {
        String accid = shipto.Customer_Code__c;
        List<Account> account = [SELECT Id FROM Account WHERE Customer_Code__c = :accid];
        if(account != null && account.size()>0)
             shipto.Account__c = account[0].Id;
    }
}




This was selected as the best answer
Srik PothSrik Poth
Karthiks code makes sense. You trigger is not the best approach.. 

If you are updating or inserting over 100 ShipTo__c records then your SOQL limit would hit and your forloop will execute 100 times. Whenever you write a Trigger you need to make sure it works in bulk.
Michael BobeeMichael Bobee
Thank you. I will remove the 'before update'. this will only happen on insert and they do not change, so that's a safe removal. From there, I will stare at the code and look at David Lui's website for some tips.
Michael Bobee 4Michael Bobee 4
OK,- I'm still learning. This derivation is looking for the Account ID from one record type to populate a parent acocunt field. Am I close?

01 trigger SetParentAccount on Account (before insert, before update) {
02  
03  Set<String> customerCodeSet = new Set<String>();
04    for (Account acc : Trigger.new) {
05       customerCodeSet.add(acc.Group_ID__c);
06    }
07    Map<String,Account> customerCodeAccMap = new Map<String,Account>();
08    for(Account acc : [Select Id,Group_ID__c from Account where Group_ID__c IN :customerCodeSet && RecordType = '01239000000URW3AAO']){
09        customerCodeAccMap.put(acc.Group_ID__c,acc);
10    }
11    for (Account acc : Trigger.new) {
12        if(acc.Group_ID__c != null && customerCodeAccMap.containsKey(acc.Group_ID__c))
13            acc.Parent = customerCodeAccMap.get(acc.Group_ID__c).Id;
14    }
15}