Using Argument Tables | Introducing Overloading in Dynamics NAV

Last year I did some videos about organizing code in Microsoft Dynamics NAV which I put on my YouTube channel. I wanted to do more, but got occupied by writing a book about learning dynamics NAV patterns and organizing a global set of classes around this subject.

Let’s continue where we left off and discuss the possibilities and challenges of implementing the arguments table.

Let’s go into it.

At the end of this blog you will be familiar with the Arguments table pattern, why we need it in Dynamics NAV and what are possible negative side effects.

Problem Definition

Within our C/AL programming language and programming in general we have some challenges.

Using to many arguments in a function

When creating functions we sometimes need a lot of parameters to give the information we require. Sometimes these parameters are optional, only required in some scenarios. This makes calling them quite hard. The code becomes less easy to read, sometimes spread across multiple lines.

Arguments

Hard to change signatures

When refactoring code it is hard to change signatures of functions when they are called in many places of the system. Think about the Functions that create reservations for example. When changing the signature of these function you might end up changing and endless chain of codeunits.

Arguments2

No Function Overloading in C/AL

Our beloved language does not support overloading. What is that? I had to look it up too the first time. Overloading means creating functions with the same name and meaning that take different parameters effectively allowing you to be more flexible in your code.

For example creating a new DateTime in DotNet can be done in 12 different ways with different parameters effectively giving the same result, a DateTime.

Arguments6

Duplicating Option Definitions

Lastly, when calling functions that take an option field as parameter we have to duplicate the option value in order to make the code easy to read. And option values are hard to maintain anyway.

Solution

These challenges can be solved by grouping commonly used arguments in a single table and use that table as the parameter of a function. This is effectively using a table as a class.

Let’s look at some examples of candidates in our product

The legacy code of Dynamics NAV is full of examples, but let’s discuss two that you are bound to hit if you start working with the product, even if you don’t deep dive.

FindSalesPrice

This function in codeunit 7000 is called to calculate a sales price for an Item. It uses 10 parameters.

FormatAddr

This function in codeunit 365 is called to format an address in the system

Changing the signature

Imaging adding a field to this function, or change a datatype. The amount of code affected is pretty big and if you need to parameter only for one specific case you end up changing a lot of code for no purpose.

Compiler

Fortunately the compiler finds all instances where the function call is incomplete, but that does not mean we should use that to change all of them.

Let’s also make sure we understand that the sheer fact that NAV legacy code has these functions it is ok to do so. It does not match the basic principles of clean code.

The Argument Table

So the solution is to create a single table that holds the contract for the function. This would be similar to creating a class in DotNet and using that class as parameter.

When we add new fields to the table, we effectively do not change the signature of the function hence this acts as overloading allowing optional parameters to change the behavior of the code.

Arguments3

Examples in Standard Dynamics NAV

What if I told you that this one of the oldest patterns in Microsoft Dynamics NAV, dating all the way back to good old Navision Software. Would you believe me? I guess not, but it is true.

All codeunits that are used to post Journals are effectively argument functions. We use the Journal Line as an argument table to call into the posting routine. Imagine the effect if posting routines had all these fields as parameters.

Arguments4

When we call one of these codeunits nested inside another transaction we never actually insert the journal line in the database. We merely use the record variable as a placeholder in memory for the data.

Side effects

Although in my personal opinion the arguments is one of the greatest patterns to write clean code, there are some side effects

First off we need to write code to populate the arguments table. This requires us to write extra code we don’t need if we just call a function with let’s say 10 parameters. It does make the code cleaner and makes it intention easier to understand.

Also, the fact that the compiler does not catch adding a field to the table as a signature change can be a downside. Who has not abused this feature as “where used”. We would really need where used in order to perform a risk analysis when adding arguments.

Last but not least, one of the basic principles of events will be broken. The new events in NAV2016 have a built in warning system if a parameter that I inherit no longer exists. This mechanism does not understand if I delete a field of an arguments table. The extensions have the same challenge.

Example

Let’s look at an example. In NAV2015 the development team decided to implement email as an arguments table. This is table 9500 Email Item.

This table has all fields we need to send emails, as well as functions to send the email. The validation logic of the fields can be used to perform checks on the values. How nice and clean is that.

Arguments5

The arguments table is used in Codeunit 260 Document Mailing. Here you can see the coding that is required to use an arguments table.

A new, nice and clean way of writing C/AL code.

Naming Recommendations

When using arguments tables, I recommend adding the keyword “arguments” to the name of the table. This makes it one of the only, if not the only plural table name in Dynamics NAV.

Licensing Considerations

In essence Argument tables can be outside of a customer’s license file since we never insert data in the SQL Server database. However, when you want to use functions as methods of the arguments table it needs to be licensed. Reason for this is simple. The licensing engine is not aware that you want to run code that is tied to a temporary table, you might for example call code in a Production Order when running Business Essentials licensing. To make this work, Microsoft first needs to add a table type “temporary” to the properties

Want to know more?

I will create a video on this too soon. The Arguments Table is also part of my new book.

Learning Dynamics NAV Patterns

Advertisements

8 thoughts on “Using Argument Tables | Introducing Overloading in Dynamics NAV

  1. I have also used this pattern a few times, but I must admit I’m not a big fan of it. Introducing it in existing functions requires all existing calls to be modified. This can be prevented using a different pattern, which actually is closer to real overloading.

    The argument pattern also get into problems, once it becomes necessary to add a record variable to the signature. It only supports simple variables. It is also very difficult for users of the function to see which parameters are optional and which are required.

    I therefore recommend a different approach, or pattern if you like. Simply create a new function with the extension Main, mark it Local, and move the code from the existing function to this new local function. Then call the new function from the old function to keep existing functionality unchanged.

    Now you haven’t changed any existing calls, and are ready to create all the function overloads you like. Just name the function name by adding either a number or a meaningful name if possible. Have all the overloads functions call the main function. Each time you add a parameter, you only have to change the main function and all the overload functions. This even enable you to have different default values of the new parameters in the old overload functions.

    I find this pattern easier to use and with a smaller footprint than the argument table. The footprint is important when customizing existing functions, but I also prefer it in my own functions, as it makes it easy to see which valid signatures a function got.

    What do you think about this approach?

    Like

    1. I agree. This pattern is useful if you have control and for repeatable libraries. You can combine it with a variant and create a variant facade. The approach of adding a second function is how the testabilty framework works. Alain Krikilion is the one that pointed that out for the first time from a patterns perspective. It’s the one I use when I have to add functions to reservations for example. We should think of a nice name for it from a patterns perspective. Any ideas?

      Like

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