AX 2012: LogisticsPostalAddress unknown value


I learned something new about DateEffective tables today. I had a customer requirement to store addresses in a Standard AX table, PdsApprovedVendorList. So I created a relationship between my table and LogisticsPostalAddress table, adding foreign key to LogisticsPostalAddress to my table. Then I added this field to a form and set ReplacementFieldGroup property of the control to LocationReference.

Everything worked as expected but the problem surfaced when user modified one of the addresses in the Global Address Book which were referenced in my table. The custom field began to show Unknown for the address that was updated by user.


1. Add new Reference Data Source of LogisticsPostalAddress to the data source of your table on the form.


2. Add the following lines of code to the form’s init method:

legManufacturerAddress_ds.addFieldToSelectionList(fieldNum(LogisticsPostalAddress, ValidFrom));
legManufacturerAddress_ds.addFieldToSelectionList(fieldNum(LogisticsPostalAddress, ValidTo));
legManufacturerAddress_ds.addFieldToSelectionList(fieldNum(LogisticsPostalAddress, CountryRegionId));

3. Add the following lines of code to the executeQuery() method of parent data source to which reference data source is added before super() call. In this case, it is PdsApprovedVendorList.

legManufacturerAddress_ds.query().validTimeStateDateTimeRange(DateTimeUtil::minValue(), DateTimeUtil::maxValue());


LogisticsPostalAddress is a DateEffective table. When user modifies an existing address, system creates a new record instead of updating the existing record. That’s why references do not get resolved after address modification.


AX 2012: Add Custom Module to Main Menu

1. Create your custom menu under Menus in AOT.


2. Create menu reference for your newly added menu under Menus > MainMenu in AOT.


3. Drag your newly created menu to the MainMenu.


4. Save the changes. Restart the Functional workspace to see your module coming up with standard AX modules 🙂


AX 2012: Getting ReferenceGroup Control

Getting ReferenceGroup control automatically while dragging a datasource field to a form control is little tricky. Even if you have defined relations correctly at the table level, you might not always get the reference group control for a foreign key in the table. See the solution below for this issue.


Consider for example, two tables:

1. FAZCourseTable
2. FAZEnrollmentTable

where FAZEnrollmentTable contains the foreign key of FAZCourseTable as follows:


But when I drag this foreign key field from datasource to grid control, I get Int64Edit control instead of ReferenceGroup control.



To get the ReferenceGroup control, perform the following development steps:

1. Create unique index on FAZCourseTable for the natural key of the table which in this case is Code field.
2. Set AllowDuplicates to No on the index properties.
3. Set AlternateKey to Yes on the index properties.


4. Set ReplacementKey to CodeIdx, name of the index just created, on the table properties.


5. Delete the Int64Edit control created earlier on the form.
6. Drag the FAZCourseTable field from the datasource to the grid control node.
7. You should be getting the ReferenceGroup control now.


AX 2012: Enable Disable Buttons on PurchTable SalesTable Forms

To enable/disable buttons on PurchTable/SalesTable form, you can customize their respective interaction classes:

1. Classes\PurchTableInteraction
2. Classes\PurchTableInteractionHelper
3. Classes\SalesTableInteraction
4. Classes\SalesTableInteractionHelper

Let’s say, for example, I want to enable the Configure line button under Product and Supply menu:


All you need to do is to find and customize the right method which controls the enabling/disabling of the button. In this case it is SalesTableInteractionHelper.parmButtonConfigureLineEnabled():


After compiling, you can see the button enabled!



In the example above, I am returning true without any condition to enable the button. This has been done just for demonstration purpose. You should be controlling the enabling of the button based on any condition that suits your business requirement.

AX 2012: Auto increment a field using LineNum

Do you want a line number field for your table just like we see the line numbers on SalesLine table on the Sales Order? if so then follow the steps below the achieve this functionality.

1. Drag LineNum EDT to the fields node of your table.
2. Create an index on your table and drag the LineNum field to this index
3. While defining the datasource on your form,

  • Set Table to your table
  • Set Index to the index you created which contains the LineNum field
  • Set CounterField to LineNum


4. Override the create() method on your form’s datasource and set the default value of append parameter to be true. This will ensure that records are getting inserted at the bottom so that AX kernel generates positive line numbers instead of negative line numbers because of prepending records at the top!


AX 2012: Using Temporary Table as Form’s Datasource

First add a method on the form to populate records in the temporary table:

public LabelsTable populateRecords()
    SysDictTable    dictTable = new SysDictTable(tableNum(PurchLine));
    SysDictField    dictField;
    TreeNode        treeNode;
    LabelsTable     labelsTableLocal;                 // Temporary table (InMemory)
    FieldId         fieldId = dictTable.fieldNext(0);

    while (fieldId)
        dictField = dictTable.fieldObject(fieldId);

        if (dictField.isSql() && !dictField.isSystem() && != "Modified")
            treeNode = dictField.treeNode();
            labelsTableLocal.Field =;
            labelsTableLocal.Label = treeNode.AOTgetProperty("Label");

        fieldId = dictTable.fieldNext(fieldId);
    return labelsTableLocal;


Then override form’s init() method and add the following code to display the temporary table data on the form:

public void init()

AX 2012: Add dynalink in X++

Use the following code to add dynalink to the form datasource query:

public void init()
        fieldNum(MzkPurchTrackingDetailsTable, PurchId),
        fieldNum(PurchParmTable, PurchId));


  • First parameter is the source table field
  • Second parameter is the destination table
  • Third parameter is the destination table field