Set financial dimension values through code in AX 2012

In Dynamics AX 2012, the dimensions framework has gone for a complete makeover. We can now have an unlimited number of financial dimensions. In Dynamics AX 4 and Dynamics AX 2009, the dimensions were actually stored as an array of string fi?>elds. This has changed in Dynamics AX 2012 where the dimension is stored as a recid. Recently I came across a requirement where if the CostCenter dimension was set to a particular value, the department dimension's value should change to a different value and vice versa.


I developed the code and thought it will be a good idea to share it here.

My requirement was in the ProjTable form but you can use this code in any of your form which uses the default financial dimensions.

Override the DefaultDimension field's dataChanged() method on your main datasource and add the below code.
// Financial dimension change code - Zubair - Begin
public void dataChanged()
{
    DimensionAttribute  dimToBeChanged;
    DimensionAttributeValue dimAttributeValue;

    boolean             triggerDimensionChange;
    str        10       valueToBeDefaulted;

    DictTable           dictTable;
    Common              common;

    FormStringControl   dimensionControl = element.selectedControl();

    super();

 // Our dimension change will trigger this method again, we dont want to skip it then.
    if (!dimensionValueChanged)
    {
        if (dimensionControl.name() == 'DimensionValue1' && dimensionControl.valueStr() == #CostCenterValue)
        {
            dimToBeChanged = dimAttributeDepartment;
            triggerDimensionChange = true;
            valueToBeDefaulted = #DepartmentValue;
        }

        if (dimensionControl.name() == 'DimensionValue2' && dimensionControl.valueStr() == #DepartmentValue)
        {
            dimToBeChanged = dimAttributeCostCenter;
            triggerDimensionChange = true;
            valueToBeDefaulted = #CostCenterValue;
        }

        if (triggerDimensionChange)
        {
            dictTable = new DictTable(dimToBeChanged.BackingEntityType);
            common = dictTable.makeRecord();

            select common where common.(fieldName2id(dimToBeChanged.BackingEntityType, #DimensionValueFieldName)) == valueToBeDefaulted;

   // Find the DimensionAttributeValue record for the dimension being changed
            dimAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndEntityInst(dimToBeChanged.RecId, common.RecId, false, true);

            // Set the new dimension value
            dimensionDefaultingController.setDimensionAttributeValue(dimToBeChanged, dimAttributeValue.RecId, valueToBeDefaulted);

            dimensionValueChanged = true;
        }
    }
    else
    {
        dimensionValueChanged = false;
    }
}
// Financial dimension change code - Zubair - End

Add the following lines in the init() method of your form after the call to super().
// Financial dimension change code - Zubair - Begin
    dimAttributeCostCenter = DimensionAttribute::findByName(#CostCenterDimension);
    dimAttributeDepartment = DimensionAttribute::findByName(#DepartmentDimension);
// Financial dimension change code - Zubair - End

Add the following lines in the classDeclaration of the form.
// Financial dimension change code - Zubair - Begin
    DimensionAttribute  dimAttributeCostCenter;
    DimensionAttribute  dimAttributeDepartment;

    boolean             dimensionValueChanged;

    #define.CostCenterDimension('CostCenter')
    #define.DepartmentDimension('Department')
    #define.CostCenterValue('OU_3569')
    #define.DepartmentValue('OU_2561')
    #define.DimensionValueFieldName('Value')
// Financial dimension change code - Zubair - End

Thats it. Now try changing the value of the CostCenter dimension to OU_3569. Notice that the value in Department to OU_2561.

Hope this snippet will be useful if you have a similiar requirement or atleast you know how it can be done now.

Feel free to mail me or comment here if you need help with understanding the code.

Comments

Anonymous said…
Hi,

Excellent post. Thanks for posting this information, it was a good read.

I have a question. Is it possible to separate the dimensions into separate fields on a grid? Say for instance, in a grid, department, cost center and purpose are separate drop down fields, yet all relate back to the ledger dimension field.

Thanks,

Francis
Amar said…
Hello Zubair,

Thanks for the excellent post and sharing the knowledge with the world.

In addition to this requirement, I will need to disable (non-editable) the financial dimension 'Department' whenever 'CostCenter' is changed.

Please let me know how can we achieve this.

Thanks,
Amar
Zubair Ahmed said…
Hi Amar,

You can disable the controls by checking for its name and disabling it.

dimensionControl.enabled(dimensionControl.name() == 'DimensionValue1');
Amar said…
Hi Zubair,

Thanks for the reply.

I have applied the code provided and see that it only disables the current selected financial dimension even though I provided the other financial dimensions control name. I think this is happening as 'dimensionControl' is always picking the selected control 'element.selectedControl()'.

Please let me know how to disable the other controls.

Thanks in advance,
Amar
Aslam said…
I am knew to AX,Can you tell me about what is the mean of Financial dimension
why we use it ..base leval not in ax general words
If anyone can help me understand this linking I would greatly appreciate it. I will check back for any replies or you can email me at Aslammd111@gmail.com Thanks
Aslam said…
I am knew to AX,Can you tell me about what is the mean of Financial dimension
why we use it ..base leval in ax general words
If anyone can help me understand this linking I would greatly appreciate it. I will check back for any replies or you can email me at Aslammd111@gmail.com Thanks
Zubair Ahmed said…
Hi Ashu,

Financial Dimensions in AX 2009 and AX 2012 provide a means to create additional segments to the main or natural general ledger account in order to track revenues, costs or expenses by a specific attribute, without having to have the segment be imbedded in the natural account itself. Additionally, these dimensions can also be linked to vendors and customers in order to facilitate the dimension tracking for a multitude of transactions. Standard functionality in AX 2009 offers the three predefined dimensions of Department, Cost Center and Purpose. A big upgrade in AX 2012 is the ability for users to create an unlimited number of Financial Dimensions and link them in any combination to vendors, customers and the chart of accounts, creating one or more Financial Dimension sets or structures. These dimension sets can then be used to establish reporting structures, as well as in the validation of data entered for transactions, minimizing errors. Financial Dimensions offers the flexibility to continue to customize your chart of accounts and data analysis based on your business’ growth and needs.
Zubair Ahmed said…
Hi Amar,

U'll have to loop thru all the controls in the form's design as u cant readily find this control coz its added dynamically.

What you can do is use element.design().controlNum(i).

Use element.design().controlCount() to get a count of all controls on the form.


This will return a formControl object, check for the control's name and then disable it.

Popular posts from this blog

How to add empty ranges in query

The field with ID '0' does not exist in table - Cause and resolution.

Get selected records in Dynamics AX 2012