Using the Translation Service for G/L Source Names

Until now I have had my G/L Source Names extension in English only.

Now the upcoming release of Microsoft Dynamics 365 Business Central I need to supply more languages.  What does a man do when he does not speak the language?

I gave a shout out yesterday on Twitter asking for help with translation.  Tobias Fenster reminded me that we have a service to help us with that.  I had already tried to work with this service and now it was time to test the service on my G/L Source Names extension.

In my previous posts I had created the Xliff translation files from my old ML properties.  I manually translated to my native language; is-IS.

I already got a Danish translation file sent from a colleague.

Before we start; I needed to do a minor update to the AdvaniaGIT tools.  Make sure you run “Advania: Go!” to update the PowerShell Script Package.  Then restart Visual Studio Code.

Off to the Microsoft Lifecycle Services to utilize the translation service.

Now, let’s prepare the Xliff files in Visual Studio Code.  From the last build I have the default GL Source Names.g.xlf file.  I executed the action to create Xliff files.

This action will prompt for a selection of language.  The selection is from the languages included in the NAV DVD.

After selection the system will prompt for a translation file that is exported from FinSql.  This I already showed in a YouTube Video.  If you don’t have a file from FinSql you can just cancel this part.  If you already have an Xliff file for that language then it will be imported into memory as translation data and then removed.

This method is therefore useful if you want to reuse the Xliff file data after an extension update.  All new files will be based on the g.xlf file.

I basically did this action for all 25 languages.  I already had the is-IS and da-DK files, so they where updated.  Since the source language is en-US all my en-XX files where automatically translated.  All the other languages have translation state set to “needs-translation”.

All these files I need to upload to the Translation Service.  From the Lifecycle Services menu select the Translation Service.  This will open the Translation Service Dashboard.

Press + to add a translation request.

I now need to zip and upload the nl-NL file from my Translations folder.

After upload I Submit the translation request

The request will appear on the dashboard with the status; Processing.  Now I need to wait for the status to change to Completed.  Or, create requests for all the other languages and upload files to summit.

When translation has completed I can download the result.

And I have a translation in state “needs-review-translation”.

Now I just need to complete all languages and push changes to GitHub.

Please, if you can, download your language file and look at the results.

Why do we need Interface Codeunits

And what is an interface Codeunit?

A Codeunit that you can execute with CODEUNIT.RUN to perform a given task is, from my point of view, an interface Codeunit.

An interface Codeunit has a parameter that we put in the

This parameter is always a table object.

We have multiple examples of this already in the application.  Codeunits 12 and 80 are some.  There the parameter is a mixed set of data and settings.  Some of the table fields are business data being pushed into the business logic.  Other fields are settings used to control the business logic.

Table 36, Sales Header, is used as the parameter for Codeunit 80.  Fields like No., Bill-to Customer No., Posting Date and so on are business data.  Fields like Ship, Invoice, Print Posted Documents are settings used to control the business logic but have no meaning as business data.

Every table is then a potential parameter for an interface Codeunit.  Our extension can easily create a table that we use as a parameter table.  Record does not need to be inserted into the table to be passed to the Codeunit.

Let’s look at another scenario.  We know that there is an Interface Codeunit  with the name “My Interface Codeunit” but it is belongs to an Extensions that may and may not be installed in the database.

Here we use the virtual table “CodeUnit Metadata” to look for the Interface Codeunit before execution.

This is all simple and strait forward.  Things that we have been doing for a number of years.

Using TempBlob table as a parameter also gives us flexibility to define more complex interface for the Codeunit.  Tempblob table can store complex data in Json or Xml format and pass that to the Codeunit.

Let’s take an example.  We have an extension that extends the discount calculation for Customers and Items.  We would like to ask this extensions for the discount a given customer will have for a given Item.  Questions like that we can represent in a Json file.

And the question can be coded like this.

The Interface Codeunit could be something like

With a Page that contains a single Text variable (Json) we can turn this into a web service.

That we can use from C# with a code like

This is just scratching the surface of what we can do.  To copy a record to and from Json is easy to do with these functions.

And even if I am showing all this in C/AL there should be no problem in using the new AL in Visual Studio Code to get the same results.

Working with optional NAV table fields

Now that we have entered the Extension era we must take into account that some extensions may or may not be installed at the time of code execution.

You might even have two Extensions that you would like to share data.

Let’s give an example.

In Iceland we add a new field to the Customer table (18).  That field is named “Registration No.” and is being used for a 10 digit number that is unique for the individual or the company we add as a customer to your system.

My Example Extension can support Icelandic Registration No. if it exists.

Using Codeunit 701, “Data Type Management”, Record Reference and Field Reference we can form the following code.

Let’s walk through this code…

GetRecordRef will populate the record reference (RecRef) for the given table and return TRUE if successful.
FindFieldByName will populate the field reference (FltRef) for the given record reference and field name and return TRUE if successful.

Call this function with a code like this.

We could create a more generic function.

