2

I want to know the previous value of Standard picklist called Status in Case Object for checking against a condition.I know we can achieve this using triggers.Is there any way we can do it via apex class.

  • 1
    I do not believe this is possible in apex class – SFDC Learner Dec 31 '15 at 9:53
  • 2
    If you need to have the prev value inside a VF controller, save the prev value on another variable and use the old value as a check whenever you do a post back form your page. If you are talking of a context that is not a VF page nor a Trigger, @Nilesh is right, this is not possible – Enrico Murru Dec 31 '15 at 10:13
  • when you say you want it in an apex class, do you mean an apex class called by a trigger? – cropredy Dec 31 '15 at 16:59
5

You can get most of what you want if you enable history tracking on your object, and set history tracking to track your target field.

There are some restrictions with history tracking (the default limit is tracking 20 fields at most, can't track formula fields), and it requires some work in your Apex class(es). It's also ridiculously hard to test code that depends on history tracking without breaking data isolation (as performing DML on test data does not currently cause history tracking records to be created).

If you can live with that, History tracking is the way to go.

  • Query the <sobject name>History object if you're working with history on a Salesforce Standard Object, or <custom sObject name>__History for Custom Objects.
    • If you had My_Custom_Object__c, the history object would be My_Custom_Object__History. In your case, you'll be querying CaseHistory

About the best you'll be able to do is something like the following query

List<CaseHistory> ch = [SELECT ParentId, OldValue, NewValue 
    FROM CaseHistory 
    WHERE Field = 'Status' AND ParentId IN :someIdList 
    ORDER BY CreatedDate DESC];

There's probably a way to use a subquery as a semi-join to more easily grab only the most recent history record for a given field and case (ParentId).

Other than that, it comes down to looping through the results and populating a Map of some sort (Map<Id, Map<String, Boolean>> would be one possibility. Case Id is the key of the outer map, Field name is the key of the inner map, and OldValue == NewValue gives you the value of the inner map).

If history tracking is not an option for you, there is another way. It's not seamless, and it pollutes your object schema, but it'll work.

This alternate method will work for nearly every field type. The biggest exception that I can think of would be lookup fields (if you want to grab data from somewhere up the relationship hierarchy from the old lookup value).

For the sake of giving a specific example, I'll work with your case where you're working on the Case object, and want the previous value for the standard Status field.

  • Create a new text field on your target object (Previous_Status__c)
    • Make sure your target users have read permission for this field. I'd recommend not giving anyone edit permission, and not putting the field on any layouts.
  • Create a new workflow rule on your target object, call it Record Previous Status or something like that.
  • Set the workflow evaluation criteria to be "Created, and every time a record is edited"
  • Set the rule criteria to "formula evaluates to true"
  • Use the ISCHANGED() formula function to detect the change in your target field (ISCHANGED(Status))
  • For the workflow action, create a new field update
    • Select the text field you created to hold the previous value of your target field (Previous_Status__c)
    • For specifying the new value, select "use a formula to set the new value", and use PRIORVALUE() to get the previous value (PRIORVALUE(Status))

Now, in your Apex classes, when you query your object, you'll be able to query both the original field and the prior value tracking field. You may need to typecast the previous value before making any comparison. You also might be able to create an additional formula field to do the comparison for you in some cases.

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.