Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
Showing results for 
Search instead for 
Did you mean: 
Like standard objects, you can also create change history for custom objects without much coding, but with few simple configurations. Let us see how to implement it :

  1. Business Object - Enable business object to track changes at Field/Node level.

  2. User Interface – Reuse existing embedded component to show the change history on UI.

  3. Deploy Business Configuration.


  1. It is very simple to enable the business object to track changes. It is done just by adding annotation [ChangeHistory]. System will automatically track the changes done for the marked elements. You can add the annotation at:

    • Business object level: You can use at business object level if you want to track changes for all fields under root node and association under root node. Please note: Sub node elements are not tracked.

    • Element level:  You can also choose to track selective fields instead of all the fields in business object by adding change history tag for specific fields. Of course, the transient fields are not supported as they are not persisted.

    • Node level: All the elements under the sub node are tracked.

    • Association: Association based on alternative keys can be tracked.

    Make sure to save and activate the business object after adding the annotation.

  2. Now that the business object is enabled to record change history, let us see how to enable this on UI.

  • We will use standard embedded component, SAP_BYD_APPLICATION_UI/Reuse/ChangeHistory/ChangeDocuments_EC. Drag and drop to our TI facet as shown below:


  • Let us bind the embedded component, but before binding let us prepare the out port and parameters. Make sure, you have the node ID from root node bound in the data model.


  • Create an outport and pass the nodeID as parameter.


  • Let us go ahead with binding, click on the bind button on embedded component, and create a simple navigation flow.Under Navigation Configuration ->Navigations create new and map the outport & inport from source and target respectively and bind the parameters. As shown below.


  • Let us maintain few parameters, on the properties of embedded component.

    • Business Object Name : Name of the object where we enabled the change history.

    • Business Object namespace : you can find this UI data model.

    • ECO Name : Same as business object Name

    • ECO Namespace : Same as business object name space.

    • IsAttributeSearchEnabled = X


  • The last step is to make sure that when the facet is loaded the out port needs to be fired. create an Event handler with operation FireOutport and select the outport configured in above step.

  • Assign the event handler to onclick even of facet.


3.  Now that UI part is done, let us make sure that the BC deployment is done. This a very important step. Make sure, the business object is saved and active.

  • From solution explorer, right click on the solution.

  • Select "Deploy Business Configuration".


And finally, we can test: You can create new instance save it, open the TI make some updates, save, navigate to changes facet.



Change History API:

You can also get the change history in backend, using standard API.

ChangeHistory.Read – it provides you the all changes logged for a Business object instance.

You can get specific changes by applying more filter based on Node, From-To date, Changed By user.

Please note that, the Read will only work if standard object has already been enabled to track changes and log it. and for custom object if the annotation is added as shown in above section.


Import Parameters:

BusinessObjectName [Mandatory] – Name of business object along with the namespace.

NodeID [Mandatory] – UUID of the Root node instance

NodeName [Optional] –  To filter specific node changes, you can specify the name of node.

FromChangeDateTime [Optional] – From date time in GDT format

ToChangeDateTime [Optional] – To date time in GDT format

ChangerUUID [Optional] - To filter further based on Changed by specific user


Export structure:

ElementName - Name of the element whose value was changed.

NewContent - New updated value

OldContent - Old value

ChangeDateTime - Time stamp record when the change was triggered.

ChangeIdentityUUID - UUID of the user who triggered the modify.

ChangeIdentityName - Name of the user who triggered the modify

NodeUUID - UUID of the node

NodeName - Name of the node where element is part of.

import AP.Common.GDT as GDT;

var BOName = "AP.CRM.Global:Opportunity";
var NodeID : GDT:UUID;
NodeID = this.UUID;
var NodeName = "Root";
var FromDateTime : GLOBAL_DateTime; //2016-04-19T15:30:00Z
var ToDateTime : GLOBAL_DateTime; //2017-04-19T15:30:00Z
var ChangedByUUID = Context.GetCurrentIdentityUUID();

var OppChange = ChangeHistory.Read(BOName,NodeID,NodeName,FromDateTime,ToDateTime,ChangedByUUID);