+ Start a Discussion
lnryanlnryan 

Dynamic Apex - setting field values help

Hi,

I get how to use dynamic apex to find out about elements and fields in an sObject and how to leverage that information to prepare SOQL statements, but i'm having trouble figuring out how to dynamically access or assign a field value on a record using dynamic apex. Can someone please help? Say I want to create a method that receives an incoming sObject and changes the Name to be a concatenated string based on a supplied list of fields in the object itself or its parents. How would I do this?

When I try
sobj.Name = ...
I get the error 'Field expression not allowed for generic SObject'

I have a number of places where i'd like to be able to trigger essentially the same pattern of behavior on multiple objects types...

Thanks in advance.
Best Answer chosen by Admin (Salesforce Developers) 
tmatthiesentmatthiesen
Code:
  //setting up a sample list of strings and sobjects
List<String> flds = new List<String>{'name','id','phone','accountnumber'}; List<sobject> recs = [select name, id, phone, accountnumber from account limit 10]; SObjectType objToken = Schema.getGlobalDescribe().get('Account'); DescribeSObjectResult objDef = objToken.getDescribe(); Map<String, SObjectField> fields = objDef.fields.getMap(); String newname = ''; for (sObject rec: recs){ if (rec.get('Name') != 'auto'|| rec.get('Name') != 'auto-name'){ for (Integer f=0; f< flds.size();f++){ newname = newname+fields.get(flds[f])+'||'; } system.debug(newname); rec.put('Name',newname); } } update recs;

 

All Answers

tmatthiesentmatthiesen
sobject sb = token.newsObject(); //you can get the token from a describe

sb.put(field, value);

or

sb.get(field);
lnryanlnryan
thanks, but how would that work if you needed to first specify the related object and then the field upon that related object?
tmatthiesentmatthiesen
not sure I understand.  You can leverage the describe to dynamically retrieve the sobjects and fields.  You can then dynamically create an sobject and set or get the necessary fields.
lnryanlnryan
i'm aware of the abstract capabilities; what i'm trying to figure out is the specific syntax for doing so over a list of incoming sObjects. The following is a simple case that doesn't extend beyond the primary object. It also does not work:

Code: /* This would take a list of records, a list of field names, and a delimiter and create a concatenated version as the name (useful, among other things, for junction objects where the name is really the combination of the two parent records ) */
 public static void standardName(sObject[] recs, String[] flds, String delim){
  String newname;
  for (sObject rec: recs){
   if (rec.get('Name') == 'auto'|| rec.get('Name') == 'auto-name'){
    rec.put('Name','');
    for (Integer f=0; f< flds.size();f++){
     newname = ((f+1)==flds.size)—rec.get('Name')+rec.get(flds[f]):rec.get('Name')+rec.get(flds[f])+delim;
     rec.put('Name',newname);
    }
   }
  }
  update recs; 
 }

 
i also tried
rec.getSObjectType().get('...');
rec.getSObjectType().getDescribe().get('...');
rec.getSObjectType().getDescribe().fields.get('...');

So what i'm asking, is what do I need to do differently to get it to work...and what would I need to do additionally to retrieve those field values if they were on a related object instead of the object itself?

Thanks for any assistance


tmatthiesentmatthiesen
//get object token - you should pass the globalDescribe to a Map if you need to retrieve multiple tokens    
SObjectType objToken = Schema.getGlobalDescribe().get('Account');        

//grab the describe
DescribeSObjectResult objDef = objToken.getDescribe();

//get the fields
Map<String, SObjectField> fields = objDef.fields.getMap();
//get the field token
SObjectField fieldToken = fields.get('Name');
//get the field describe - if necessary - there is a limit per request on field describes    
DescribeFieldResult selectedField = fieldToken.getDescribe();
lnryanlnryan
i'm confused. where in the example above is an actual record's field value retrieved? Are you saying that once i have that token

Code:
rec.fieldToken = 'something';

and 

rec.fieldToken1 = rec.fieldToken2+rec.fieldToken3;

 

should work? Thanks for the clarification...
tmatthiesentmatthiesen
Dynamically setting fields:

sobject.put(field,value);

So in your case:

sobject.put('name', concat_string);
lnryanlnryan
there's still a pretty crucial missing link in these explanations of how the fieldToken is used to get and set values on a pre-existing record. Perhaps if you have one, you could post a working piece of code that models this behavior? Thanks again for the help
tmatthiesentmatthiesen
Code:
  //setting up a sample list of strings and sobjects
List<String> flds = new List<String>{'name','id','phone','accountnumber'}; List<sobject> recs = [select name, id, phone, accountnumber from account limit 10]; SObjectType objToken = Schema.getGlobalDescribe().get('Account'); DescribeSObjectResult objDef = objToken.getDescribe(); Map<String, SObjectField> fields = objDef.fields.getMap(); String newname = ''; for (sObject rec: recs){ if (rec.get('Name') != 'auto'|| rec.get('Name') != 'auto-name'){ for (Integer f=0; f< flds.size();f++){ newname = newname+fields.get(flds[f])+'||'; } system.debug(newname); rec.put('Name',newname); } } update recs;

 
This was selected as the best answer
lnryanlnryan
thanks for the response. I've been able to lookup records directly on the record in question, but the proposed solution above does not work for fields on related objects. Any idea how to dynamically set both the related object (ie parent) and the field on that object to return?
rajesh k 10rajesh k 10
Hi,
       Actually Every time i create  fields and object using metadata api and i displayed all fields in an visualforce page Dynamiacally without using any fieldsets(Here object through URL will come).Here object related record is saved using schema methods,but this object related record fields(Here fields will come dynamically and add to visualforce page) information not saved in database.

Note:Here All fields in an visualforce page as editable fields.I give fields related information and click save only records only created related object, fields related information is not saved

How to save Dynamically comming fields(in an visualforce page) in Related Object Record Dynamically?

help me..........