【二开指导】如何根据部门编码生成对应的维度组合ID
二开生成凭证,其中遇到的最大难点就是如何根据一个或多个核算项目的编码生成对应的维度组合ID。这里以已知部门编码生成对应的维度组合ID如例。
首先,需要查询得到部门的维度标识是什么,可以用以下SQL脚本得到:
SELECT TM.FID,FFLEXNUMBER,FFORMID,FTABLENAME,PL.FNAME,FSTRATEGYTYPE,CASE FSTRATEGYTYPE WHEN 1 THEN '共享' WHEN 2 THEN '分配' WHEN 3 THEN '私有' ELSE 'UNKNOW' END FSTRATEGYTYPENAME, FMASTERIDFIELDNAME,FNUMBERFIELDNAME,FNAMEFIELDNAME,FORGFIELDNAME,FPKFIELDTYPE,FPKFIELDNAME,FNAMEISLOCALE FROM ( SELECT C.FID,C.FFLEXNUMBER,A.FFORMID, ISNULL(A.FTABLENAME,' ') FTABLENAME, ISNULL(BT.FSTRATEGYTYPE,1) FSTRATEGYTYPE, CASE WHEN LEN(ISNULL(A.FMASTERIDFIELDNAME,' ')) <= 1 THEN A.FPKFIELDNAME ELSE A.FMASTERIDFIELDNAME END FMASTERIDFIELDNAME, A.FNUMBERFIELDNAME, A.FNAMEFIELDNAME,A.FORGFIELDNAME, A.FPKFIELDTYPE, A.FPKFIELDNAME,A.FNAMEISLOCALE FROM T_META_LOOKUPCLASS A LEFT JOIN T_BD_FLEXITEMPROPERTY C ON A.FFORMID=C.FVALUESOURCE LEFT JOIN T_META_BASEDATATYPE BT ON BT.FBASEDATATYPEID=C.FVALUESOURCE WHERE C.FVALUETYPE='0' AND C.FDOCUMENTSTATUS='C' UNION ALL SELECT DISTINCT C.FID,C.FFLEXNUMBER,C.FVALUESOURCE FFORMID, 'T_BAS_ASSISTANTDATAENTRY' FTABLENAME, 1 FSTRATEGYTYPE, 'FMASTERID' FMASTERIDFIELDNAME, 'FNUMBER' FNUMBERFIELDNAME, 'FDATAVALUE'FNAMEFIELDNAME,'FUSEORGID' FORGFIELDNAME, 2 FPKFIELDTYPE, 'FENTRYID' FPKFIELDNAME,1 FNAMEISLOCALE FROM T_BD_FLEXITEMPROPERTY C WHERE C.FVALUETYPE='1' AND C.FDOCUMENTSTATUS='C' ) TM LEFT JOIN T_BD_FLEXITEMPROPERTY_L PL ON PL.FID=TM.FID AND PL.FLOCALEID=2052 ORDER BY TM.FID
结果如下图所示,FFLEXNUMBER列就是对应维度的标识列:
同时,官方预置的核算维度及标识如下(注意:因数据存在人为改动的可能,以下仅供参考):
供应商 BD_Supplier FFLEX4
部门 BD_Department FFLEX5
客户 BD_Customer FFLEX6
员工 BD_Empinfo FFLEX7
物料 BD_MATERIAL FFLEX8
费用项目 BD_Expense FFLEX9
资产类别 FA_ASSETTYPE FFLEX10
组织机构 ORG_Organizations FFLEX11
物料分组 AMB_MaterialGroup FFLEX12
客户分组 AMB_CustomerGroup FFLEX13
银行 BD_BANK FFLEX14
银行账户 CN_BANKCNT FFLEX15
其他往来单位 FIN_OTHERS FFLEX16
也可以在前端查询核算维度标识,方法为:打开【核算维度】界面,默认不显示维度列标识,可以点【过滤】打开过滤界面的【显示隐藏列】,勾选【单据头-维度列标识】,确定。如下图所示:
可见,部门的维度标识为FFLEX5。
其次,就是根据部门的编码,得到该编码在当前账簿核算组织下的主内码(FMASTERID)。根据部门基础资料控制策略的不同(基础资料控制策略分为共享,分配和私有三种,可以通过前面提供的SQL脚本查到),但取数方式基础相同,因为总账核算维度中统一使用其主内码FMASTRID来存储维度信息,实际脚本中可以取内码行于主内码的那条记录。
注:查询时用到的内码字段名(FDEPTID)、主内码字段名(FMASTERID)、表名(T_BD_DEPARTMENT)和编码字段的名称(FNUMBER)等的具体字段名称,可以从前面提供的SQL脚本中得到:
即:
SELECT FMASTERID FROM T_BD_DEPARTMENT WHERE FNUMBER='BM000007' AND FDEPTID=FMASTERID
可见,编码为“BM00007”的部门的主内码为100518,
第三步,在得到维度列标识FFLEX5和主内码100518后,最关键的一点就是生成相应的核算维度对象。以下给出详细示例代码:
#给核算维度对象中的具体维度项赋值 : //给指定行的核算维度指定具体的维度值 public void SetFlexValue(long iRow, object FlexItems) { // 获取指定行的维度对象 var objDetail = GetFlexItemDetailID(iRow); //依次给需要赋值的核算项目赋值,FlexItems为需要赋值的各核算项目,包含维度标识(如:供应商ItemDBField="FFLEX4")以及对应的维度的FMASTERID值(如:id=1000001),FlexItems中包含的核算项目必须和该行科目所挂的核算维度一致,否则可能保存不成功。 foreach (var item in FlexItems)//待赋值的具体维度项 { string key = item.ItemDBField.Substring(1) + "_Id"; //赋值ID if (objDetail.DynamicObjectType.Properties.ContainsKey(key)) { objDetail[key] = item.id;//该维度项的FMasterID值,注意,不能是FID } else if (objDetail.DynamicObjectType.Properties.ContainsKey(item.ItemDBField)) { objDetail[item.ItemDBField] = item.id; } } //给指定行设置核算维度值 var FDetailID = SaveFlexItemDetailID(iRow,objDetail); } #region 获取核算维度组ID /// <summary> /// 获取指定行的维度数据结构 /// </summary> private DynamicObject GetFlexItemDetailID(int iRow) { DynamicObject dyObj = this.View.Model.GetValue(Col_DetailID, iRow) as DynamicObject; if (dyObj == null) { //生成一个新的核算维度对象: var detailvObjtype = FormMetaDataCache.GetCachedFormMetaData(this.Context, "BD_FLEXITEMDETAILV").BusinessInfo.GetDynamicObjectType(); return detailvObjtype.CreateInstance() as DynamicObject; } return dyObj; } /// <summary> /// 生成核算维度组ID,并给指定行上的核算维度赋值 /// </summary> /// <param name="iRow"></param> /// <param name="dyObject">核算维度对象</param> /// <returns></returns> private long SaveFlexItemDetailID(int iRow, DynamicObject dyObject) { long fID = GLFlexServiceHelper.SaveFlexItemDetailID(this.Context, dyObject); //得到真正的核算维度组织ID,这个才是凭证是FDETAILID_ID的值。 SetDetailID(fID, iRow, dyObject); return fID; } /// <summary> /// 直接赋值给指定行中维度组的堆栈中 /// </summary> /// <param name="iDetailID"></param> /// <param name="iRow"></param> /// <param name="dyObject">核算维度对象</param> private void SetDetailID(long iDetailID, int iRow, DynamicObject dyObject) { DynamicObjectCollection dyCol = GetEntityDynamicObject("FENTITY");//获取单据体数据集 DynamicObject dy = dyCol.Where<DynamicObject>(p => Convert.ToInt32(p["Seq"]) == iRow + 1).SingleOrDefault();//单据体行数据 if (dy != null) { //给指定行上的核算维度赋值 dy["DetailID_Id"] = iDetailID; dy["DetailID"] = dyObject; } } #endregion 获取核算维度组ID
有了上面的方法,只需要调用SetFlexValue(),就可以为指定行生成对应的核算维度组合对象的值了。
关于上面用到FlexItems对象的说明:它是一个集合对象,集合中每一个元素表示 一个核算维度,如部门,它至少包含两个属性,其中一个就是维度标识列,另一个就是对应的主内码。当需要为一个核算维度组合对象指定多个不同的核算项目时,这个集合对象就包含多个元素。上面的方法封装了具体生成核算维度组合ID(FDETAILID)的过程,但语句:
var FDetailID = SaveFlexItemDetailID(iRow,objDetail)
即可以直接得到这个值。
推荐阅读