This function can be used in more generic ways, like

See where I am going with this?

So the other way around…

And using this with

More generic versions can be something like this.

To use these functions we first need to copy our record to a variant variable and then back to the record after the function completes.


I have requested Microsoft to add more generic functions to Codeunit 701, “Data Type Management”.  I trust that they will deliver as usual.

That NAV Codeunit is one of my favorite ones delivered by Microsoft.

My first Dynamics 365 Extension – Offer ‘G/L Source Names’ is live

So, back from summer vacation and time to blog…

Early this month I got this email:

Offer ‘G/L Source Names’ is live

Congratulations! Your offer ‘G/L Source Names’ has been successfully published and is available publicly.

Next Steps

Below are the published link(s) for this offer. Please use these to verify and validate end to end experience.

Microsoft AppSource

If you need to update your offer click here.

Reply all to this email in case you need any help.

Thank you,
Microsoft AppSource team

If you follow these links you should see that the publishing portal for Dynamics 365 AppSource has been changed.

My App was automatically migrated from Azure MarketPlace to Cloud Partner Portal.  Got this email from Microsoft:


Azure Marketplace will be migrating your VM offers to the Cloud Partner Portal – the new and improved portal for publishing your single VM offers and getting valuable insights about your Azure Marketplace business, on Monday, 17th July 2017.

What should you expect during migration?

Migration will be done by Azure marketplace team and there is no action needed from you. Post-migration, you will start managing your single VM offers in the new Cloud Partner Portal.

During the migration, you will be unable to make updates to your offers via the publishing portal. Migration will be completed on the same day.

Will my offer be available on Azure Marketplace during migration?

Yes, migration will not affect your Azure Marketplace listing.

Refer to migration documentation here for FAQs.

You can log in to the Cloud Partner Portal at Documentation about the Cloud Partner Portal and publishing single VM offers can be found here.

General questions on the new CPP itself, reach out to and we will follow up with you! If you have specific D365 questions, reach out to

Azure Marketplace Team

And that is not all.  I also got this email from Microsoft:


The Dynamics 365 for Financials Extension Team wants to inform you of some important information. As of August 1st, 2017, we will begin accepting version 2.0 extensions for validation. Version 2.0 extensions is a much improved experience and represent our future direction for extensions. We will continue to accept v1 extensions until October 1. Please plan accordingly.

If you have a v1 app that is currently in process of validation, or if you have one that is currently published in App Source, you can begin (at your convenience) to convert your v1 app to v2. Refer to the site here for information on how to convert your app. We will work with you as well for the conversion so please direct any questions to and has all the information to date around Extensions v2.0. If there is anything you cannot find there, you can always contact the email with any further questions.

Best Regards

D365 Extension Validation Team

This blog series will be continued where I will be converting this App to Extension v2.0 using VSCode.  Stay tuned…

My first Dynamics 365 Extension – In maintenance mode

This morning I got this email:

Hi Gunnar,

I just wanted to inform you that your extension passed validation on US, CA, and GB. We will now get your extension checked in and it will go into the June (Update 7) release.

I am excited to see if users will start to install my app.  As more markets will open for Dynamics 365 for Financials (D365) I will need to support more languages to my App.

If you can help me with your local language please ping me.  The App is available on my GitHub site;  If you would like to install this extension or merge the deltas into your solution, again just ping me.

If you are in the process of creating an Extension for Dynamics 365 for Financials you can now request a Financials sandbox environment.  I installed this on my local virtual machine and this was an essential part of validating the extension.  You will need to sign up for the CTP program, which provides you with a prerelease version of Dynamics 365 for Financials. After you have signed the CTP Agreement, you are directed to a page that contains information about how to download the latest builds and configure a local computer or a Microsoft Azure VM for Dynamics 365 for Financials. If you have questions or feedback regarding this, please send an e-mail to:

Also, take a look at the updated page for more information.

Finally, if you take a look at the source for G/L Source Names you will find a setup.json file.  This file has all the information needed for my GIT Source Control.  As promised in NAV TechDays 2016 I am releasing the AdvaniaGIT to be community project.  Stay tuned to as I will be writing blogs about this project in the coming days and weeks.


Updates to my Object Renumbering Tool

Back in the end of 2014 I published a renumbering tool for NAV objects.  Using DotNet I was able to increase the renumbering speed for text object files dramatically.

Since then I have been asked if I could upgrade it to work with IDs and Field Numbers.

Now I have.

What’s more, it is also on GitHub.

The Process functions are the following;

  • Read Object Lines – Creates renumbering lines base on the objects in the selected object file.
  • Suggest IDs – Suggest new object numbers in the range from 50.000 based on the available objects in the current license.
  • Read from Excel – Reads object renumbering lines from Excel Sheet created with the Write to Excel process.
  • Write to Excel – Writes current renumbering lines to a new Excel Sheet to me managed within Excel and reread into the renumbering lines.
  • Renumber Using Lines – Prompts for a file to read and for a new file to save with renumbered objects based on the rules in the renumbering lines.
  • Renumber Using Controls – Prompts for a file to read and for a new file to save with renumbered objects based on the rules in the control IDs setup.

