NAVY: A package manager for Dynamics NAV

After a discussion at the MVP Summit between some of the NAV MVPs a idea of an alternative to Microsoft’s new extensions appeared. And after some hours of coding, and about ~400 lines of code, here is “NAVY” – Microsoft extensions are called NAVX – Y is coming after X  therefor NAVY (Thanks Waldo).

This package manager is created for OnPremise installations, for installing verticals and horizontals into a standard NAV. Currently multi-tenant setup is not on my mind.

A NAVY package consist of metadata, new objects as FOB or TXT and DELTA files for changed standard objects.

NAVY can perform 5 operations:

  • BUILD a NAVY package with FOB/TXT objects and DELTA files
  • INSTALL a NAVY package into a database
  • UNINSTALL a NAVY package from a database
  • SUSPEND a NAVY package in a database
  • RESTORE a NAVY package in a database

The package life cycle

The main idea, is that you BUILD a package and then INSTALL that into a database. When you need to update the standard Dynamics objects you SUSPEND the objects (so the original objects are put back), upgrade NAV and then RESTORE the package back to its intended functionality.  If you want to get rid of the package you will use UNINSTALL so the original objects are reinstalled.


Download NAVY from here NAVY and extract the files from the zip file. The first thing to do is edit NAVY.exe.config and make sure that the paths points to your Dynamics NAV installation.

I have only tested with Dynamics NAV 2016, but it should work with 2013R2 and newer.


Building a package

A package need a FOB file and some DELTA files. If you never have tried to create DELTA files, there are lots of good explanations on the net, here is Microsoft’s:

Waldo wrote a lot about it here

A .NAVY file is just a ZIP file, so you can open the package with any ZIP tools.

Installing a package to a database

Installing is easy, make sure your NAVY.exe.config file points to the right executables, after that you simply type:

NAVY install Name=<packagename> DatabaseName=<databasename>

and NAVY will install the package.

After the installation has completed, a .NAVY.Backup file is created with the original objects. This file is required to do uninstalls and suspensions. Keep this file together with the .NAVY file.

Uninstalling a package from a database

Uninstalling a package is just a easy.

NAVY uninstall Name=<packagename> DatabaseName=<databasename>

NOTE: The objects installed from a FOB file is not removed  by the uninstall, only the changes to standard objects.

If fields are added to standard tables, uninstall will delete the field and thereby destroy the data – If that is not what you want, go look at the suspend command

Suspend a package on a database

If you want to upgrade the standard objects, its much easier to do if the original objects are back. This is what the suspend command does:

NAVY suspend Name=<packagename> DatabaseName=<databasename>

This will save values from fields added to standard tables before uninstall the changes and putting the original objects back.

In the .config file, you can specify what object number the table and codeunit used for storing data uses. Default is 50000.

After suspension has completed, you can upgrade NAV and then run the restore command.

Restore a package on a database

The restore command revert the suspension.

NAVY restore Name=<packagename> DatabaseName=<databasename>

The DELTA files are again applied and the saved data is being place back into the new fields.

NAVY is Open Source

Download the source from github, it is just a Visual Studio 2015 C# project with no external requirements. Fell free to change it into something useful. I love pull request :)

Access the source code at:

Developing for the Dynamics NAV Phone client..

Not every Microsoft Dynamics NAV page works with the new phone client. If you suddenly get a message saying “This task is not possible on your current device. Instead, use a tablet or a desktop computer to complete this task. (ID: xxxxxx)” xxxxxx is the object number of the offending page.

Then you are using a page of type worksheet you will get this error.


How to create a cool LEGO remote controlled car.

In our house we love to play with remote controlled cars. But RC cars in the kid-budget area tend to break after a few hours of use.

Not long ago we shopped a bit a and we got some of the “motor” pieces that normally only come with some of the largest Lego Technic sets.

And very quicky, a remote controlled car in Lego Technic was put together, and it actually gave the same play ability as a normal remote controlled car, plus the entire Lego universe. And it seems unbreakable – If something “breaks” – we put it back together again, or perhaps a new car is suddenly a reality.

The center piece is the “88004 Servo motor”, a motor that gives a 180 degrees turn and can be controlled with any of the IR remotes from Lego. We had the IR Receiver (8884) from a Lego train system and we got the 8885 remote controller.

A motor and a battery box is of cause needed, the standard 8293 motor set will do fine, however, if you want more power, the new L-motor or XL-motors are great for speed and power. We use the L and XL motors that reason.

Watch this small video for a demo of the car:

Here are links to the three pieces needed – Total investment if you already have a motor set is $50 – Not bad for unlimited supply of different remote controlled cars.

Servo engine:

IR Receiver:

Remote Control:

Creating user documentation and help for Dynamics NAV

Here are the slides from my NAVUG talk on doing documentation for Microsoft Dynamics NAV solutions.

COM08 An elegant solution for creating Dynamics NAV user documentation

The open sourced code can be found at:

A precompiled package of the tools can be downloaded from here:


I suggestion reading through the old posts on this to understand whats going on at

Wishlist for “NAV2017” / Code name Madeira

Now that NAV2016 has hit the road and is looking great, we can start dreaming about NAV2017, NAV2018 or just code name Madeira until it gets a proper name. I’ve try to keep this blog post updated with my ideas, other people ideas and link to relevant information. So far this is focused on NAV as a development platform, but application suggestions are very welcome!

So here goes:


