Thursday, June 7, 2018

How to load all labels from a label file

Here is a small example of how to load all the labels of a particular label file, in a particular language. It takes about 6-8 seconds on my developer box to load the 122190 label from SYS.

public static void main(Args _args)
    info ("Starting");
    ClrObject labels = new ClrObject("System.Collections.Generic.Dictionary`2[System.String,System.String]");
    labels = Microsoft.Dynamics.Ax.Xpp.LabelHelper::GetAllLabels('SYS', System.Globalization.CultureInfo::CurrentCulture);

    ClrObject labelsEnumerator = labels.GetEnumerator();
        ClrObject keyValuePair = labelsEnumerator.get_Current();

        var currentlabelId = keyValuePair.get_Key();
        var currentTxt = keyValuePair.get_Value();
    info ("Done");

Wednesday, May 2, 2018

Need to work with or add system defined buttons on forms?

You can change the behavior of system defined buttons form, or add buttons, by subscribing to delegates from the SysSystemDefinedButons class.

The class AlertFormExtender has an example of how a button is added to the Options action pane tab.

Monday, April 30, 2018

Why you can't setup sharing of customers and vendors in 8.0

The release notes for 8.0 says that you can now share customers and vendors with the data sharing feature. But it also says: "To enable this functionality, contact your Solution Architect, who will verify that your business requirements and data volumes will be acceptable for data sharing, and then enable the sharing policies in your environment".

So what does that mean?

Microsoft has started using a "flighting" concept where they add features on a release, but keep them turned of until activated for the tenant by Microsoft. This is something you can see Microsoft check in their code.

A new isFlightEnabled method on the Global class does the work of checking if a feature is enabled or not.

If you want to cheat a bit, you could probably add an event handler to this method and return true for the feature you want to enable. I haven't tried that though.

In class SysDataSharingValidation, method validateTableCanBeSharedWithPolicy, you can see an example of how this is called:

Thursday, March 15, 2018

Lifecycle Service companion app

Here is a cool tool for LCS environment managers, written by Tomek Melissa from Microsoft.

The tool is unofficial and comes AS-IS.

Saturday, March 10, 2018

Generic function for switching line numbers on records

Tried to write a generic routine for switching line numbers on records, to help with functions that move records up or down according to a line number sequence.

Comments are welcome and I'll update the post according to the bugs you can find. However I only spent 10 minutes on this and it's provided to you for free, so please bear that in mind before you send me death threats in the comments.

public static void switchLineNumbers(
    Common      _currentTopRecord,
    Common      _currentBottomRecord,
    FieldName   _lineNumberFieldName)
    Common      currentTopRecordUpdate;
    Common      currentBottomRecordUpdate;
    LineNumber  topLineNumber;
    LineNumber  bottomLineNumber;
    FieldId     lineNumberFieldFieldId = fieldName2id(_currentTopRecord.TableId, _lineNumberFieldname);


        // Initialize correct table id on common
        currentTopRecordUpdate = new DictTable(_currentTopRecord.TableId).makeRecord();
        currentBottomRecordUpdate  = new DictTable(_currentBottomRecord.TableId).makeRecord();

        select firstOnly forUpdate currentTopRecordUpdate
            where currentTopRecordUpdate.RecId == _currentTopRecord.RecId;

        // Make a temporary line value, in case there is a unique index with line number,
        // making a free spot to update the currect bottom record with
        topLineNumber = currentTopRecordUpdate.(lineNumberFieldFieldId);

        currentTopRecordUpdate.(lineNumberFieldFieldId) = maxInt();

        select firstOnly forUpdate currentBottomRecordUpdate
            where currentBottomRecordUpdate.RecId == _currentBottomRecord.RecId;

        bottomLineNumber = currentBottomRecordUpdate.(lineNumberFieldFieldId);

        currentBottomRecordUpdate.(lineNumberFieldFieldId) = topLineNumber;

        currentTopRecordUpdate.(lineNumberFieldFieldId) = bottomLineNumber;


    catch (Exception::DuplicateKeyException)
        if (appl.ttsLevel() == 0)
            if (xSession::currentRetryCount() >= #RetryNum)
                throw Exception::DuplicateKeyExceptionNotRecovered;
            throw Exception::DuplicateKeyException;

Use at your own risk.

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.