How to mass populate State & Country picklist values

As of this time, there is no support for doing anything but mass editing of States you've already added manually to the system (no way to use the Metadata API to create/delete).


The best way I've found to do this is using the Selenium plugin for Firefox. It's a horrible hack, but it got the job done and has saved many hours typing thousands of values into multiple environments. You can generate a file by recording your actions in the browser, and then replay that file against a Salesforce session to insert the picklist values.

The recorded file is in HTML format, so you can use a text editor to generate it automatically. I loaded the state list I needed to import into Excel, and then generated the HTML I needed to import it into the org using excel concatenation functions.

Below is an example of the HTML I used, to import more simply insert repeated copies of the whole section within the <tbody> tag

<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <meta content="text/html; charset=UTF-8">
        <link rel="selenium.base" href="https://cs80.salesforce.com">
    </head>
    <body>
        <table cellpadding="1" cellspacing="1" border="1">
            <thead>
                <tr>
                    <td rowspan="1" colspan="3">New Test</td>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>open</td>
                    <td>/i18n/ConfigureNewState.apexp?countryIso=****Country Code Here****&amp;setupid=AddressCleanerOverview</td>
                    <td></td>
                </tr>
                <tr>
                    <td>waitForElementPresent</td>
                    <td>id=configurenew:j_id1:blockNew:j_id9:nameSectionItem:editName</td>
                    <td></td>
                </tr>
                <tr>
                    <td>type</td>
                    <td>id=configurenew:j_id1:blockNew:j_id9:nameSectionItem:editName</td>
                    <td>****State Display Name Here****</td>
                </tr>
                <tr>
                    <td>type</td>
                    <td>id=configurenew:j_id1:blockNew:j_id9:codeSectionItem:editIsoCode</td>
                    <td>****State Code Here****</td>
                </tr>
                <tr>
                    <td>type</td>
                    <td>id=configurenew:j_id1:blockNew:j_id9:intValSectionItem:editIntVal</td>
                    <td>****State Integration Name Here****</td>
                </tr>
                <tr>
                    <td>click</td>
                    <td>id=configurenew:j_id1:blockNew:j_id9:activeSectionItem:editActive</td>
                    <td></td>
                </tr>
                <tr>
                    <td>waitForEditable</td>
                    <td>id=configurenew:j_id1:blockNew:j_id9:visibleSectionItem:editVisible</td>
                    <td></td>
                </tr>
                <tr>
                    <td>click</td>
                    <td>id=configurenew:j_id1:blockNew:j_id9:visibleSectionItem:editVisible</td>
                    <td></td>
                </tr>
                <tr>
                    <td>clickAndWait</td>
                    <td>id=configurenew:j_id1:blockNew:j_id43:addButton</td>
                    <td></td>
                </tr>
            </tbody>
        </table>
    </body>
</html>

Beware, this solution is liable to break at any moment if Salesforce update the configuration UI. Also the reliability of the import varies with your network connection, and the speed you execute the script in Selenium (although someone with more detailed knowledge of Selenium may be able to fix this).


Here's a batch class that creates all ISO states:

  • approx 5,000 default state codes
  • it screen scrapes the 'Configure New State' form,
  • then posts back to the setup menu to create each picklist value:

https://github.com/bigassforce/statecodes