[AX2012]关于财务默认维度

和以前的版本一样,AX2012中很多地方都使用财务维度,比如客户、销售订单、销售订单行等,根据相应的财务维度设置,生成的相应财务分录将带有财务维度,方便后续对财务分录交易的分析。下图是在客户记录上设置默认财务维度的情况:

默认财务维度只包括CostCenter、Department和ExpensePurpose,如果要象上图要添加显示其他的财务维度,在以前的版本中需要编程实现,但是在AX2012我们只需要配置即可实现。

首先需要创建相应的财务维度(General ledger>Setup>Financial dimensions>Financial dimensions,表DimensionAttribute的一条记录对应一个财务维度):

 需要注意的是“use values from”选项,系统集成了几种维度值来源,比如这里维度“Customer”的维度取值为“Customers”,维度的值将来自于CustTable表由系统自动生成不能手工添加(其实来自于视图DimAttributeCustTable)。“use values from”可以是“<Custom dimension>”,这种维度的维度值是手工维护的,点击“Financial dimension values”可以维护维度的值列表:

维度“Customer”取值来自于系统,所以上图中是不能修改维度取值的,“new”、“delete”等按钮是灰化的。

创建的财务维度我们需要添加到相应公司的总账账号结构中,找到General ledger>Setup>Ledger:

Account structures有两条记录,选择一条记录点击“Config account structure”:

上图中我们把“Customer”和“Vendor”添加到默认的总账账号结构中,激活后我们在客户记录的默认财务维度中就能看到“Customer”和“Vendor”两个维度了。

再来看看相关的数据是如何保存的,客户表CusTable.DefaultDimension保存的是来自于DimensionAttributeValueSet表的一条记录RecId,表单上维度信息的显示与编辑由类DimensionDefaultingController实现,它用下面的代码根据DimensionAttributeValueSet.RecId获取各个维度的设置值:

protected container getAttributeValueSet(DimensionDefault _dimAttributeValueSetId, selectableDataArea _company)
{
    return DimensionControllerObject::getAttributeValueSetServer(_dimAttributeValueSetId, _company);
}

这里用到另外一个表DimensionAttributeValueSetItem,假设我们在图1中同时设置客户的Department和Department两个财务维度,这个过程会创建1条DimensionAttributeValueSet记录和2条DimensionAttributeValueSetItem记录:

  • DimensionAttributeValueSetItem.DimensionAttributeValueSet 字段 -> DimensionAttributeValueSet.RecId
  • DimensionAttributeValueSetItem.DimensionAttributeValue 字段 -> DimensionAttributeValue.RecId (该表的一条记录保存财务维度的一个取值)
  • DimensionAttributeValue.DimensionAttribute 字段 -> DimensionAttribute.RecId

通过关联查询这几个表,我们就能查找出CustTable.DefaultDimension所代表的一组Dimension及其值的组合。DimensionAttributeValueSet表只有一个字段Hash,且被设置为不能重复的索引,它表示的是其代表的一组维度值HashKey经过运算后得到的哈希值,存放在表DimensionAttributeValueSet以表示这样的财务组合已经存在,以防止重复生成相应的维度组合。

在有一定的了解后,我们来看看如何通过代码设置默认维度:

static void setCustTableDefaultFinancialDimension(Args _args)

