Including financial dimensions in a form

It is fairly easy to show and maintain financial dimensions from a record on a form. Here is a quick demo:

Create a new table called DEMO_FinancialDimInForm. Add 2 fields:

AccountNum (Extended data type = AccountNum)

DimensionDefault  (Extended data type = DimensionDefault)

Since this is just for showing off I will leave it at this

Demo_LedgerDim1

Now create a form with the same name based on the template SimpleListDetails. Add the DEMO_FinancialDimInForm table as datasource.

Add the AccountNum field to the grid. Add it to the details tab to make sure we can edit it when creating records. Create a new empty tab DimensionTab. It should end up looking more or less like this:

Demo_LedgerDim2

And now let’s move on to the cool part. Add this variable declaration to ClassDeclaration on the form:

    DimensionDefaultingController   dimensionDefaultingController;

This object does the work in handling the dimensions. And it does it without that much work from our site. In the init method add this after the super() call:

    dimensionDefaultingController = DimensionDefaultingController::constructInTabWithValues(true, true, true, 0, this, DimensionTab, "@SYS138487");
    dimensionDefaultingController.parmAttributeValueSetDataSource(DEMO_FinancialDimInForm_ds, fieldStr(DEMO_FinancialDimInForm, DimensionDefault));
    dimensionDefaultingController.pageActivated();

The first line instantiates the object which takes – among others – the formRun and the empty tab page as parameters.

The second line tells the class what data source and which field on the table it should use when handling the financial dimensions.

The third activates the class. If you have the dimensions on a separate tab page on your form you can call the pageActivated method when that tab page is activated to increase performance.

We are now getting close to the finish line. You need to add one line of code to the write, delete and active method on the data source. They should look like this:

public void delete()
{
    super();
     dimensionDefaultingController.deleted();
 }
public void write()
{
    dimensionDefaultingController.writing();
    super();
}
public int active()
{
    int ret;
    ret = super();
    dimensionDefaultingController.activated();
    return ret;
}

Done. Now open the form and watch the magic:

Demo_LedgerDim3

Updating a single dimension

The dimension structure in AX 2012 has been completely redesigned. This has a lot of advantages and a few disadvantages. One of the downsides is that all we knew before we do not know anymore.

One of the things I ended up struggling a bit with was changing a single dimension value on a given dimension set. Here is a piece of code that ended up doing the trick. If you have other and/or better solution please let me know. In this case I am updating the value of a dimension called Sub Group id based on a value from the product.

    #DimensionNames // A macro that gives me the names of the dimensions
    DimensionAttributeValueSetStorage   dimStorage;
    DimensionAttribute                  dimAttribute;
    DimensionAttributeValue             dimAttributeValue;
    EcoResProductSubGroupId             subGroupId; // The value we are going to update with

    // Get the current dimension set
    dimStorage = DimensionAttributeValueSetStorage::find(this.DefaultDimension);
    // Get the attribute we want to change
    dimAttribute = DimensionAttribute::findByName(#DimName_Subproduct_group);

    // Lookup the value we should update to
    subGroupId = EcoResProductSubGroupTable::find(EcoResProduct::find(this.Product).EcoResProductSubGroupTable).SubProductGroupId;
    // If the group id is filled in add it to the dimension set. Else clear the value in the set.
    if (subGroupId)
    {
        dimAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimAttribute, subGroupId, true, true);
        dimStorage.addItem(dimAttributeValue);
    }
    else
    {
        dimStorage.removeDimensionAttribute(DimensionAttribute::findByName(#DimName_Subproduct_group).RecId);
    }

    // Add the new dimension set record id to the record
    this.DefaultDimension = dimStorage.save();

As you can see it is a bit like InventDim … just a bit more flexible. 🙂