8

I have searched and read through countless questions & answers here, scoured the interwebs, etc. and I cannot find out whether what I want to do is even doable, much less how. I don't know if I am searching for the wrong terms, looking past the answer, or just being stupid. (FYI: After being a developer on a different large on-premise CRM for almost 5 years, I am only approximately 8 months new to Salesforce; so go easy, please, if I am being stupid.)

Prelude

I have found countless ways to get the value of an sObjectField using a variable. E.g.,

Account a = new Account(Name = 'Test Account');
String n = 'Name';
String result = a.get(n);

// result == 'Test Account'

This can obviously be "genericized" using objects, lists, maps and whatnot; and then with for loops or other iteration, one could get multiple field values when the field names were not previously known.


Question

Can you do something similar to set a field value using a variable for the field name?


What I've Tried

a.n = 'New Account Name';

// Results in "Variable does not exist: n" error.
a.set(n) = 'New Account Name';
a.get(n) = 'New Account Name';
a.(a.get(n)) = 'New Account Name';
(sObjectField) a.n = 'New Account Name';
(sObjectField) a.get(n) = 'New Account Name';

// All result in "Expression cannot be assigned" error.

I've used Schema.SObjectType.Account.fields.getMap() and tried all sorts of permutations and combinations of things. (I didn't record all that I tried because I tried hacking at it over and over and can't remember everything.)

I've individually tried...

sObjectField n = Account.Name;
                 Account.Name.getDescribe();
                 Account.Name.getDescribe().getName();
                 Account.Name.getDescribe().getsObjectField();

... all followed by a.n = 'New Account Name';

(which honestly wouldn't really help since the Name part of those would also need to be a variable for it work in a real use case).

And all sorts of things with (), {}, and [] that obviously didn't work.


Use Case

In a test data factory class I was wanting to iterate a map that has field names and values (where the field names could be different every time) and then create an object with those field names and values. If I can't use a variable to set a field name, I'm going to have to go through and check every possible field name. That obviously makes for MUCH more code; and if we ever add new fields to that object and would want to be able to set those in a test, we would have to add those fields to this code.

1 Answer 1

11

The put(key,value) method on SObject does what you're looking for. Slightly modified example from the doc:

String fieldName = 'description';
Account acc = new Account(name = 'test', description = 'old desc');
String oldDesc = (String)acc.put(fieldName, 'new desc');
System.assertEquals('old desc', oldDesc);
System.assertEquals('new desc', acc.description);
2
  • 1
    That worked like a charm - thank you so much! Now I do feel stupid! Even though I didn't explicitly list it in my What I've Tried, I really thought that I had tried that. As I stated, I was hacking through a lot of different attempts; when I moved into an Execute Anonymous Apex window in Developer Console so that I could hack through them quicker, I lost track of everything that I had tried. I will now be able to make my trigger helper code MUCH more elegant, and make an even more useful test data factory. Thanks to you, I might be the (temporary) star of our small dev team!
    – Moonpie
    May 9, 2020 at 20:29
  • @Moonpie Test factory frameworks already exist: one two. There are more, these are mentioned often.
    – identigral
    May 9, 2020 at 21:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.