You may need to track changes in a table or data entity for your own data staging or logging purposes. AIF framework has a change tracking feature which uses SQL server stored procedures to track data changes in AX tables, which is also the standard change tracking used by the DMF (DIXF) framework to handle incremental push of data. Implementation is as easy as below. Create a data entity (or a Query) for your source AX table and initialize DB tracking on your data entity using the code below (As of writing, in D365 FO Spring 2018 release) :

class AIFChangeTrackingInit
{
    public static void main(Args _args)
    {
        AifChangeTrackingScope scope = 'ANDVisitScheduleTrackingScope';
        DictDataEntity dictEntity   = new DictDataEntity(tableNum(ANDVisitScheduleEntity));
        boolean		isSuccess = false;
        AIFSQLCDCENABLEDTABLES  ctEnabledTables;

        new AifChangeTrackingPermission().assert();
        aifchangetrackingconfiguration::initialize();
        isSuccess = AifChangeTrackingConfiguration::enableChangeTrackingForDataEntity(scope,dictEntity,true, AifChangeTrackingType::SqlChangeTracking);
        info(strFmt("Is success : %1", isSuccess));
    }
}

Check if the initialization is successful from the infolog message, then insert, update or delete records in your source table for testing :

CaptureWSTrack.PNG

To list the changes, run the job below :

class AIFChangeTrackingTest
{
    public static void main(Args _args)
    {     

        DictDataEntity dictEntity   = new DictDataEntity(tableNum(ANDVisitScheduleEntity));

        AifChangeTracking       aifChangeTracking;
        AifChangeTrackingTable  changeTrackingTable;

        new AifChangeTrackingPermission().assert();

        aifChangeTracking = AifChangeTracking::constructFromDataEntity(dictEntity, '', AifChangeTrackingType::SqlChangeTracking);
        changeTrackingTable = aifChangeTracking.getChanges(DateTimeUtil::utcNow());

        while select changeTrackingTable
        {
            info(strFmt("Changed record : %1, type : %2 ", changeTrackingTable.KeyField_RecId, "Insert/Update"));
        }

        changeTrackingTable = aifChangeTracking.getDeletes(DateTimeUtil::utcNow());

        while select changeTrackingTable
        {
            info(strFmt("Deleted record : %1, type : %2 ", changeTrackingTable.KeyField_RecId, "Delete"));
        }
    }

}

You will see the results of change tracking :

CaptureDbTRack.PNG

If you run the job once again, it will only show you the changes that are done after the previous retrieval process. This way it only picks up the incremental data updates, making it suitable for staging and data synchronization.

 

[adinserter block=”9″]

 

 

 

6 thoughts on “D365 FO: How to track data changes with AIF change tracking

  1. Thanks for this post,

    I tried to implement this functionality on my dev-vm and all works fine! But I have some trouble in customer tier-1 vm. Change tracking doesn’t return any records from method
    changeTrackingTable = aifChangeTracking.getChanges(DateTimeUtil::utcNow());
    Did some one know the root of this issue?

    P.S. Im enabled changeTracking on dataEntity

    Kind regards,
    Roman

  2. Hi, this post is a bit old and that functionality might be depreciated, best is to check it with Microsoft support. If it is depreciated, only alternative left is FO database logging feature since alerting events are also depreciated.
    There are requests made to Microsoft to add a generic/extensible X++ DB changes tracking..

      1. Hi Nick, when MS removed eventing methods my colleagues from HSO Innovation team and many other developers had a big discussion in the Yammer group for a replacement feature. This is a highly needed feature but unfortunately it is not added yet. MS says “why not insert/update methods?” but they are not useful because you cannot use them for generic tracking and they are often skipped via X++ code allover in the existing functionality.
        So I still use Database Log for tracking.
        I use myself

Leave a Reply

Your email address will not be published. Required fields are marked *