+ Start a Discussion
Jeff C.ax327Jeff C.ax327 

Adding a new value to a picklist field -- 90% there

I've managed to write code that inserts a value into a picklist field from my c# web application.  However, it is VERY clunky and I still can't figure out how to keep from losing some of the field properties.


First, it seems a little silly to have to programmatically recreate the entire picklist field just so I can update it with one new value in the picklistValues property.  Also, I have to do a describeSObject and then step through all the fields looking for the right field name.  Isn't there a way to just grab the metadata for a field directly?  I've seen code like the following, but....

Schema.DescribeFieldResult f = Schema.sObjectType.Account.fields.MyFieldName__c;

 ...but, I don't seem to have the Schema namespace/library at my disposal from the C# environment.  Is there ANY way to get DescribeFieldResult functionality in C#?


So I loop through the fields in the object, find the one I want, step through each of the picklist values and recreate them in a new array.  Then I add my new entry to the picklist values array and save it to the picklistValues property.  I can update the field and the new value does in fact show up in Salesforce.... but...


...another problem is that I end up losing the Picklist.Description and Picklist.Sorted properties because the Field object that I'm reading from doesn't have that information.

Well, enough words from me, here is the code.  This works, but you lose the Description and Sorted settings each time.  I post it in hopes that it helps someone and that perhaps someone can help us figure out the rest.



public void InsertPicklistValue(string objectName, string picklistFieldName, string valueToInsert) { try { // Load describe info for the object. DescribeSObjectResult descSObjectRslt = c_sfEnterprise.describeSObject(objectName); if (descSObjectRslt != null) { Field[] fields = descSObjectRslt.fields; foreach (Field field in fields) { if (field.name == picklistFieldName) { // Get the array of existing picklist entries. PicklistEntry[] picklistEntries = field.picklistValues; // We have to recreate the entire list of existing picklist values... List<PicklistValue> pVals = new List<PicklistValue>(); PicklistValue pVal; foreach (PicklistEntry picklistEntry in picklistEntries) { pVal = new PicklistValue(); pVal.@default = picklistEntry.defaultValue; if (picklistEntry.label != null) pVal.fullName = picklistEntry.label; else pVal.fullName = picklistEntry.value; pVals.Add(pVal); } // Add the NEW value... pVal = new PicklistValue(); pVal.fullName = valueToInsert; pVals.Add(pVal); // Now that we have the values, we need to save them to a new picklist. Picklist pList = new Picklist(); pList.picklistValues = pVals.ToArray(); //pList.sorted = how can we get this from the existing field? CustomField picklistField = new CustomField(); picklistField.fullName = objectName + "." + picklistFieldName; picklistField.label = field.label; picklistField.type = FieldType.Picklist; picklistField.picklist = pList; picklistField.inlineHelpText = field.inlineHelpText; //picklistField.description = how/where can we get this? // Update the existing picklist. UpdateMetadata updatedMetadata = new UpdateMetadata(); updatedMetadata.currentName = objectName + "." + picklistFieldName; updatedMetadata.metadata = picklistField; AsyncResult result = update(new UpdateMetadata[] { updatedMetadata })[0]; while (!result.done) { System.Threading.Thread.Sleep(result.secondsToWait * 1000); result = checkStatus(new string[] { result.id })[0]; } if (result.state == AsyncRequestState.Error) Console.WriteLine("Error {0}\n{1}", result.statusCode, result.message); else Console.WriteLine("Picklist updated successfully"); break; } } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("\nFailed to get " + objectName + " description, error message was: \n " + ex); } }



Anyone?  Bueller?




Mike LeachMike Leach

Not sure if the question is "how to read picklist metadata?", "how to update picklist metadata?" or both.


But the following snippet of C# works to query picklists. The native NameValueCollection in .NET is a great container for storing and caching picklist values.



public static NameValueCollection GetPicklistValues(string className, string fieldName)
NameValueCollection result = new NameValueCollection();

DescribeSObjectResult sr = SForceService.describeSObject(className);
if(sr == null || sr.fields == null || sr.fields.Length == 0)
return null;

foreach(Field field in sr.fields)
if (field.type != fieldType.picklist && field.type != fieldType.multipicklist)

foreach(PicklistEntry entry in field.picklistValues)
result.Add(entry.label, entry.value);

return result;
return null; //Class name / field not found


I have no experience with updating picklist metadata through the API. If your code works, I'll take your word for it :-)



Jeff C.ax327Jeff C.ax327

Thanks for your reply.  The question is all metada related...

I can get the existing values fine, but I'm trying to add a new value programmatically without losing any of the field information, i.e., Description and Sorted.  I wish there was a way to just put a new value in the .picklistValues array without having to totally recreate and overwrite the entire picklist field.

I also working on same issue.Did you considered packing and upgrading picklist values.
Is it possible to do this using Apex code instead?
Apex LearnerApex Learner

is there any way to edit picklist value through metadat API . 

I am current testing meta data API via SOAP ui and till now I am able to add picklist values .

but can not edit any perticuler picklist value 


eg . object : lead 

       field : number__c

  type : picklist


values : 1 , 2


any methode i cn edit 1 to 11  ??