【二开指导】如何根据部门编码生成对应的维度组合ID原创
金蝶云社区-战斗的凯文
战斗的凯文
79人赞赏了该文章 752次浏览 未经作者许可,禁止转载编辑于2023年05月06日 19:10:42

【二开指导】如何根据部门编码生成对应的维度组合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列就是对应维度的标识列:

image.png


        同时,官方预置的核算维度及标识如下(注意:因数据存在人为改动的可能,以下仅供参考):

        供应商  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

        也可以在前端查询核算维度标识,方法为:打开【核算维度】界面,默认不显示维度列标识,可以点【过滤】打开过滤界面的【显示隐藏列】,勾选【单据头-维度列标识】,确定。如下图所示:

image.png

        可见,部门的维度标识为FFLEX5。

        其次,就是根据部门的编码,得到该编码在当前账簿核算组织下的主内码(FMASTERID)。根据部门基础资料控制策略的不同(基础资料控制策略分为共享,分配和私有三种,可以通过前面提供的SQL脚本查到),但取数方式基础相同,因为总账核算维度中统一使用其主内码FMASTRID来存储维度信息,实际脚本中可以取内码行于主内码的那条记录。

        注:查询时用到的内码字段名(FDEPTID)、主内码字段名(FMASTERID)、表名(T_BD_DEPARTMENT)和编码字段的名称(FNUMBER)等的具体字段名称,可以从前面提供的SQL脚本中得到:

image.png

        即:

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)

即可以直接得到这个值。


赞 79