+ Start a Discussion
dselatdselat 

trigger to add value to a custom multi-select pick list field

Hello, I need to have a trigger to update or add new values to existing multi-select custom picklist field. I've below trigger but it overwrites existing value. How can I add to multi-select field? or Can you direct me to a forum that have a solution? Appreciate your help.


trigger AccountUpdate_Saas on OpportunityLineItem (after update) {
  //Get Triggered Opps
  List<Account> Accts = new List<Account>();
    for (OpportunityLineItem ol : [Select O.Opportunity.AccountId, O.Contract_Type__c from OpportunityLineItem O where O.id in :Trigger.newMap.keySet()]) {
    if(ol.Contract_Type__c == 'SaaS'){
      Account eachAccount = new Account(Id=ol.Opportunity.AccountId);
      eachAccount.Client_Product_Line_s__c='SaaS (Not Specific)';
      Accts.add(eachAccount);
    }
  }
    if(!Accts.isEmpty()){
    update(Accts);
  }
}
vhanson222vhanson222

You can add multi-select picklist values to a field through the user interface by going to Setup | Customize | Opportunity | Fields and selecting your multi-select picklist. 

Ritesh AswaneyRitesh Aswaney

The Values in a multi select picklist are stored as semi colon (;) separated values in the database.

 

eg London;Paris;Frankfurt

 

So if you'd like to append values, just delimit using semicolons and set the field value

dselatdselat

Thanks Ritesh. But then I should not overwrite the values that already exists in multi-select field. How can I do this with triggers? Should I first query and get all the values in that field and re-add them along with the new value? If so how to do it? I am new to SFDC triggers.

dselatdselat

I am not talking about adding through gui.

Ritesh AswaneyRitesh Aswaney

Yes, include them in your SOQL query and then just append the new values to them, like you would to a string

 

eg

for (Account acc : [Select Id, MultiSelectField__c from Account where ....]){

 

....

acc.MultiSelectField__c + = ''Paris;London' ;

 

}

Shashikant SharmaShashikant Sharma

Use this trigger

 

trigger AccountUpdate_Saas on OpportunityLineItem (after update) {
  //Get Triggered Opps
  List<Account> Accts = new List<Account>();
    for (OpportunityLineItem ol : [Select O.Opportunity.AccountId,o.Opportunity.Account.Client_Product_Line_s__c, O.Contract_Type__c from OpportunityLineItem O where O.id in :Trigger.newMap.keySet()]) {
    if(ol.Contract_Type__c == 'SaaS'){
      Account eachAccount = new Account(Id=ol.Opportunity.AccountId);
      eachAccount.Client_Product_Line_s__c=ol.Opportunity.Account.Client_Product_Line_s__c+';'+'SaaS (Not Specific)';
      Accts.add(eachAccount);
    }
  }
    if(!Accts.isEmpty()){
    update(Accts);
  }

 

 

 

This should solve your problem.

dselatdselat

Here is the updated code but it still won't append the new value to the multi-select field. Not sure what is wrong:

 

 

trigger AccountUpdate_Saas on OpportunityLineItem (after update) {
    //Get Triggered Opps
    List<Account> Accts = new List<Account>();
  for (OpportunityLineItem ol : [Select O.Opportunity.AccountId, O.Contract_Type__c from OpportunityLineItem O where O.id in :Trigger.newMap.keySet()]) {
        if(ol.Contract_Type__c == 'SaaS'){
            //Account eachAccount = new Account(Id=ol.Opportunity.AccountId);
            for (Account acc:[Select Id,Client_Product_Line_s__c from Account where Id=:ol.Opportunity.AccountId]){
            acc.Client_Product_Line_s__c +='SaaS (Not Specific)';
      }
      }
   }
}
Ritesh AswaneyRitesh Aswaney

You're missing the semi-colon delimiter between values. Also in an after trigger, you need an explicit update - so you will need to aggregate your Account record in a list and issue an Update at the end

 

So,

 acc.Client_Product_Line_s__c +=';SaaS (Not Specific)';
dselatdselat

Hi Shashikant, Thanks...It works! Need to add another condition is it should not add 'SaaS (Not Specific) if it already exists..How to achieve this?.

Ritesh AswaneyRitesh Aswaney

if (acc.Client_Product_Line_s__c.indexOf('SaaS (Not Specific)') < 0)

acc.Client_Product_Line_s__c += ';SaaS (Not Specific)';

 

You could also use CONTAINS, i.e. str1.contains(str2)

 

Another alternative would be to only select values which dont already have Saas (Not Specific) in the field by using a SOQL Where Clause, so that condition never arises.

http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_soql_querying_multiselect_picklists.htm

Shashikant SharmaShashikant Sharma

Hi dselat,

 

I will your solution has two problems in my view

1)It uses SOQL in loop , not a best practice bcoz trigger will fail for bulk data

2)acc.Client_Product_Line_s__c +='SaaS (Not Specific)';

 I think it should be

 acc.Client_Product_Line_s__c +=';SaaS (Not Specific)';

 

Shashikant SharmaShashikant Sharma

Use this in your condition before update

 

IF(ol.Contract_Type__c == 'SaaS' && (!ol.Opportunity.Account.Client_Product_Line_s__c.Contains('SaaS (Not Specific)')))

 

 

 

 

dselatdselat

Ritesh and Shashikant...thanks to both of you. Here is the final code that is working fine:

 

 

trigger AccountUpdate_Saas on OpportunityLineItem (after update) {
    //Get Triggered Opps
    List<Account> Accts = new List<Account>();
  for (OpportunityLineItem ol : [Select O.Opportunity.AccountId, O.Contract_Type__c from OpportunityLineItem O where O.id in :Trigger.newMap.keySet()]) {
        if(ol.Contract_Type__c == 'SaaS'){
            //Account eachAccount = new Account(Id=ol.Opportunity.AccountId);
            for (Account acc:[Select Id,Client_Product_Line_s__c from Account where Id=:ol.Opportunity.AccountId]){
            if (acc.Client_Product_Line_s__c.indexOf('SaaS (Not Specific)') < 0){
            acc.Client_Product_Line_s__c +=';SaaS (Not Specific)';
            Accts.add(acc);}  }
      }
   }
if(!Accts.isEmpty()){
        update(Accts);
    }

}