function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
mgodseymgodsey 

Using DescribeField methods to dynamically retrieve field API names and labels

I have a trigger on Opportunity that updates a text field on the Opportunity called WhatChanged__c. It's comparing the values on two related Opportunities and seeing if they are different. I need to reference the Field Label in the WhatChanged__c value, and I want to make it dynamic so that if we change any field labels/api names in the future the code will automatically handle the change.

 

Here is the relevant part of trigger:

 

//continue if there are cloned Opps moving into the pending stage
    if(!pendingClonedOpps.isEmpty()){
//get all the labels for Opportunity fields and put them in a map, keyed to the field api name String objectType ='Opportunity'; Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe(); Schema.SObjectType leadSchema = schemaMap.get(objectType); Map<String, Schema.SObjectField> fieldMap = leadSchema.getDescribe().fields.getMap(); Map<String, String> fieldAPIName = new Map<String, String>(); for(String fieldName : fieldMap.keySet()){ fieldAPIName.put(fieldName, fieldMap.get(fieldName).getDescribe().getLabel()); } for(Opportunity opp : pendingClonedOpps){ //List to store all of the names of fields that have changed List<String> Changes = new List<String>(); //get the related Cloned Opportunity record Opportunity clonedFromOpp = ClonedOppIDToClonedOpp.get(opp.ClonedFrom__c); if(opp.Buyer__c != clonedFromOpp.Buyer__c){ String fieldName = 'buyer__c'; String Label = fieldAPIName.get(fieldName); String oldBuyer = clonedFromOpp.Buyer__c; Changes.add(Label+': '+oldBuyer); } opp.WhatChanged__c = CSUtils.join(Changes, ' '); }

It's working, but the part I'm not happy with is the line String fieldName = 'buyer__c'. If the API name for that field ever changes, I will need to update the fieldName variable. Is there a way to dynamically get the API name, in a similar way to how I am getting the field name? Can I create a Map that stores <Field, String>? This is my first time working with Describe.field() methods so I think I'm confusing myself!

 

Any help is much appreciated! Thanks!

mgodseymgodsey

I got it to work, although if anyone has suggestions for another way, please feel free to chime in!

 

//continue if there are cloned Opps moving into the pending stage
    if(!pendingClonedOpps.isEmpty()){
        
        //get all the labels for Opportunity fields and put them in a map, keyed to the field api name
        String objectType ='Opportunity';
        Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
        Schema.SObjectType leadSchema = schemaMap.get(objectType);
        Map<String, Schema.SObjectField> fieldMap = leadSchema.getDescribe().fields.getMap();
        
        Map<Schema.SObjectField,String> fieldToAPIName = new Map<Schema.SObjectField,String>();
        Map<String, String> apiNameToLabel = new Map<String, String>();
        for(String fieldName : fieldMap.keySet()){            
            fieldToAPIName.put(fieldMap.get(fieldName), fieldName);
            apiNameToLabel.put(fieldName, fieldMap.get(fieldName).getDescribe().getLabel());
        }
                
        for(Opportunity opp : pendingClonedOpps){
        
            //List to store all of the names of fields that have changed
            List<String> Changes = new List<String>();
            
            //get the related Cloned Opportunity record
            Opportunity clonedFromOpp = ClonedOppIDToClonedOpp.get(opp.ClonedFrom__c);    
         
             if(opp.Buyer__c != clonedFromOpp.Buyer__c){
                String fieldName = fieldToAPIName.get(Opportunity.Buyer__c);
                String Label = apiNameToLabel.get(fieldName);
                String oldBuyer = clonedFromOpp.Buyer__c;
                Changes.add(Label+': '+oldBuyer);
            }      
 
            opp.WhatChanged__c = CSUtils.join(Changes, ' ');
      
        }

 

souvik9086souvik9086

Can check this thread.

 

http://boards.developerforce.com/t5/Apex-Code-Development/Retreive-object-schema-and-related-field-api-names-using-apex/m-p/676953#M125866

 

If this post is helpful please throw Kudos.If this post solves your problem kindly mark it as solution.

Thanks

Tabrez AlamTabrez Alam
Hi mgodsey

I'm working on a trigger on contact to achieve the functionality of workflow field update
I've created a custom workflow to created a task
I need help in getting the field dynamically & assigning the value to it dynamically
I've checked with system.debug
I'm getting the field api name & the value to assign that field but i'n not getting a way to assign that value to that field.
I've tried this
a.put(objRuleFieldUpdate.Field_Udpate__r.Field_to_Update__c, objRuleFieldUpdate.Field_Udpate__r.Value_to_Update__c);

The trigger gets saved but the it give the error when i try to created contact

this is the code that I'm using to assignt the value to the field
 for(Rule_Field_Update_JO__c objRuleFieldUpdate : objRule.Rule_Field_Update_JO__r)
                {
                    if(isInCriteria==True)
                    {
     a.put(objRuleFieldUpdate.Field_Udpate__r.Field_to_Update__c, objRuleFieldUpdate.Field_Udpate__r.Value_to_Update__c);
                    }
                }

objRuleFieldUpdate.Field_Udpate__r.Field_to_Update__c ------- this is the field api name
objRuleFieldUpdate.Field_Udpate__r.Value_to_Update__c ------- this is the value that I need to assign to the field

This is the error that I'm getting to when I created a contact.

Apex trigger ContactFieldUpdate caused an unexpected exception, contact your administrator: ContactFieldUpdate: execution of BeforeInsert caused by:System.AssertException: Assertion Failed: Expected: department, Actual: FieldUpdate: Trigger.ContactFieldUpdate: line 221,column 1
It gives the error on this line
a.put(objRuleFieldUpdate.Field_Udpate__r.Field_to_Update__c, objRuleFieldUpdate.Field_Udpate__r.Value_to_Update__c);

Please help
Thanks in advance.