PRIORVALUE
The PRIORVALUE function gets the previous value of a field that is the same value if the record is being created, or the real previous value if the record is being updated.
You could use it to prevent users from updating important fields in specific conditions, such as changing the opportunity amount once it is closed or transition a case to a Closed status if the previous status is Cancelled:
AND(
ISPICKVAL( PRIORVALUE(Status), ‘Cancelled’),
ISPICKVAL(Status, ‘Closed’)
)
What is the ISPICKVAL value? When dealing with picklists, you should use this function to check whether a picklist list field equals a certain value:
AND(
PRIORVALUE(Amount) <> Amount,
IsClosed
)
The preceding opportunity’s example is simpler as it states that if the Amount field value changes and the opportunity is closed, the error is triggered.
This simple control can be replaced with the ISCHANGED() function that returns true if the value of a given field is changed.
Picklist management
Picklist fields are a basic way to restrict user input: they deliver a default set of allowed values using a select list. From the user interface, it is impossible to set a different value than the ones listed, so you have a guarantee that no invalid value is stored.
This is not technically true, though. The picklist type field is just a UI-contained text field, but if it is not enforced, then you can set an invalid value by using other tools (such as REST APIs or Apex code).
Let’s try managing a picklist field.
Let’s create an Invoice Type picklist list field on the Case Detail object and uncheck the Restrict picklist to the values defined in the value set checkbox:
Simple picklist creation
Once the file is created and added to the page layout, you’ll be able to create a new Case Detail record with the new Invoice Type field.
Let’s do some developer work now! Open the case detail that we created in the previous chapters and get the Salesforce ID from the URL: your browser URL bar should look something like this:
URL of a Case Detail object
Copy the Salesforce ID to the clipboard; we’ll be using it shortly.
Salesforce IDs come with 15 or 18 digits. Don’t panic if you see a 15-digit ID if you expect an 18-digit one; most of the features work with both versions of the same value.
If you are in doubt, check whether the first 15 characters have the same characters.
For more information about Salesforce IDs, refer to https://help.salesforce.com/articleView?id=000004383&language=en_US&type=1.
Let’s open the Developer Console by going to Settings | Developer Console:
Developer Console link
This will open up the following window:
Developer Console window
This magic window is used by developers for quick and dirty stuff, such as Apex classes/trigger creation, query execution, Apex test execution, and more, but there is no reason why an administrator shouldn’t use it too.
We want to show that we can update an unrestricted picklist field with whatever value we want.
Go to Debug | Open Execute Anonymous Window on the Developer Console menu. In the opening text box, let’s write the following Apex code:
1. Case_Detail__c detail = [Select Id, Invoice_Type__c
2. From Case_Detail__c
3. Where Id = ‘a011i0000075ZkEAAU’];
4. detail.Invoice_Type__c = ‘Invalid Invoice Type’;
5. update detail;
What’s happening here?
- Lines 1-3 make an SOQL query on the Case Detail object, getting the ID and Invoice Type fields: since we want to update a field, only the ID field is necessary for the query, but, for the sake of this example, we are showing how an SOQL query can be composed.
- Line 4 takes the returned record and sets the new value for the Invoice Type field.
- Line 5 executes the update of the record.
Think about it. This is exactly what you do using the user interface: open a specific record by its Salesforce ID, click on the Edit button, change field values, and click on the Save button. The following diagram shows what your script should look like on the Execute Anonymous window:
Execute Anonymous Apex script
Are you ready for the magic to take place? Click on the Execute button.
If you forget a character or copy the script incorrectly, you may get a pop-up error showing the error message. If that happens, don’t worry—you have only mistyped the script.
Don’t worry about it. The life of a developer lies between a successful class save and a compilation error because of a forgotten single semicolon character in a thousand lines of code. If everything worked okay, you won’t see any message. Go back to your Case Detail page and refresh the page to see something similar to the following:
Case Detail updated with an unlisted picklist value
Feeling like a hacker, huh?
If we edit the record and open the Invoice Type picklist, we still get the Invalid Invoice Type value, but if we select an allowed value and save the record, the disallowed value disappears from the list and everything returns to its default status.
I hope you enjoyed this developer regression. Why would you need this behavior? You want an external system to be able to create a case detail with a specific Invoice Type value that shouldn’t be allowed for your users (for example, an external system that handles reimbursements).
What if you want the Invoice Type field to have the same values as another custom object’s picklist (for example, the Invoice object with a Type field)? You have two choices: replicate the values or use a global value set, the global picklist value set.
You can create a global value set by going to Setup | Objects and Fields | Picklist Value Sets, or jump to your newly created picklist field and promote it to a global value set by editing the field and clicking on Promote to Global Value Set:
Promoting a picklist list to a global value set
But to promote a global value-set, you need to restrict values to the origin picklist.
Select the Global Value Set label/nameed voilà, the picklist field will be related to a new global value set:
Picklist field related to a global value set
A global picklist is restricted by nature, so no one can add new values using Apex or APIs.
You can have up to 500 global value sets in an org, and each can have up to 1,000 active values. The length per value can be up to 255 characters.