Observer Pattern in Dynamics NAV 2016

As per my note on my previous blog on this topic, I will outline how to achieve something similar in NAV2016, but split into two bits. This is the first bit which is more generic, and follows the pattern from the standard system.

Before NAV2016, Codeunit 1 was the ideal place to put code to track all record changes, and there are two standard Codeunits which do exactly this: Codeunit 423 Change Log Management and Codeunit 5150 Integration Management (these two still have code in Codeunit 1 – I’m not sure why they haven’t moved to using Events yet, but I suspect they will).

In NAV2016 we have Events – which mean you don’t need to touch Codeunit 1, just subscribe to it.

So for the pattern you need one Table to store which tables you want to track. You could set this in code (as per Codeunit 5150) but I think a table is better.

Observable Table: 
"Table ID"        Integer  Object.ID WHERE (Type=CONST(Table))
TrackInsert       Boolean  [optional]
TrackModify       Boolean  [optional]
TrackDelete       Boolean  [optional]
TrackRename       Boolean  [optional]

And then one Codeunit with the following Event subscriptions (all pointing at Codeunit 1).

C/AL
LOCAL [EventSubscriber] OnDatabaseInsert(RecRef : RecordRef)
IF Observable.Get(TableId) AND Observable.TrackInsert THEN
//do something

LOCAL [EventSubscriber] OnDatabaseModify(RecRef : RecordRef)
IF Observable.Get(TableId) AND Observable.TrackModify THEN
//do something

LOCAL [EventSubscriber] OnDatabaseDelete(RecRef : RecordRef)
IF Observable.Get(TableId) AND Observable.TrackDelete THEN
//do something

LOCAL [EventSubscriber] OnDatabaseRename(RecRef : RecordRef;xRecRef : RecordRef)
IF Observable.Get(TableId) AND Observable.TrackRename THEN
//do something

LOCAL [EventSubscriber] GetTableTriggerSetup(TableId : Integer;VAR OnDatabaseInsert : Boolean;VAR OnDatabaseModify : Boolean;VAR OnDatabaseDelete : Boolean;VAR OnDatabaseRename : Boolean)
IF Observable.GET(TableId) THEN BEGIN
  IF Observable.TrackInsert THEN
    OnDatabaseInsert := TRUE;
  IF Observable.TrackModify THEN
    OnDatabaseModify := TRUE;
  IF Observable.TrackDelete THEN
    OnDatabaseDelete := TRUE;
  IF Observable.TrackRename THEN
    OnDatabaseRename := TRUE;
END;

The first four should be relatively clear, obviously if you don’t need to control which exact triggers you want to fire you can remove all the IF Observable.Track.. conditions.

The last one requires a bit of explanation. Basically Codeunit 1 calls GetTableTriggerSetup once per table per session, and it uses the result to determine whether it will call the OnDatabase triggers. If you don’t set the relevant boolean to TRUE, the OnDatabase trigger may not get fired at all.

I say “may not” as anything else listening to this Event (e.g. Change Log) may set the values to TRUE for this table, this is also why you should only ever set them to TRUE, and never set them to FALSE.

This also means that after you insert/change the record in the Observable Table, you may want to restart your NAV session to make sure that any changes you make actually fire the correct triggers.

That’s it! Pretty simple and very powerful. Hope you find it useful

Nikolai

Advertisements

2 thoughts on “Observer Pattern in Dynamics NAV 2016

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s