For the Tracking purpose I need the last modified date of a field(any datatype). I know there is last modified date system field for a record but I need last modified date of a field.

My Questions are,

1. Is it possible to get the last modified date of particular field?

2. If it is possible then how can I use that last modified date of particular field in Apex Class?

  • 2
    u hv to either enable field tracking for that field or create a new custom field and use a workflow field update to store the last modified date of your field Nov 25, 2015 at 10:58
  • if i enable field tracking from object then how can i use in apex class Nov 25, 2015 at 11:27

1 Answer 1


Is this possible?

As Vamsi Krishna mentioned in a comment on your question, this is possible.

The two methods he mentioned are:

  1. Enable field history tracking for the field (or fields) that you wish to track
  2. Create a new custom (datetime) field, and create a workflow rule that updates this new datetime field every time your target field is modified

Method 1 is the easiest to set up, and scales up to 20 fields (this is a limit imposed by Salesforce). It takes a little more work to pull the information for use in an Apex class, and has another important limitation that I'll get to later.

Method 2 is the easiest to use in an Apex class, but takes longer to set up and doesn't scale well at all (you need a new custom field, a new workflow rule, and a new field update for each field you want to track in this manner). I wouldn't recommend this to anyone unless you only need to track one field. Even then, this method incurs more technical debt than I'm comfortable with.

How to use tracked field history

Making use of field history tracking information in an Apex class requires a query. For standard objects (Account, Case, Contact, etc...), the object you'll be querying is simply <sObjectName>History (AccountHistory, CaseHistory, ContactHistory, etc...) For custom objects, you'll be querying the respective __History object (the history object for My_Custom_Object__c is My_Custom_Object__History). You just replace __c with __History

The history tracking object always comes with the same 8 fields, CreatedById, CreatedDate, Field, Id, isDeleted, NewValue, OldValue. The 8th field is a lookup to the object that history is being tacked on. For Custom Objects, this appears to always be ParentId. For Standard Objects, this is <sObjectName>Id (AccountId, CaseId, ContactId, etc...)

Assuming you're working in a Trigger, or otherwise have access to Trigger Context Variables, your query would end up looking like this

[SELECT ParentId, Field, CreatedById FROM My_Custom_Object__History WHERE ParentId IN :trigger.newMap.keySet()]

Now, the problem with making business logic depend on tracked field history is that it is currently impossible to insert data into the history object in a unit test. You can't insert directly into history objects, and field history is not tracked in unit tests (even if the field is set up for history tracking).

You could manage to test the logic that depends on field history by wrapping your history query inside an if(test.isrunningtest()), and providing your own 'history' records in your test, but this limitation was a dealbreaker for me.

The other limitation is that you can't track field history on formula fields, autonumber fields, or rollup summary fields.

Another option

To get around the limitations of standard history tracking (if you need to track more than 20 fields, track a formula field, or want to reasonably test your code), you'd need to use a different method than the two listed above:

  1. Create your own Custom History object, as well as an interface to use it

This option is more work up front, but gives you the most freedom. I've done this in my org so that the interface to my custom History__c object is sObject agnostic, and only requires a single line of code to use in my Update triggers.

Adding or removing fields from my Custom History tracking is a matter of updating a fieldset (which can be done without a deployment).

Adding a new sObject to my Custom History tracking requires a new lookup field on my custom History__c object as well as a new fieldset on the newly tracked object.

  • 1
    N.B. With separate paid option Field Audit Trail, you can track up to 60 fields and for longer than 18 months
    – cropredy
    Nov 26, 2015 at 0:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .