Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I need to update the Picklist values for a custom field on a custom object. I have already populated the Available Values via the Enterprise and Metadata Java APIs, but now I need to move the newly updated Available Values to the Selected Values Picklist.

I can query the custom field as described in this post:

REST API: How to retrieve active values for picklist?

Does anyone have an example of doing this via the Enterprise/Metadata APIs?

Update:

This is the code that I use to update the picklist using the Salesforce API. This only updates the Available Values and not the Selected Values of the Picklist:

/** Updates the versions in Salesforce. */
public void updateSalesforceVersions() throws ConnectionException, InterruptedException
{
  // Salesforce object and field name values
  String sObjectName = "Product_Information__c";
  String fieldName = "Licensed_Version__c";
  String fullName = String.format("%s.%s", sObjectName, fieldName);

  List<OhmVersion> versionsFromDao = this.getOhmVersions();

  Field versionsField = SalesforceUtilities.getField(
    salesforceConnectionSource.getConnection().getEnterpriseConnection(),
    FieldType.picklist, sObjectName, fieldName);

  if(versionsField == null)
    return;

  Picklist versionsPicklist = new Picklist();
  List<PicklistValue> versionsPicklistValues = new ArrayList<>();
  for (OhmVersion version : versionsFromDao)
  {
    PicklistValue picklistValue = new PicklistValue();
    picklistValue.setFullName(version.getVersion());
    versionsPicklistValues.add(picklistValue);
  }
  versionsPicklist.setPicklistValues(versionsPicklistValues.toArray(
    new PicklistValue[versionsPicklistValues.size()]));

  CustomField customField = new CustomField();
  customField.setFullName(fullName);
  customField.setType(com.sforce.soap.metadata.FieldType.Picklist);
  customField.setLabel(versionsField.getLabel());
  customField.setPicklist(versionsPicklist);

  AsyncResult asyncResult = SalesforceUtilities.updateCustomField(
  salesforceConnectionSource.getConnection().getMetadataConnection(),
  fullName, customField);
}

This is the code that actually updates the picklist metadata:

public static AsyncResult updateCustomField(MetadataConnection metadataConnection,
                                            String fullName, 
                                            CustomField customField) 
  throws ConnectionException, InterruptedException
{
  AsyncResult asyncResult = new AsyncResult();

  // do the update
  UpdateMetadata updateMetadata = new UpdateMetadata();
  updateMetadata.setMetadata(customField);
  updateMetadata.setCurrentName(fullName);

  // wait for it to complete
  AsyncResult[] ars = metadataConnection.update(new UpdateMetadata[] {
    updateMetadata });
  asyncResult = ars[0];

  // set initial wait time to one second
  long waitTimeMilliSecs = 1000;
  while(!asyncResult.isDone())
  {
    Thread.sleep(waitTimeMilliSecs);
    // double the wait time for the next iteration
    waitTimeMilliSecs *= 2;
    asyncResult = metadataConnection.checkStatus(new String[] { asyncResult.getId()})[0];
  }
  return asyncResult;
}

This only updates the Available Values. I don't see any method or property to update the Selected Values. I can query the Selected Values with this code by using the EnterpriseConnection.describeLayout() method:

public void describeLayout()
{
  String sObjectName = PRODUCT_INFORMATION;
  try
  {
    // Make the describe call
    DescribeLayoutResult describeLayoutResult = 
        this.enterpriseConnection.describeLayout(sObjectName,
                             new String[] { SalesforceConstants.PRODUCT_INFORMATION_OHM_RECORD_TYPE_ID });
    // Get sObject metadata
    if (describeLayoutResult != null)
    {
      for(RecordTypeMapping recordTypeMapping : describeLayoutResult.getRecordTypeMappings())
      {
        System.out.println("RecordTypeMap name: " + recordTypeMapping.getName());
        for(PicklistForRecordType picklistForRecordType : recordTypeMapping.getPicklistsForRecordType())
        {
          System.out.println("Picklist Name:" + picklistForRecordType.getPicklistName());
          for(PicklistEntry entry : picklistForRecordType.getPicklistValues())
          {
            System.out.println("Entry Value:" + entry.getValue());
          }
          System.out.println();
        }
        System.out.println();
      }
    }
  }
  catch (ConnectionException ce)
  {
    fail("Connection failed: " + ce);
  }
}

How do I update the Selected Values even if I need to use a different class/method?

share|improve this question
1  
Can you clarify what you're having difficulty with and what you've tried? It sounds like you have been able to add selectable values to a multi-picklist, but you now need to actually select those values for a specific record? –  jkraybill Feb 13 '13 at 3:46
1  
@jkraybill - I've updated the post with additional information and actual code. Hopefully this helps. –  dprice Feb 13 '13 at 15:29
add comment

1 Answer

I was finally able to figure it out. It was a combination of using the RecordType with the metadata.update() call:

public void recordTypeSample() throws InterruptedException
{
  try
  {
    RecordType productInfo = new RecordType();
    productInfo.setFullName("Product_Information__c.OHM");
    productInfo.setLabel("OHM");

    PicklistValue version1 = new PicklistValue();
    version1.setFullName("7.4.5");

    RecordTypePicklistValue ohmVersions = new RecordTypePicklistValue();
    ohmVersions.setPicklist("Licensed_Version__c");
    ohmVersions.setValues(new PicklistValue[] { version1 });
    productInfo.setPicklistValues(new RecordTypePicklistValue[] { ohmVersions });

    UpdateMetadata updateMetadata = new UpdateMetadata();
    updateMetadata.setMetadata(productInfo);
    updateMetadata.setCurrentName(productInfo.getFullName());

    AsyncResult[] asyncResults = this.metadataConnection.update(new UpdateMetadata[] { updateMetadata });

    AsyncResult asyncResult = asyncResults[0];

    // set initial wait time to one second
    long waitTimeMilliSecs = 1000;
    while(!asyncResult.isDone())
    {
      Thread.sleep(waitTimeMilliSecs);
      // double the wait time for the next iteration
      waitTimeMilliSecs *= 2;
      asyncResult = metadataConnection.checkStatus(new String[] { asyncResult.getId() })[0];
    }
  }
  catch(ConnectionException ce)
  {
    ce.printStackTrace();
  }
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.