Wednesday, December 13, 2017

Find standard label translations

Microsoft aren't shipping the source standard label translations with the developer boxes. You only get the source for labels in en-us and the rest you only get as binary.

Here is what you can do if want to figure out how a particular label is translated.

First find the binary for the translated label file. This will be in the Resources folder under the package in question. For example, looking for the PRO labels from ApplicationSuite in Danish:

And next, open the dll in a tool allowing you to peek inside dll's. For example .NET Reflector.

Thursday, December 7, 2017

Misleading statements in 81215AE: X++ Programming and Advanced Topics in Microsoft Dynamics 365 for Finance and Operations, Enterprise edition

In Module 07 (and a few other places within same course) the importance of using the client / server modifiers and the RunOn property is discussed and emphasized.

However in D365 all X++ code is executed on the server. And thus the client / server keywords as well as the RunOn property are ignored.


I haven't tried the actual exam yet, so I don't know if this wrong assumption from the training material has sneaked into the exam as well. If there are questions on client/server settings, it probably has sneaked its way in since it's not of any importance anymore.

Wednesday, November 8, 2017

XQuery to save source code from all tables and classes

You can use this XQuery, with for example BaseX, to save all your source code from table and classes to an XML file:
  for $t in AxClass | AxTable  
  order by $t/local-name(.), $t/Name ascending

  for $y in ($t/SourceCode/Methods/Method)

  return <Code Type='{$t/local-name(.)}' Parent="{$t/Name/text()}" MethodName="{$y/Name/text()}" Source="{$y/Source/text()}"/>

Query range function: Less than date and not date null

There is a lessThanDate query function in AX, but it also selects blank dates.

Here is a suggestion for a similar function, that does not include the blank dates:
public static str lessThanDateAndNotNull(int relativeDays = 0)
    utcdatetime  currentDateTime;      

    currentDateTime = DateTimeUtil::applyTimeZoneOffset(DateTimeUtil::getSystemDateTime(), 

    return SysQuery::value(dateNull() + 1) + ' .. ' +            
           SysQuery::value(DateTimeUtil::date(DateTimeUtil::addDays(currentDateTime, relativeDays - 1)));  

Friday, November 3, 2017

XQuery to use with BaseX to find elements with no configuration key

Here is an XQuery that you can use with BaseX to find elements with no configuration key:
  for $t in AxTable | AxEnum | AxEdt | AxDataEntityView | AxMenuItemAction | AxMenuItemDisplay | AxMenuItemOutput
  order by $t/local-name(.), $t/Name ascending
  where fn:empty($t/ConfigurationKey)
  return <Element type='{$t/local-name(.)}' Name='{$t/Name/text()}' ConfigKey='{$t/ConfigurationKey}'/>

More on BaseX

Tuesday, September 26, 2017

Short book review: Implementing Microsoft Dynamics 365 for Finance and Operations, Enterprise Edition

Authors: Rahul Mohta (@RahulMohta8), Yogesh Kasat (@yogeshkasat) and JJ Yadav (@JJYadav)

Link to purchase:

This book covers the implementation process for a D365FOE project from A-Z. It combines theory with real life experience and it collects information you would have to look up multiple different places otherwise.

The book is very much up to date, also with information about the July 2017 release. It’s an impressive achievement to make the book so much up to date, taking into account the pace of changes from Microsoft. One thing that is not up to date though is the description of the database log implementation which has changed in the July 2017 update.

I currently work with ISV product development, not doing project implementations currently and I can say that I have learned a lot from this book. I could definitely see myself use this book as reference for future work.

A digital copy of the book was provided at no cost for me, by the authors, for the purpose of this short review.

Friday, September 22, 2017

The role of XLIFF files in the LCS Translation service

In the July 2017 release for LCS, support for XLIFF Translation Memory (TM) files was added. XLIFF (XML Localisation Interchange File Format) is an XML format used to standardize how translations are passed between different tools (Wikipedia).

Such a file holds a lot of information, like tags for source- and target languages, source- and target texts, indication whether the target text is the result of a machine translation, indication about if you actually want a translation of a given text (using {locked} in the comment of a label sets this flag to No), workflow status in relation to review of a translation and much more.

If you have existing translations and you need to add new translations to a project, you would want to tell the translation service about your existing translations to avoid getting them overwritten. You do that by requesting an XLIFF file as the first thing you do:

And here you upload a source and target label file:

In relation the tips 1,2 and 3, it seems like the label files are structured well enough for the tool not care about it. I have uploaded files with different number of labels, because new labels only have been added to source label file and I have used files where a few labels was not in the exactly same order. If it doesn't work out, you must prep the target file first.

As a result the browser returns the XLIFF file almost immediately.  Make sure your browser doesn't block downloads, otherwise nothing happens.

This is a small sample from a file:

You can also open it it Excel:

At this point you can actually start working with the translation. For example by inserting manual translations that you want included.

You can also use the "Multilingual app toolkit" from Microsoft to work with the file. The program is a bit outdated, latest supported Windows version is Windows 8.1 and the integration to Microsoft Translation services is broken. But as an editor the program works fine, and it has a fine UI for all the important tags of the XML file. 

It looks like this:

Now that you have the base for the translation, you can start the actual translation.

This takes you to the file upload dialog, where you upload zip files with your labels and with your XLIFF file:

When you click submit, the the job enters status processing.

There are some manual steps involved in the processing and you'll get an e-mail from the LCS team stating that this could take up to 5 business days. This manual involvement is related to the Microsoft Translator Hub being fed with your XLIFF files in order to train it using your existing translations. This should mean that it is able to pick up on how you have translated existing terms and reuse that way of translating for similar terms. For example (an example from AX 2012 that didn't go well there) the word "Visa" can be translated into two different words in Danish. Either as a required travel document (da: visum) or the credit card (da: Visa). When the translator hub knows what you have translated "Visa" into in other places in your label file, it has a better chance of determining what kind of visa you refer to.

In order to not start manual work just for the sake of this blog post, here is the result from another translation task.

The second file is a new label file which you can check into VSTS. You can do that directly or use this process if you might have other changes to the label file: Merge externally modified label files

The first file is a new XLIFF file including all the new translations. You can send this file out for manual review and the receivers can open it essential using a tool of their choice. Excel or the Multilingual App Toolkit would be good choices. You can actually also find a couple of online tools where you upload the file, edit the translations and download an updated file.

If the review causes changes to the XLIFF file, you can click the Regenerate button, upload the modified XLIFF file and almost immediately get a new label file based on that.

If you are 100% sure that only your source label file gets changes during development, you can keep this new XLIFF file and recycle it for your next translation. If both source and target could be changed, you should build a new XLIFF file.