We have a bunch of multi-select picklists on standard page layouts, whereby the selectable values have been largely reworked. When not in edit mode, the selected values are semicolon delimited strings, but we're now seeing duplicate values in these strings.

When you go to edit mode, it "realigns" the selections to reflect the new values and indeed saving without making any manual changes fixes the delimited list.

Normally in situations like this (when things are fired on a trigger, for example), I'd just pull all the IDs out in Data Loader and put them back in again on an Update, which changes LastModified, which fires the triggers. However, in this scenario, there is no trigger - it's something about going to Edit mode that fires and updates the selections.

Is there a way to update these in bulk? Way too many records to manually edit

1 Answer 1


You can use a utility class such as this:

public class Multi {

    public static Set<String> parse(String values) {
        Set<String> s = new Set<String>();
        if (values != null && values != '') {
            for (String part : values.split(';')) {
        return s;

    public static String format(Set<String> values) {
        if (values == null) return null;
        List<String> l = new List<String>(values);
        return format(l);

    public static String format(List<String> values) {
        if (values == null) return null;
        return String.join(values, ';');

called from a batchable that you Database.executeBatch:

public class MyBatchable implements Database.Batchable<SObject> {

    public Database.QueryLocator start(Database.BatchableContext context) {
        return Database.getQueryLocator([select MyField__c from MyObject__c]);                                                                                                                                                

    public void execute(Database.BatchableContext context, List<MyObject__c> scope) {
        for (MyObject__c sob : scope) {
            sob.MyField__c = Multi.format(Multi.parse(sob.MyField__c));
        update scope;

    public void finish(Database.BatchableContext context) {
  • Not sure you're quite getting the issue here - the string concatenation of the selected values is a built-in platform feature for multi-select picklists, we're looking to leverage that refresh rather than try and build our own string values. Or is it me that is missing something and this is indeed the only way to refresh them, by overwriting forcibly?
    – Rob Cowell
    Jan 16, 2018 at 11:51
  • 1
    @RobCowell Yeah I don't think I am either. In your question you say "duplicate values" but by that do you mean a mix of the old values and the new values and that you want to discard the old values or replace them with corresponding new values? If so change the right hand side of sob.MyField__c =. Updating the database avoids having to manually edit every record to make the change.
    – Keith C
    Jan 16, 2018 at 12:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .