42

It states in Salesforce Apex docs that I can get fields for a particular SObject (standard or custom) in the following way:

Map<String, Schema.SObjectField> M = Schema.SObjectType.Custom__c.fields.getMap();

But this requires hardcoding. as I need to hardcode the API name of the SObject : Schema.SObjectType.

Is there a way to access all fields on an SObject dynamically without hard coding? I am getting a list of all SObjects in my org by calling Schema.getGlobalDescribe(), but this leaves me with API names of individual SObjects. There is no way to get all those SObject's field info dynamically. Am I missing something or it is just not possible?

I want something like:

List <Schema.SObjectField> fieldList = Schema.SObjectType.get(SObject_API_Name).fields;

7 Answers 7

58

You don't need to hard code the Object name as you have specified, you can indeed do it dynamically, for example:

SObjectType accountType = Schema.getGlobalDescribe().get('Account');
Map<String,Schema.SObjectField> mfields = accountType.getDescribe().fields.getMap();
3
  • 1
    Thanks! Exactly what I was looking for. But somehow I weren't able to find the getGlobalDescribe().get(strname) flavour of this in SF docs ... although the hardcoded example is pretty common. Thanks again.
    – S_2013
    Commented Dec 3, 2013 at 9:22
  • 1
    getGlobalDescribe returns a Map<String,Schema.SObjectType>, so you're using the Map class's get method. Commented Jun 12, 2015 at 5:04
  • @S_2013 the getGlobalDescribe() method is under the Schema class , which is under the System namespace. you can find it here developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/…. There is another Schema namespaces which as another set of functions.developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/…
    – Don
    Commented Sep 8, 2022 at 10:20
27

The docs suggest you use the newer Schema.describeSObjects(List) method - that lets you pass one or more names of objects as a list, and get back the results. Here's the sample code:

// sObject types to describe
String[] types = new String[]{'Account','Merchandise__c'};
// Make the describe call
Schema.DescribeSobjectResult[] results = Schema.describeSObjects(types);
System.debug('Got describe information for ' + results.size() + ' sObjects.');
// For each returned result, get some info
for(Schema.DescribeSobjectResult res : results) {
    System.debug('sObject Label: ' + res.getLabel());
    System.debug('Number of fields: ' + res.fields.getMap().size());
    System.debug(res.isCustom() ? 'This is a custom object.' : 'This is a standard object.');
    // Get child relationships
    Schema.ChildRelationship[] rels = res.getChildRelationships();
    if (rels.size() > 0) {
        System.debug(res.getName() + ' has ' + rels.size() + ' child relationships.');
    }
}
2
  • 7
    Faster than describe global when you know the names you're looking for, important for the new governor limits.
    – sfdcfox
    Commented Nov 26, 2013 at 17:12
  • How about for custom metadata? Super_Metadata__mdt? Commented May 31, 2021 at 20:43
8

You can use Schema.SObjectType to get the object type dynamically:

String obj = 'Account';

Map<String,Schema.SObjectType> gd = Schema.getGlobalDescribe(); 
Schema.SObjectType sobjType = gd.get(obj); 
Schema.DescribeSObjectResult describeResult = sobjType.getDescribe(); 
Map<String,Schema.SObjectField> fieldsMap = describeResult.fields.getMap(); 
4
String sobjectname = 'Case' ; //object api name
String fieldapiName = 'Status'; //Field api name
String fieldTypeName = Schema.getGlobalDescribe().get(sobjectname).getDescribe().fields.getMap().get(fieldApiName).getDescribe().getType().name().toupperCase(); 
System.debug('*** fieldTypeName = ' + fieldTypeName);       
0

There is a way to access all fields on an SObject dynamically without hard coding:

Schema.SObjectField result = Schema.getGlobalDescribe().get('yourObjectName as a string').getDescribe().fields.getMap().get('yourFieldName as a string');

Did it not work in 2013 ?

#archeology

0

In some orgs with a lot of objects processing time for getGlobalDescribe can consume a lot of time. You can use this instead:

SObjectType accountType = ((SObject) Type.forName('Account').newInstance()).getSObjectType();

It is consumes 1 ms for my org instead of around 60 ms for getGlobalDescribe

-4

The Summer '16 release has a nice function to retrieve populated fields from an object: getPopulatedFieldsAsMap()

I had a simple use case of generating a CSV file from an arbitrary list of sObjects for which it provided an easy solution.

Using getPopulatedFieldsAsMap() you can retrieve a map of field names and their corresponding values without knowing the object type.

sObject data = [SELECT Id, Name FROM Lead LIMIT 1];
Map<String, Object> fieldsAndValues = data.getPopulatedFieldsAsMap();
2
  • 6
    This doesn't really answer the question. It doesn't give you all fields on the object, only a subset of them. And you need actual records.
    – Adrian Larson
    Commented Jul 26, 2016 at 17:43
  • @AdrianLarson , may I know what you mean by subset . Because I check release note releasenotes.docs.salesforce.com/en-us/summer16/release-notes/… , it does not state limitation. However I stil face some of the field is not return although class version is 46.
    – unidha
    Commented Jul 18, 2019 at 7:26

You must log in to answer this question.

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