2012年6月1日星期五

批量给多个表的Dimension字段赋初值

[需求]
最近遇到这样一个需求,在实施的时候把系统现有的三个纬度前两个分别用于记录分公司和部门,在做财务凭证或者销售采购订单的时候,需要给这些表相应的Dimension字段的前两个纬度赋值,用户要求根据当前用户所属的分公司和部门直接赋值,而不想自己去选择。
[分析] 最直观的想法就是修改各个表的InitValue()方法,给相应的表赋初值,不过这样的工作量有些大,要修改多个表,并且当需要赋初值的表增加时还需要继续修改相应的表。
AX中用Map实现表方法的共享,于是考虑用Map来实现这个功能。
只有Map还是不行的因为InitValue()这个方法还是在各个表上的,好在AX为了使用模板,所有的initValue()方法都会调用类classFactory的CreateRecord()方法,所以可以把代码添加到这里。
[解决方案]1.创建DimensionMap
创建名为DimensionMap的Map,添加字段Dimension,设定其EDT属性为Dimension,然后把需要设定初始值的表与该Map用Dimension字段建立影射。
2.写一个工具类SysUtility,添加根据当前用户获取部门和分公司的方法
http://www.cnblogs.com/Farseer1215/archive/2007/04/20/721585.html
static Container GetComanpyAndDepartmentOfCurrentUser()
{
Container c;
EmplTable emplTable;
;
select Dimension from emplTable
where emplTable.EmplId
== curuserid();

if(emplTable.Dimension[1]&&emplTable.Dimension[2])
return [emplTable.Dimension[1],emplTable.Dimension[2]];
else
throw Error("@GCN588");
}
在这个工具类里再添加一个方法,用于判断表是否需要给Dimension赋初值,判断的标准是如果该表包含在DimensionMap中则需要赋初值,否则不需要

static anytype IfNeedInitDimension(TableId tableId)
{
#AOT
SysGlobalCache sysGlobalCache
= classFactory.globalCache();
TreeNode treeNodeMap;
TreeNode treeNodeMapTable;
Name mapTableName;
str strPath;
;

//如果在全局缓存中没有对应的纪录,则添加之
if(!sysGlobalCache.elements(TableStr(DimensionMap)))
{
//找到Map的Mapping路径
strPath = strFmt(#TableMapsPath+@"\%1\Mappings",TableStr(DimensionMap));

treeNodeMap
= TreeNode::findNode(strPath);
treeNodeMapTable
= treeNodeMap.AOTfirstChild();

while(treeNodeMapTable)
{
//将属性添加到全局缓存
mapTableName = treeNodeMapTable.AOTgetProperty("MappingTable");
sysGlobalCache.
set(TableStr(DimensionMap),tableName2Id(mapTableName),mapTableName);
treeNodeMapTable
= treeNodeMapTable.AOTnextSibling();
}

}

return sysGlobalCache.get(TableStr(DimensionMap),tableId,false);

}
3.在DimensionMap中添加方法,给表赋初值

void InitDimension()
{
str
10 dirCompany;
str
10 dirDepartment;
;
[dirCompany,dirDepartment]
= SysUtility::GetComanpyAndDepartmentOfCurrentUser();
this.Dimension[1] = dirCompany;
this.Dimension[2] = dirDepartment;

}
4.在classFactory的CreateRecord方法中添加代码调用DimensionMap的方法给相关表的Dimension字段赋初值

void createRecord(Common common)
{
SysRecordTemplate sysRecordTemplate;
;
if (! common.isTmp() && new SysDictTable(common.TableId).isRecordTemplateEnabled())
{
sysRecordTemplate
= SysRecordTemplate::newCommon(common);
sysRecordTemplate.createRecord();
}


//赋予初始值
if(SysUtility::IfNeedInitDimension(common.TableId))
{
common.DimensionMap::InitDimension();
}

}

没有评论:

发表评论