Showing posts with label dimensions. Show all posts
Showing posts with label dimensions. Show all posts

Tuesday, November 6, 2018

Create LedgerDimension from main account and financial dimensions

The following code will (hopefully) keep generating valid LedgerDimension values, even after account structures or advanced rule structures are modified.

In the example below, there is an account structure with MainAccount-BusinessUnit-Department segments and an advanced rule with Project segment.

class TestLedgerDim
{        
    public static DimensionDynamicAccount generateLedgerDimension(
        MainAccountNum _mainAccountId,
        str _departmentId,
        str _businessUnit,
        str _projectId)
    {
        DimensionAttributeValueSetStorage dimensionAttributeValueSetStorage 
            = new DimensionAttributeValueSetStorage();

        void addDimensionAttributeValue(
            DimensionAttribute _dimensionAttribute, 
            str _dimValueStr)
        {
            DimensionAttributeValue dimensionAttributeValue;

            if (_dimValueStr != '')
            {
                dimensionAttributeValue = 
                    DimensionAttributeValue::findByDimensionAttributeAndValueNoError(
                        _dimensionAttribute,
                        _dimValueStr);
            }

            if (dimensionAttributeValue.RecId != 0)
            {
                dimensionAttributeValueSetStorage.addItem(dimensionAttributeValue);
            }
        }

        DimensionAttribute dimensionAttribute;

        while select dimensionAttribute
            where dimensionAttribute.ViewName == tableStr(DimAttributeOMDepartment)
               || dimensionAttribute.ViewName == tableStr(DimAttributeOMBusinessUnit)
               || dimensionAttribute.ViewName == tableStr(DimAttributeProjTable)
        {
            switch (dimensionAttribute.ViewName)
            {
                case tableStr(DimAttributeOMDepartment):
                    addDimensionAttributeValue(dimensionAttribute, _departmentId);
                    break;

                case tableStr(DimAttributeOMBusinessUnit):
                    addDimensionAttributeValue(dimensionAttribute, _businessUnit);
                    break;

                case tableStr(DimAttributeProjTable):
                    addDimensionAttributeValue(dimensionAttribute, _projectId);
                    break;
            }            
        }

        RecId defaultDimensionRecId = dimensionAttributeValueSetStorage.save();

        return LedgerDimensionFacade::serviceCreateLedgerDimension(
            LedgerDefaultAccountHelper::getDefaultAccountFromMainAccountRecId(
                MainAccount::findByMainAccountId(_mainAccountId).RecId),
            defaultDimensionRecId);
    }

    /// <summary>
    /// Runs the class with the specified arguments.
    /// </summary>
    /// <param name = "_args">The specified arguments.</param>
    public static void main(Args _args)
    {   
        // Prints 110110-001-022-000002
        info(
            DimensionAttributeValueCombination::find(
                TestLedgerDim::generateLedgerDimension(
                    '110110', 
                    '022', 
                    '001', 
                    '000002')).DisplayValue);
    }

}

Wednesday, September 18, 2013

Why reading whitepapers may be useful

If you don't know how to find a list of values behind a DefaultDimension in AX 2012, Google will most likely get you to the following solution:

static void DEV_Dimension(Args _args)
{
    CustTable                         custTable = CustTable::find("1101");
    DimensionAttributeValueSetStorage dimStorage;
    Counter i;

    dimStorage = DimensionAttributeValueSetStorage::find(custTable.DefaultDimension);

    for (i=1 ; i<= dimStorage.elements() ; i++)
    {
        info(strFmt("%1 = %2", DimensionAttribute::find(dimStorage.getAttributeByIndex(i)).Name,       
                               dimStorage.getDisplayValueByIndex(i)));
    }
}


The solution above is copy-pasted all over the AX segment of the Internet.

However, there is a better way to do that:

static void ShowDimensionInOneSelect(Args _args)
{
    DefaultDimensionView defaultDimensionView;
    CustTable                       custTable;

    while select defaultDimensionView
        exists join custTable
            where custTable.AccountNum == "1101"
               && custTable.DefaultDimension == defaultDimensionView.DefaultDimension
    {
        info(strFmt("%1 = %2", defaultDimensionView.Name,
                               defaultDimensionView.DisplayValue));
    }
}

This and some other useful techniques are well described in Implementing the Account and Financial Dimensions Framework white paper.