Nav 2016 Events and Workflow Walk Through – 2

This is the second of a multi part series on Nav 2016 events and workflows. This post will be a introduction to subscribing to built in events.

First part : What are events and the advantages they provide.

Second part: What are the builtin events and how to subscribe to events.

Third Part: Creating event subscribers

Fourth Part : What are workflows and how to make a workflow step

Fifth part: Making a workflow response

Sixth Part: Assigning workflow step and response combinations

Seventh Part: Assigning workflow step predecessors

Eighth Part: Putting it all together

Built in Published Events

Base Nav provides a lot of built in events that you can tap into. Every table and page has a standard list of events. Some of the larger codeunits have some built in ones as well. For tables, almost all the standard triggers have a corresponding event. Most triggers actaully have two, one before the trigger is about to fire, and one after. Important note about trigger events is that they cannot be raised programmatically. That is to say you cannot, through code explicitly call/raise the event. The event only happens when that table trigger happens. Some common table trigger events are:

OnBeforeDeleteEvent(VAR Rec: Record, RunTrigger: Boolean)

OnBeforeInsertEvent(VAR Rec: Record, RunTrigger: Boolean)

OnBeforeModifyEvent(VAR Rec : Record, VAR xRec : Record, RunTrigger : Boolean)

OnBeforeValidatieEvent(VAR Rec : Record, VAR xRec : Record, RunTrigger : Boolean; CurrentFieldNo : Integer)

OnBeforeRenameEvent(VAR Rec : Record, VAR xRec : Record, RunTrigger : Boolean)

All these events also have a corresponding  “OnAfter…Event”. Its up to you to decide if you want your subscriber to run before or after the code within the trigger. As you can see, all these events have a few parameters. The two common among all of these are the record “Rec” and the boolean “RunTrigger”. The Rec is the table record that is currently being affected. The “RunTrigger” is there to let you know if the code inside the table trigger was ran or not.  The “CurrentFieldNo” parameter is there so you know what field got validated, or is about to be validated.

Page events are very similar:

OnBeforeActionEvent(VAR Rec : Record)

OnBeforeValidateEvent(VAR Rec : Record, VAR xRec : Record)

These two events have a corresponding “OnAfter…Event”, the rest don’t.

OnAfterGetCurrRecordEvent(VAR Rec : Record)

OnAfterGetRecordEvent(VAR Rec : Record)

OnOpenPageEvent(VAR Rec : Record)

OnClosePageEvent(VAR Rec : Record)

OnQueryClosePageEvent(VAR Rec : Record, VAR AllowClose : Boolean)

OnDeleteRecordEvent(VAR Rec : Record, VAR AllowDelete : Boolean)

OnInsertRecordEvent(VAR Rec : Record, BelowxRec : Boolean, VAR xRec : Record, VAR AllowInsert : Boolean)

OnModifyRecordEvent(VAR Rec : Record, VAR xRec : Record, VAR AllowModify : Boolean)

OnNewRecordEvent(VAR Rec: Record, BelowxRec : Boolean, VAR xRec : Record)

Most of these triggers will run after the actual action was preformed. For example, if you tried to delete a record from a page, the table “OnDeleteRecord” trigger would fire first. And then your event subscribers would run. A lot of the parameters look similar to the table events. Rec is still the table record that is being effected. “AllowClose” is there to let you know if the code in the “OnClose” trigger was called. The “AllowDelete”, “AllowModify” and “AllowInsert” are similar in that they will be true if the “OnDelete/Modify/InsertRecord” trigger was successful or not, and false if the record cannot be deleted, modified, or inserted. “BelowxRec” will be true if the new record is inserted after the end of the table (xRec).

For a full list of table and page events check out the MSDN page. We will be referring back to this in the next post as well.

The last type of built in events are codeunit events. Some are global opperations, such as OnCompanyOpen. Others are more context sensitive, such as OnBeforePostSalesDoc. In any case, these events can be changed if you want. I would advise against it as you could be breaking a lot more than you think. Each one of these events is special in its own way. If you want to learn more about these types of events, find them in the code. Most are in codeunit 1 or in the posting codeunits.


A bit of Order

The full order of actions happen like so:

Press the New button on a card page.

OnBeforeInsertEvent – table event

OnInsert – table trigger

OnDatabaseInsert – codeunit 1 event

SQL will insert the record into the database – database operation

OnInsertRecord – page event

OnAfterInsertEvent – table event

That is a lot of stuff that happens for each and every action. Also a lot of code to possibly debug through if something is going wrong. Also, if you are wonding what happens when you have multiple subscribers to the same event, check this out.


So now that we know all about these built in events, how do we take advantage of them?

In our example we are going to subscribe to the “OnAfterInsertEvent” on the customer table. The first thing I suggest is making a new codeunit specifically for event subscribers. As an aside, you can only put subscribers in codeunits.  Once you have your shiny new codeunit, add a new function. A good rule of thumb for making event subscribers is to include what event the function is subscribing to in the funcation name. As well as includeing what the funcation is supposed to do. They can get quite lengthy doing this but the upside is that it is very clear what your function does and you don’t have to check out its properties to see what its subscribing to. I’m going to call mine “BlockCustomerOnAfterInsertCustomer”. This function is going to be pretty simple. It will set the blocked flag on a customer after it is created. If we chose before instead of after we would have gotten an error trying to modify the record because it wouldn’t have been created yet. Once you create the function go into its properties. This is where we set it up that we want this function to be a subscriber.


Once you specify the EventFunction, Nav will ask you if you want your parameters to match the published event parameters. You almost always want to say yes to this. As it will give you access to the proper parameters that will be passed in to your subscriber. Usually these parameters include the record that you are currently working with. Once you have your function subscribing to an event, you can put in whatever code you want. My example just has the following:

Rec.Blocked := TRUE;

Its not a lot, and you might be thinking, “Why not just put this in the customer table insert trigger?”. The main reason you do not want it in the trigger is there might already be a lot of code in the trigger. Code that isn’t yours. If you change that code it will be harder to upgrade that code. This way, your modifications are completely separate from anyone else’s changes. This will also allow you to more modularize your code, which can make it easier to debug since you don’t have to step through massive hundred line function. It should be more apparent where each change is being made.

Hope this helps get you on your feet when subscribing to built in events provided by Microsoft or other ISVs.

Next we will look into creating our own event publishers. – 03/16/2016

Leave a Comment