Contact
Back to the blog

Recalculate formulas on the fly with the new Formula class – Salesforce Winter ’20

Sep 23 · min read

Winter 20 is full of low-key goodies that can make our life easier. Along with the Lightning Message Service, Salesforce is now introducing the Formula class in the System namespace.

In the old age of Apex (back in 2017 or so), when we created a new sObject and wanted to retrieve the values for its formula fields, we had to re-query the Database. This made sense, as formulas are calculated on read so we had to actually read the data to see those values.

After much begging, Salesforce finally gave us the recalculateFormulas method in the sObject namespace. It was great, except that it had a huge caveat: Cross-Object formulas were not allowed.

Finally, in Winter 20, we can say goodbye to our formula recalculating problems and really save those SoQL limits. Behold, the Formula class.

The Formula class finally gives us the ability of feeding it a list of sObjects and have all of their formulas recalculated on the fly without having to query. Here is how it works:

I wrote a test class for this, since we can use the assert functionality to quickly prove our results. That means that first we have to set up some data. We also prove that the formulas are, as expected, not calculated nor read until I query.

 

List<Account> testAccounts = new List<Account>();
testAccounts.add(new Account(Name = 'One'));
testAccounts.add(new Account(Name = 'Two'));
insert testAccounts;

Contact testContact = new Contact(LastName = 'Contact', AccountId = testAccounts[0].Id);
insert testContact;

System.assertEquals(null, testContact.AccountNameViaFormula__c, 'Should be null, formula is not evaluated yet.');

testContact = [
        SELECT Id,
        AccountNameViaFormula__c
        FROM Contact
        WHERE Id = :testContact.Id
        ];

System.assertEquals('One', testContact.AccountNameViaFormula__c, 'Should be the name of the first account since the formula is evaluated on read.');

 

Well, that was nice…. but let’s see some magic happening. I will now, on the fly, repoint the contact to a new account and execute the new method.


// Change the associated account in memory only.
testContact.AccountId = testAccounts[1].Id;
List<FormulaRecalcResult> results = Formula.recalculateFormulas(new List<Contact>{
        testContact
});

System.assertEquals('Two', testContact.AccountNameViaFormula__c, 'Should be the name of the second account since the formula is evaluated using the Formula Class.');

System.assertEquals('Two', results[0].getSObject().get('AccountNameViaFormula__c'), 'Should be the name of the second account since the formula is evaluated using the Formula Class.');

 

Note how there are two possible methods to see the results. This method updates the objects passed, but also returns a list of FormulaRecalcResult records that I can use to dynamically read those updated formulas. Really simple, really elegant and really cool.

 

Alas, not all is 100% perfect (although it still is really good!). I am very demanding and want formulas to be able to calculate on objects that are not yet in the DB. Understandably, Apex does not like this. Not so understandably, however, is that we get a nasty gack (aka: “Salesforce System Error” with a string of numbers) when we try it, and we can’t even try-catch it.

 

So, for those of you following at home, the snippet below will crash and burn. You should try it out to see it in action, but keep it out of any production environment. That catch block is not going to be hit… so beware.


//This will error out
Account unwrittenAccount = new Account(Name = 'Three');
testContact.Account = unwrittenAccount;

try {
    List<FormulaRecalcResult> results2 = Formula.recalculateFormulas(new List<Contact>{
            testContact
    });
    System.assertEquals('Three', testContact.AccountNameViaFormula__c, 'Should be the name of the third account, if this works. Unfortunately, it errors out');
} catch (Exception e) {
    System.assert(true, 'Would be nice if we were able to at least hit this line');
}

 

In summary, the Formula class is a really cool new addition to Apex, and will allow us to save time and limits on SoQL queries when dealing with formulas. I know I will be using it frequently in my projects.

Note: A special thanks to Trieste LaPorte from our friends at Foglight Solutions for the collaboration to get this new feature evaluated.

 

You can find the full code used in this article in this repo: https://github.com/TheCoderyIO/Winter20Release

 

ABOUT THECODERY

theCodery understands the challenges in modern tech stacks. We have developed a personalized approach for each Salesforce Cloud implementation while leveraging our deep been-there-done-that and best-practice expertise to ensure you get the most value from your Salesforce deployment.  We take an agile approach with all development, optimization, and integration projects.  Whether you are trying to broaden your engineering and development capabilities, reduce technical debt, integrate tools you are unfamiliar with, or create new applications, theCodery has a proven track record of solving problems and streamlining complexity.

If you have any questions for theCodery about our team, our process, or the clients, please reach out to us at: https://www.thecodery.io/contact-thecodery

theCodery: Accelerate your time-to-value on Salesforce with a trusted partner that delivers scalable architectures that are tailored to delight your customers.

Other Articles by this Author

theCodery’s Dreamforce Recap – 5 Sessions We Found Most Inspiring theCodery’s Dreamforce Recap – 5 Sessions We Found Most Inspiring
Dreamforce 2021 was held in San Fransisco on September 21st-24th. It was a flurry of presentations, meetings, and activities all centered around the Salesforce ecosystem. Th...
5 min read
We Make Migrating from Klaviyo to Marketing Cloud Easy We Make Migrating from Klaviyo to Marketing Cloud Easy
It may look like a mountainous task from the outside, but the integrations experts at theCodery made it look easy. Learn how we tackled the mountainous task of migrating an ...
6 min read
Is Your Salesforce Driving Operations Or Is It In Need Of An Operation? Is Your Salesforce Driving Operations Or Is It In Need Of An Operation?
A great Salesforce system is constantly evolving to increase performance and drive organizational change. A great Salesforce system is not exclusively consumed with just fix...
5 min read
Salesforce Summer 21’ Release Notes Salesforce Summer 21’ Release Notes
Summer 21’ is just around the corner with releases starting across Salesforce instances as soon as May 15th and deploying to all Salesforce orgs by June 12th...The team at t...
5 min read
theCodery Supports Autism Awareness Month theCodery Supports Autism Awareness Month
Here at theCodery, we are part of a program called Pledge 1%. “Pledge 1% is a global movement that encourages and empowers companies of all sizes and stages to donate 1% of ...
3 min read
What Sets theCodery Apart From Other Salesforce Partners? What Sets theCodery Apart From Other Salesforce Partners?
What sets us apart from every partner that I’ve worked for (or cleaned up after) wasn’t pointed out to me during the interview process, employee orientation, or a pep-rally....
5 min read

Get a {FREE} Consultation Now!

LET'S TALK!