My number 1 wish is “BLOB Ref” – We got FieldRefs, but they do not support Blob fields. Throughout the standard application Microsoft uses “TempBlob” and other not optimal constructions to overcome the fact that you cannot address a blobfield as a reference. This also prevents RapidStart to handle values in Blob fields. I wrote about this 2 years ago.

Dynamic temporary variables

Marking a variable of type RECORD temporary is currently a static compile time property. I would love to be able to mark record temporary or not directly from code. In that way, creating simulations would be much easier, even the new “preview” functions in standard NAV could properly be implemented smarter.

Better FOREACH statement

The FOREACH statement should work on RECORD variables also, it could work with a slight change in syntax:

FOREACH customer in FINDSET(false,false) DO BEGIN

That would be the same as:

IF customer.FINDSET(false,false) THEN
UNTIL customer.NEXT = 0;

or perhaps just:

FOREACH Customer.FINDSET(false,false) DO BEGIN

Incoming from Guido Robben

  • A more user friendly report designer
  • F2 key press to work the same way in the Role Tailored Client as it did in the Classic Client.

More to come …

New variable types in NAV2016

Even though we are getting used to the DotNet variable type, Microsoft Dynamics NAV 2016 has several new types available.

This is what NAV2015 supported:

And now, in Microsoft Dynamics NAV 2016:

DefaultLayout – That goes together with the REPORT.DEFAULTLAYOUT function. A variable of type “DefaultLayout” can hold the different types of reports (Word, RDLC etc.)

FilterPageBuilder – Used by the new dynamics request pages. This rabbit hole looks quite interesting.

ObjectType – Being used as a parameter to the GETURL function.

ReportFormat – Being used as a parameter to the REPORT.SAVEAS function.

TableConnectionType – Being used with the REGISTERTABLECONNECTION and UNREGISTERTABLECONNECTION methods. Options can be CRM or ExternalSQL

TextEncoding – This one is really nice. CREATEINSTREAM and CREATEOUTSTREAM can now take an extra parameter for encoding. So now there is no more need for StreamReader and StreamWriter constructs with System.Text.Encoding help. Now this is done by NAV.

All of these are just Option fields (not the FilerPageBuilder) with a fixed OptionString – Not really necessary and does not, standalone, bring any new functionality to NAV. But each of them are related to new features or functionality and that is always interesting. I’m getting back to the FilterPageBuilder later.

I’m still missing “BlobRef” as a variable type, or if I cannot get that – just give me CREATEINSTREAM and CREATEOUTSTREAM on FieldRef, please Microsoft, that would even clean up a lot of your code with all the TempBlob you got going.

FOREACH Statement available in NAV2016

A very used statement in C# is the foreach statement. A loop that traverse any structure with a enumerator. This is now present in NAV2016, only on dotnet variables so far.

Here is an example from the OCR/Document module of NAV0216.

An outer loop of all the child nodes in a xml node, and the an inner loop of all the “DocumentId” childs of the first node.

        ChildNode := XMLNode.SelectSingleNode('BatchExternalId');
        ExternalBatchId := ChildNode.InnerText;
        IF (ExternalBatchFilter = '') OR (ExternalBatchFilter = ExternalBatchId) THEN
          FOREACH ChildNode IN XMLNode.SelectNodes('DocumentId') DO BEGIN
            DocId := ChildNode.InnerText;


Another example, goes through all the elements of an dotnet Array:

        Name := FilterPageBuilder.ADDTABLE(GetTableCaption(Table),Table);

So far, it looks like FOREACH is only present in “new” objects in NAV2016.

NAV 2016 is released :)

Today Microsoft announced the general availability of Microsoft Dynamics NAV 2016, a milestone release of Microsoft’s business management solution for small and midsized organizations. Microsoft Dynamics NAV 2016 offers significant new capabilities in mobility, business insight, and cloud services, as well as deeper interoperability with Microsoft Azure, Microsoft Dynamics CRM and Office 365.

New capabilities in Microsoft Dynamics NAV 2016 will help SMBs:

  • Enable mobile workers on any device with new streamlined, easy-to-use native apps for all form factors of devices – phones, tablets, and mouse and keyboard – running Android, iOS, or Windows.
  • Increase business insight with pre-built Microsoft Power BI dashboards and data connections that give teams instant access to key performance indicators in an intuitive, easy to use environment designed for secure collaboration.
  • Grow sales, improve customer service, and streamline order-to cash-processes through native integration with Microsoft Dynamics CRM Online.
  • Take advantage of enterprise class scalability, security, and availability in the cloud with the new option to deploy Microsoft Dynamics NAV on Microsoft Azure SQL Database, Microsoft’s industry-leading database-as-a-service in the cloud offering.
  • Digitize their businesses with expanded document management, workflow, and Optical Character Recognition (OCR) capabilities designed to help SMBs automate processes and eliminate paper-based transactions.
  • Tap into the power of the cloud more easily with expanded extensibility and connectivity capabilities to help customers and partners more easily integrate Microsoft Dynamics NAV with other cloud-based services.

I’ve start blogging about the many new features very soon :)


Mouse over in debugger …


If you get multiple entries when hovering the mouse over a variable name in the Microsoft Dynamics NAV  2015 debugger  – you are out of luck.

The debugger does not perform a lexical parsing of the source, so it will just search the variable space, and in cause of multiple hits, it will show them all.

So when you hit something like this, you got to perform your own parsing – In my case, this came from a piece of code that used the WITH <?> DO statement.