Wednesday 9 October 2013

Describe all the fields for all SObjects

13:58
In one of the requirements I came across, I needed to get the list of all the fields across all objects. I wanted to make sure that I did in the best possible way, But couldn't find any straight answers. So here's the code I came up with. Its simple and straight-forward and if you find a better way to do this let me know in the comments. Thank you

To start off, we need the list of SObjects that we are going to run this for. Ideally we should have the list of SObjects stored in a Custom setting, this is a one time thing and could be done using anonymous apex execution. Following is the code to do just that..

List<string> SObjectList = new List<string>();

for(Schema.SObjectType objTyp : Schema.getGlobalDescribe().Values()){
   String name = objTyp.getDescribe().getName();
   // Exclude all the unwanted Sobjects e.g. History, Share etc..

 if(!name.containsignorecase('history') && !name.containsignorecase('tag')&&
    !name.containsignorecase('share') && !name.containsignorecase('feed')){      
      SobjectList.add(name);
  }
   // Insert into your custom settings
  }
Now that we've got the entire list of SObjects, lets do a Global Describe. Before we move on there is a gotcha here, as you know there is a governor limit on the number of Describes in an execution context (As of Winter '14 its 100 in both asynchronous and Synchronous) . I'll go ahead and suggest that its best if you could either do it in multiple executions or use a limit to control the number of SObjects processed.

 
      SObjectFieldsMap = new Map<string,Set<string>> ();
      Map<String, Schema.SObjectType> GlobalDescribe = new Map<String, Schema.SObjectType>();
      // Get the Global Describe which contains details for all objects
      GlobalDescribe =Schema.getGlobalDescribe();

      // Now we loop through our pre-compiled list of SObjects and get the describes for it
      for(String sObj:SObjectList)
      {
       // Populate the Map, with Sobject => list of fields
       if(SObjectFieldsMap.get(Sobj)==null && GlobalDescribe.get(sObj)!=null)
        SObjectFieldsMap.put(sObj,new Set<string>());

        if(SObjectFieldsMap.get(sObj)!=null) // Some Objects may not have Describes 
        SObjectFieldsMap.get(sObj).addAll(GlobalDescribe.get(sObj).getDescribe().fields.getMap().keyset());
      }
      
Well thats pretty much it. Hope this helps, let me know if you need anymore clarifications on this or if you've got some thoughts on this. Happy Coding!