[SalesForce] Copy field values from one object to another

I have Obj1 and Obj2 both having 20 fields of same API Names. For while creating Obj2 records I want to copy all those field values to Obj1. Is there any shortcut to do the coding instead of writing the whole thing.

Like below is the code.

    for (Integer i = 0; i < srList.size(); i++ ) {
         Database.SaveResult sr = srList[i];
            if (sr.isSuccess()) {

                 //Alstitem.External_ID_vod__c = actID+'-'+key;
                 for(Business_Plan_abv__c j: accMap.get(BpToInsert[i].Territory_Name__c))
                 { 
                 Business_Plan_Approval_Process_Data_abv__c bpdata = new Business_Plan_Approval_Process_Data_abv__c();
                 bpdata.Business_Plan_Approval_Process_abv__c= sr.getId();  
                 bpdata.Territory_abv__c= BpToInsert[i].Territory_Name__c;
                 bpdata.External_Id_abv__c = j.Account_abv__c+'_'+sr.getId();
                 bpdata.Account_abv__c = j.Account_abv__c;
                 bpdata.City_abv__c = j.City_abv__c;
                 bpdata.Comments_abv__c = j.Comments_abv__c;
                 bpdata.Call_Priority_Decile_abv__c = j.Call_Priority_Decile_abv__c;
                 bpdata.Call_Activity_Avg_of_last_3_quarters_abv__c = j.Call_Activity_Avg_of_last_3_quarters_abv__c;
                 bpdata.Business_Planner_Flag_abv__c = j.Business_Planner_Flag_abv__c;
                 bpdata.Biologic_Index_last_6_months_abv__c = j.Biologic_Index_last_6_months_abv__c;
                 ......................?? Instead of writing like this, is there any shortcut way to copy field values.
}
                 insbpdata.add(bpdata);
            }
        }

Best Answer

This is a good use case for Field Sets or, if you've concerned that some values or field names may change a bit in either side, Custom Metadata.

I will walk you through Field Sets.

Field Sets

First, create a field set in Business_Plan_abv__c and call it something like Approval_Process_Data_Fields. Put all of the fields in it that you want to copy over.

Then, in your code you can do something like this:

Schema.FieldSet fieldSetToCopy = Schema.SObjectType.Business_Plan_abv__c.FieldSets.Approval_Process_Data_Fields;
for (Schema.FieldSetMember dataField : fieldSetToCopy.getFields()) {
  bpdata.put(dataField.getFieldPath(), j.get(dataField.getFieldPath()));
}

This assumes that the fields will always share a name. Once that is no longer the case, this solution is unusable without some hacking. Also, note that there is no compile-time documentation about that requirement anywhere in the code - you'd need to write a test for all the fields in that FieldSet.

Custom Metadata

A more robust way to deal with this is Custom Metadata.

Declare a custom metadata type with two Entity-Field pairs. One pair is the "From" and one pair is the "To".

You can then map each field in the Custom Metadata records (and possibly some transformation information). In your code, you'd loop through the Custom Metadata records, doing something like:

for (Mapping__mdt mapping : [SELECT From_Field__c, To_Field__c
                             FROM Mapping__mdt
                             WHERE From_Entity__c = :Schema.SObjectType.Business_Plan_abv__c 
                             AND To_Entity__c = :Schema.SObjectType.Business_Plan_Approval_Process_Data_abv__c
                             AND Use_Case__c = 'something']) {
  Object oldData = j.get(mapping.To_Field__c);
  bpdata.put(mapping.From_Field__c, oldData);
}

You'll still need tests, of course - and probably validation rules to ensure that the mapped fields are the same type, but you can here expand the mapping to include a transformation if needed (I suppose you can do that with FieldSets, too).

Related Topic