{

    #LedgerSHA1Hash

    DimensionSHA1Hash               hash; //To store the calculated hash for DimensionAttributeValueSet
    HashKey                         valueKeyHashArray[]; //To store the has key of dimension in question
    Map                             dimAttrIdx; //to store the dimension index and backing entity type
    DimensionAttributeSetItem       dimAttrSetItem; // Contains the number of dimensions active for a account structure ledger
    DimensionAttribute              dimAttr; // Contains the financial dimensions records
    DimensionAttributeValue         dimAttrValue; // Contains used financial dimension values
    DimensionAttributeValueSet      dimAttrValueSet; //Contains default dimension records
    DimensionAttributeValueSetItem  dimAttrValueSetItem; //Contains individual records for default dimensions
    DimAttributeCustTable           dimAttrCustTable; //Backing entity view for Employee type dimension
    DimensionEnumeration            dimensionSetId; //Record id for table that contains active dimensions for current ledger
    CustTable                       custTable; //Record of the customer used to set the dimension

    int dimAttrCount, i;
    int custBackEntityType; //Stores the backing entity type for Employee type dimension
    ;

    //The employee backing entity will be the view DimAttributeHcmWorker
    custBackEntityType = tableNum(DimAttributeCustTable);

    //Initialize the map to store the backing entity types
    dimAttrIdx = new Map(Types::Integer, Types::Integer);

    //Get the record Id (dimension set id) for current ledger to find active dimensions
    dimensionSetId = DimensionCache::getDimensionAttributeSetForLedger();

    //Find all the active dimensions for current ledger except main account and store there
    //backing entity type in the map
    while select * from dimAttr
        order by Name
            where dimAttr.Type != DimensionAttributeType::MainAccount
        join RecId from dimAttrSetItem
            where dimAttrSetItem.DimensionAttribute == dimAttr.RecId &&
                dimAttrSetItem.DimensionAttributeSet == dimensionSetId
    {
        dimAttrCount++;
        dimAttrIdx.insert(dimAttr.BackingEntityType, dimAttrCount);
        info(dimAttr.Name);
    }

    //initialize hash key array to null
    for (i = 1; i<= dimAttrCount; i++)
        valueKeyHashArray[i] = emptyGuid();


    //Find the Dimension attribute record for the dimension to work on
    dimAttr.clear();
    select firstonly dimAttr
        where dimAttr.BackingEntityType == custBackEntityType;

    //Get the backing entity type for the dimension value to process
    select firstOnly dimAttrCustTable
        where dimAttrCustTable.Value == '1101';

    //Find the required Dimension Attribute Value record
    //Create if necessary
    dimAttrValue = DimensionAttributeValue::findByDimensionAttributeAndEntityInst(dimAttr.RecId, dimAttrCustTable.RecId, false, true);

    //Store the required combination hash keys
    valueKeyHashArray[dimAttrIdx.lookup(custBackEntityType)] = dimAttrValue.HashKey;

    //Calculate the hash for the current values
    hash = DimensionAttributeValueSetStorage::getHashFromArray(valueKeyHashArray, dimAttrCount);

    //Null hash indicates no values exist, which may occur if the user entered an invalid value for one dimension attribute
    if (hash == conNull())
    {
        throw error("Wrong value for Customer Dimension");
    }

    // Search for existing value set
    dimAttrValueSet = DimensionAttributeValueSet::findByHash(hash);

    // This value set does not exist, so it must be persisted
    if (!dimAttrValueSet)
    {
        ttsbegin;

        // Insert the value set with appropriate hash
        dimAttrValueSet.Hash = hash;
        dimAttrValueSet.insert();

        //Insert Customer dimension set item
        dimAttrValueSetItem.clear();
        dimAttrValueSetItem.DimensionAttributeValueSet = dimAttrValueSet.RecId;
        dimAttrValueSetItem.DimensionAttributeValue = dimAttrValue.RecId;
        dimAttrValueSetItem.DisplayValue = dimAttrCustTable.Value;
        dimAttrValueSetItem.insert();


        ttscommit;

    }

    //Update the customer default dimension field
    ttsBegin;
    select forUpdate custTable where custTable.AccountNum == '1101';
    custTable.DefaultDimension = dimAttrValueSet.RecId;
    custTable.Update();
    ttsCommit;


    info(strFmt("%1", dimAttrValueSet.RecId));

}

上面代码参考http://sumitsaxfactor.wordpress.com/2011/12/28/defaulting-financial-dimensions-ax-2012/,设置客户代码为“1101”客户的“Customer”维度为其自身。

代码更改默认维度还有其他一些方法,在以后的文章中再讨论。

posted @ 2013-08-07 15:51  断水流  阅读(3096)  评论(0编辑  收藏  举报