Find your content:

Search form

You are here

Refreshing Formula Fields Dynamically (without save)

 
Share

I have an "invoice" custom object which has a couple of summarising formula fields in. I also have a complicated and dynamic visualforce page for building the invoice objects.

As the user is completing this form, different areas are dynamically updated to show "latest" values. This is all fine where I am copying data about or performing bespoke lookups and maths, but - in what is really the simplest case - a formula field, I can find no way to get the value to update, without performing some weird cyclic save + reload of the whole object.

This is inappropriate for a couple of reasons (the object should not be saved until the invoice is complete + accepted) and the other option I have found online is to spoof the value by duplicating my formula field maths into the custom controller and re-executing them there - also unacceptable from a code/logic location/duplication perspective.

Is there anyway to "force" an object/page to recalculate it's formula fields, either through standard or extended controllers?


Attribution to: Simon Lawrence

Possible Suggestion/Solution #1

Good news everybody!

This has just been added to the Winter '16 release. It can be used like this:

someSObject.recalculateFormulas();

From the Documentation:

Recalculates all formula fields on an sObject, and sets updated field values. Rather than inserting or updating objects each time you want to test changes to your formula logic, call this method and inspect your new field values. Then make further logic changes as needed.

See https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_sobject.htm

Note that this method doesn’t recalculate cross-object formulas, only 'local' formula's referring to the record itself!


Attribution to: Willem Mulder

Possible Suggestion/Solution #2

Unfortunately not. Formula fields aren't stored in a Salesforce record, rather the formula definition is executed at the time that the record is queried from the database. So its the act of retrieval that populates the field based on the formula.

Another option is to save the record, query it from the database including the formula fields, capture the formula fields into controller properties or similar and then delete the record. Its clunky but it will allow you to get at the formula fields without leaving a half-populated record in the database.


Attribution to: Bob Buzzard

Possible Suggestion/Solution #3

Here is one approach along with a code example that shows a hacky but effective way to evaluate formulas before saving the record, https://jsonhammerle.wordpress.com/2014/07/21/evaluating-a-salesforce-formula-from-a-custom-visualforce-page/


Attribution to: Jason Hammerle

Possible Suggestion/Solution #4

In order to "reload" an object and to have the formula fields recalculated without querying it explicitly through SOQL, it is also possible to call the reset() method on the standard controller. Doing so any uncommitted changes on that object will be discarded. So usually the call to reset() should happen after updating the object. See: https://www.salesforce.com/us/developer/docs/pages/Content/apex_ApexPages_StandardController_reset.htm


Attribution to: Daniel Seiler

Possible Suggestion/Solution #5

As noted elsewhere, the sObject.recalculateFormulas() does exactly this; unfortunately, however, that feature currently has a bug that makes it much less useful than it could be.

There is a Known Issue regarding this bug, but essentially the problem is that if any non-updatable fields are in the SOQL query that the recalculateFormulas() will be referencing, it will fail. This includes built-in fields (IsDeleted, CreatedDate, etc.) and custom fields, as well as fields referenced from other sObjects in the SOQL query.


Attribution to: Richard Wood
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/3814

My Block Status

My Block Content