Preamble, can skip: I was helping someone make some adjustments to the Inline Account Hierarchy app from Force.com Labs. Since it's an unmanaged package, and the docs are very clear, you can do some interesting things with it.

The test code that comes with it inserts Accounts, with state and country. It predates the State & Country picklists feature, and tests/deploy fails when trying to deploy changed code from a sandbox to production when State & Country picklists are enabled. I changed the tests to work specifically in the org where the feature is active, but thought I might try to create and submit a pull request that would leave the tests working whether or not State & Country picklists are active.

Actual question: Is this the best way to determine if State & Country Picklists have been enabled, and run slightly different processes if they have?

if (Schema.SObjectType.Account.fields.getMap().containsKey('BillingStateCode')) {
        // create test data with Account.[Billing|Shipping]StateCode and Account.[Billing|Shipping]CountryCode
else {
       // create test data with Account.[Billing|Shipping]State and Account.[Billing|Shipping]Country

One could also create the test data without these fields, of course, but that's a much less interesting learning exercise, and I assume the original coders included fullsome test data for a reason.

1 Answer 1


Most standard fields are in place by default. There are a few fields in which I can see where it may not exist. One example of this would be if you never turned on PersonAccounts, the field IsPersonAccount would not exist. Grabbing all of an Sobject's fields in a map and validating the API Name is a good way to determine if a field exists if one is trying to make something dynamic. Just keep in mind for governor limits.

Here's a method I wrote a while back which does the same thing as you are requesting...

 * Return a Boolean to let you know if an Sobject has a field 
 * with the API name passed in
public static Boolean doesSobjectHaveField(String sObjectName, String fieldName){
    SObjectType sot = Schema.getGlobalDescribe().get(sObjectName);
    if (null == sot || null == fieldName) 
        return false;

    return sot.getDescribe().fields.getMap().keySet().contains(fieldName.toLowerCase());

static void testDoesSObjectHaveField(){
    system.assertEquals(false, doesSobjectHaveField(null, null));
    system.assertEquals(true, doesSobjectHaveField(Schema.SObjectType.Account.getName(), 'Name'));
    system.assertEquals(false, doesSobjectHaveField(Schema.SObjectType.Account.getName(), 'Name123'));
  • Thanks, but my tests indicate that Account.BillingStateCode doesn't show up in the field map if State & Country Picklists aren't enabled. I've run: boolean hasSCPicklists = Schema.SObjectType.Account.fields.getMap().containsKey('BillingStateCode'); System.debug(hasSCPicklists); as Execute Anonymous in orgs with & without the feature turned on, and I get false in orgs without, and true in orgs with. Also, just so I understand - your solution works the same but more generally than mine, and so doesn't determine differently if S&C picklists is on, correct? Feb 25, 2014 at 20:02
  • 1
    I'm sorry I read BillingState while skimming through. You are right about BillingStateCode. This is just like IsPersonAccount
    – Double A
    Feb 25, 2014 at 20:16

You must log in to answer this question.

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