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
Kon DeleKon Dele 

How to Bulkify Trigger to populate Opportunity Picklists with Account Picklists

I'm working on a requirement as follows: Whenever an Opportunity is created or edited, its custom region picklists (Region__c) should be overwritten with the Account region picklists (Region__c).

Trying to develop a trigger that would satisfy this requirement.

Whenever an Opportunity is created or edited, check to see if any of the custom Region__c picklists are NULL. If any are NULL, overwrite all picklist fields with corresponding data from the Account object.

Here is what I have so far:

trigger UpdateOpptyPicklists on Opportunity(Before Insert, Before Update) {
    for(Opportunity o: Trigger.new){
     Account a = [select id,Region__c,Area__c, Division__c from Account where Id=:o.AccountId];
      
        if(o.Region__c == NULL || o.Area__c == NULL || o.Division__c == NULL){
        
          o.Region__c=a.Region__c;
          o.Area__c = a.Area__c;
          o.Division__c=a.Division__c;
       }
  }
}

One major flaw with my trigger is that I have SOQL running inside a loop. How can I bulkify this trigger?

Best Answer chosen by Kon Dele
Surya KiranSurya Kiran
Check this..


trigger UpdateOpptyPicklists on Opportunity(Before Insert, Before Update) {

map<Id,Account> mymap=new map<Id,Account>([select id,Region__c,Area__c, Division__c from Account where id IN(select Accountid from Opportunity)]]);

for(Opportunity o: Trigger.new){
     if(mymap.containsKey(o.AccountId)){
        if(o.Region__c == NULL || o.Area__c == NULL || o.Division__c == NULL){
      
          o.Region__c=mymap.get(o.AccountId).Region__c;
          o.Area__c = mymap.get(o.AccountId).Area__c;
          o.Division__c=mymap.get(o.AccountId).Division__c;
       }
}
  }
}

All Answers

Surya KiranSurya Kiran
Check this..


trigger UpdateOpptyPicklists on Opportunity(Before Insert, Before Update) {

map<Id,Account> mymap=new map<Id,Account>([select id,Region__c,Area__c, Division__c from Account where id IN(select Accountid from Opportunity)]]);

for(Opportunity o: Trigger.new){
     if(mymap.containsKey(o.AccountId)){
        if(o.Region__c == NULL || o.Area__c == NULL || o.Division__c == NULL){
      
          o.Region__c=mymap.get(o.AccountId).Region__c;
          o.Area__c = mymap.get(o.AccountId).Area__c;
          o.Division__c=mymap.get(o.AccountId).Division__c;
       }
}
  }
}
This was selected as the best answer
Kon DeleKon Dele
Works perfectly! Thank you!!!!
kevin Carotherskevin Carothers
Hi Kon,

I'm glad this works for you, but it's pulling in all accounts from all opportunities - you might run into governor limits if you get a lot of data.
I'd add a few more lines to constrain your query results;

trigger UpdateOpptyPicklists on Opportunity(Before Insert, Before Update) {

List<Id> listIds = new List<Id>();
for(Opportunity o :Trigger.new){
    listIds.add(o.AccountId);
    }
    
map<Id,Account> mymap=new map<Id,Account>([SELECT id,Region__c,Area__c, Division__c
     FROM Account WHERE id IN(:listIds)]]);

for(Opportunity o: Trigger.new){
     if(mymap.containsKey(o.AccountId)){
        if(o.Region__c == NULL || o.Area__c == NULL || o.Division__c == NULL){
      
          o.Region__c=mymap.get(o.AccountId).Region__c;
          o.Area__c = mymap.get(o.AccountId).Area__c;
          o.Division__c=mymap.get(o.AccountId).Division__c;
          }
        }
    }
}

DISCLAIMER:   not tested....