I have done some fixes to the renumbering function and have added support for the EventSubscriber.

Go to GitHub to download Page and Table 50000, try this out and submit improvements.

When I am processing an object file I have it open in my text editor.  When I see something to renumber I update the control ranges and execute the renumbering process, reading and writing to the same object file.  My editor will reload the file and I can see the results immediately.


My first Dynamics 365 Extension – NAV vs 365

I am now in the validation of my app.  Unfortunately I don’t have enough time to make this go any faster so please be patient.

This process will take time.  Here is an example of the expected time frame.

As you may have read in my previous post I created a few videos.  These are the first comment from Microsoft  about these videos.

The obvious information from here is that I can’t use Dynamics NAV anywhere in my Dynamics 365 for Financials extension.

I asked and this is the solution they gave me.

If you add &aid=fin to the end of your Web Client URL it will add the Dynamics 365 shell.

When I start my web client the normal Url is “http://tfw107131:8080/NAV2017DEV0000077/WebClient/”.  By adding the suggested switch to the Url and starting the web client with “http://tfw107131:8080/NAV2017DEV0000077/WebClient/?aid=fin” I will get the Dynamics 365 shell.

The parameters that are added to the Url start with a question mark (?) and after that each parameter starts with the ampersand (&).  As an example, I have opened the Customer List and the Url says: “http://tfw107131:8080/NAV2017DEV0000077/WebClient/?aid=fin&bookmark=27%3bEgAAAAJ7CDAAMQAxADIAMQAyADEAMg%3d%3d&page=22&company=CRONUS International Ltd.&dc=0”.  The parameter order does not matter, the “aid=fin” can be placed anywhere in the parameter part of the Url.

Now I am back at creating screen shots, videos and documentation.  All with the new Dynamics 365 for Financials look and feel.

My first Dynamics 365 Extension – step by step – eight step

Now we have gotten to Step 4 in the guided path Microsoft offered us on PartnerSource.

Step 4: Provide your offer information

After you have built your app, you will need to define all the attributes that will determine how your app will be listed in Microsoft AppSource. For example, your company information, your offer & plans, marketing information, support contact, and Microsoft AppSource categories.

To define the attributes, visit the Microsoft Azure Publishing Portal.

Refer to the Marketing Validation Guidance and checklist (coming soon) to get insight into the marketing requirements and recommendations.



Lets create a new Madeira offering.

Here I clicked on “Create Dev Center account and join the Azure program”.  This helped me link the development account I created in Step 2 to my Azure publishing.

Next I clicked on “Tell us about your company” and typed away.

Next step to describe my Extension.

Here we need a lot of information.  You can see the asterisk fields that are required.

In the Plan I just created a default plan.  There will be support for more later on.

Marketing, also a generic identifier.

Then go through the language and provide all the marketing information.

Put my name, email and phone in the support page.  In Categories I checked Business Application.  Then finally I requested approval to push to production.

Now I expect to be contacted by Microsoft and helped with getting my Extension online in Dynamics 365 for Financials.

My first Dynamics 365 Extension – step by step – fifth step

Development and installation.

For my development I use source control management.  Soren Klemmensen did a short demo of that setup in his session in NAV TechDays 2016.  We are working on making that solution public in a few months.  In every branch we have a setup file in a json format. That file has all the parameters needed to build an extension.  Here is the one I use for the G/L Source Names project.  When I have this Extension completed I will publish it to my GitHub Account.

For every extension we need to make sure that the installation and configuration experience for the customer is easy.  When the Dynamics 365 for Financials user open the Extension Management page our Extension should be visible there.

Here we can see that we need to create images for our Extensions. Later in the process, when we register the Extension on AppSource we will need to supply images in different sizes for out Extension. The image that I used when I created my Extension is 250×250 points. Starting the installation will take the user through an installation wizard. In the installation process the user sees all the properties we add to the Extension manifest definition. I create the manifest with the following code.

The image and a set of screenshot images are used when creating the Extension package file (navx).

In the below screenshots you should be able to see how my parameters are used in the installation process.  I have not yet seen my screenshots used in the Extension installation.

Web links, in the order of appearance are the appUrl, appHelp, appEula and appPrivacyStatement parameters.

Installation done and the user has logged in again and ready to start the Extension setup process.

If the Extension contains any tables then it must also contain permission sets for every table.  From the parameters above you can see that I have three permission sets for my Extension.  One for read permissions, second for update permissions and the third for the Extension setup permissions.  I expect that the user that is installing the Extension has full permissions and is able to assign permissions to other users.

In a simple Extension like this, Extension that does not require any company based setup we still need to make sure that every user has the required permissions to use the Extension.  For this task I use the Assisted Setup feature.

Catch my next blog to read all about that.