What’s The Process For Modifying Custom Picklist Field Values With The Metadata API?

Users can manually add, delete, or update the values of a custom picklist field. However, there are instances where updating and adding these values programmatically becomes necessary. This is where the metadata API proves invaluable. For a deeper understanding of the metadata API, you can refer to resources on Metadata, Custom Metadata Types, and Metadata API.

To update the values of a custom picklist field, two classes are needed:

  • MetadataService.cls: While this class is available online, modifications specific to this scenario have been made within it.
  • Another class is required for updating the values of a custom picklist field, which we refer to as updatingCustomPicklistValues. This class is designed for a custom picklist field on any object; in this case, we’ve chosen the Opportunity object with a custom picklist field named Picklist_check.

Modifying Custom Picklist Field Values

public class UpdatingCustomPicklistValues { 
// Method to update the values of custom picklist field 
     public static void updatePicklistValues() { 
          MetadataService.MetadataPort service = new MetadataService.MetadataPort(); 
          service.SessionHeader = new MetadataService.SessionHeader_element(); 
          service.SessionHeader.sessionId = UserInfo.getSessionId(); 
          MetadataService.ValueSet picklistValueSet = new MetadataService.ValueSet(); 
          MetadataService.ValueSetValuesDefinition valueDefinition = new MetadataService.ValueSetValuesDefinition(); 
          List<MetadataService.ExtendedCustomValue> values = new List<MetadataService.ExtendedCustomValue>(); 
          // Fetching the values already available in the custom picklist field and storing them in the list 
          List<Schema.PicklistEntry> picklistValues = Opportunity.Picklist_check__c.getDescribe().getPicklistValues();
          // Adding the already available values 
               for(Schema.PicklistEntry picklistValue : picklistValues) { 
                    MetadataService.ExtendedCustomValue customValue1 = new MetadataService.ExtendedCustomValue(); 
                    customValue1.fullname = (string)picklistValue.getValue(); 
                    customValue1.default_x = false; 
                    customValue1.isActive = true; 
                    customValue1.label = picklistValue.getLabel(); 
                    values.add(customValue1); 
               } 
          //Adding the extra value, we want to add 
          MetadataService.ExtendedCustomValue customValue2 = new MetadataService.ExtendedCustomValue(); 
          customValue2.fullname = ‘1’; 
          customValue2.default_x = false; 
          customValue2.isActive = true;
          customValue2.label = ‘1’; 
          values.add(customValue2);
          valueDefinition.value = values; 
          valueDefinition.sorted = true; 
          picklistValueSet.valueSetDefinition = valueDefinition; 
          MetadataService.CustomField customField = new MetadataService.CustomField(); 
          customField.fullName = ' Opportunity.Picklist_check__c '; 
          customField.label = ' Picklist_check '; 
          customField.type_x = 'Picklist'; 
          customField.required = false; 
          customField.unique = false; 
          customField.valueSet = picklistValueSet;
          MetadataService.CustomField[] customFields = new List<MetadataService.CustomField> { customField }; 
          service.upsertMetadata(customFields); 
     } 
     // Method to save the work done 
     public static void handleSaveResults(MetadataService.SaveResult saveResult) 
          { 
          if(saveResult==null || saveResult.success) 
          return; 
          // Construct error message and throw an exception 
          if(saveResult.errors!=null) 
               {
                    List<String> messages = new List<String>(); 
                    messages.add( 
                    (saveResult.errors.size()==1 ? 'Error ' : 'Errors ') + 
                    'occured processing component ' + saveResult.fullName + '.'); 
                    for(MetadataService.Error error : saveResult.errors) 
                    messages.add( 
                    error.message + ' (' + error.statusCode + ').' + 
                    ( error.fields!=null && error.fields.size()>0 ? 
                    ' Fields ' + String.join(error.fields, ',') + '.' : '' ) ); 
                    if(messages.size()>0) 
                    throw new MetadataServiceExamplesException(String.join(messages, ' ')); 
               } 
          if (!saveResult.success) 
          throw new MetadataServiceExamplesException('Request failed with no specified error.'); 
     } 
     //Method to create an instance of MetadataService.MetadataPort 
     public static MetadataService.MetadataPort createService() 
     { 
          MetadataService.MetadataPort service = new MetadataService.MetadataPort(); 
          service.SessionHeader = new MetadataService.SessionHeader_element(); 
          service.SessionHeader.sessionId = UserInfo.getSessionId(); 
          return service; 
     } 
     public class MetadataServiceExamplesException extends Exception { } 
}

Next, within the Developer Console, save both classes. Afterward, navigate to Debug and then select Open Execute Anonymous Window. Copy and paste the provided code into the anonymous window.

UpdatingCustomPicklistValues.UpdatePicklistValues();

And there you have it, it’s completed!