解决API获取科目余额表时核算维度名称识别难题原创
金蝶云社区-战斗的凯文
战斗的凯文
43人赞赏了该文章 324次浏览 未经作者许可,禁止转载编辑于2023年12月15日 14:51:50

标题:解决API获取科目余额表时核算维度名称识别难题

问题:科目余额表通过API取数时,取得的核算维度结果字符串,由于没有标明维度名称,因此,当科目挂多个核算维度,如果有未录入时,无法分辨出具体维度。核算维度分裂显示可以解决这个问题,但可惜目前的API无法取到分列后的维度列。

解决方案:

二开,为科目余额表增加一个维度名称字段,用来显示带维度名称的核算维度字符串,显示格式如:

[部门]BM00001/财务部;[客户]未录入;[供应商]GYS0002/天天乐超市;

通过API查询时,指定获取上面新增字段即可。

实现方法:

1,新增并显示字段。请参考社区文章:账表增加自定义显示字段二开指南【https://vip.kingdee.com/article/11821?productLineId=1&isKnowledge=2】

注:上文中放弃了标准产品的临时,而是新生成了一个临时表,本方案建议不要新增临时表,而是在原临时表的基础上,增加一个字段即可。


2,填充字段的值。该字段的值是根据科目(FACCOUNTID)及核算维度组合ID(FDETAILID)这两个值经计算得出的。因此,在第一步中“重写报表取数逻辑”时,需要从临时表中取到这两个值,并调用下面的方法得到格式化的核算维度名称字符串,最后将字符串依次写入字段中。


注:GetDetailIdName方法是一个批量处理的集合方法,一次性收集好所有行的科目(FACCOUNTID)及核算维度组合ID(FDETAILID)作为参数传入,输出为字典格式。

        /// <summary>
        /// 获取核算维度组合的字符串名称字典
        /// </summary>
        /// <param name="ctx">上下文</param>
        /// <param name="lstDetailIDAccount">科目ID,核算维度组合ID</param>
        /// <returns>返回字典格式:key=科目内码_核算维度组合内码 value=[维度名称1]编码/名称;[维度名称2]未录入;</returns>
        public static Dictionary<string, string> GetDetailIdName(Context ctx, List<Tuple<long, long>> lstDetailIDAccount)
        {
            Dictionary<string, string> dct = new Dictionary<string, string>();
            //得到包含科目内码FACCOUNTID和FDETAILID的临时表
            var strTempTable = GetDetailIDAccountTable(ctx, lstDetailIDAccount.Distinct().ToList<Tuple<long, long>>());
            if (strTempTable != null)
            {
                // 获取核算维度明细表内码转换成编码和名称的临时表
                Tuple<List<string>, string> tup = GetFlexItemDetailDataByCol(ctx, strTempTable, null);
                var strFinalTable = tup.Item2;

                var doc = DBUtils.ExecuteDynamicObject(ctx, string.Format("SELECT * FROM {0}", strFinalTable));
                if (doc != null && doc.Count > 0)
                {
                    List<string> lstFlexFieldName = new List<string>();
                    //根据科目内码查找科目挂的维度顺序
                    Dictionary<long, List<string>> dctAcctFlex = GetAcctFlexSortFromTempTable(ctx, strTempTable, ref lstFlexFieldName);
                    if (dctAcctFlex != null && dctAcctFlex.Count > 0)
                    {
                        Dictionary<string, string> dctFlexTypeName = GetFlexTypeName(ctx);
                        StringBuilder sb = new StringBuilder();
                        string strUnknownItemName = Kingdee.BOS.Resource.ResManager.LoadKDString("【未录入】", "003195000009470", Kingdee.BOS.Resource.SubSystemType.FIN);
                        string unknownItemName = Kingdee.BOS.Resource.ResManager.LoadKDString("未录入", "003235000010356", Kingdee.BOS.Resource.SubSystemType.FIN);
                        foreach (var item in doc)
                        {
                            var lAccountId = item.GetValue<long>("FACCOUNTID");
                            var lDetailId = item.GetValue<long>("FID");
                            var strKey = string.Format("{0}_{1}", lAccountId, lDetailId);
                            List<string> lstFlex = null;
                            sb.Clear();
                            if (dctAcctFlex.TryGetValue(lAccountId, out lstFlex))
                            {
                                if (lstFlex != null && lstFlex.Count > 0)
                                {
                                    var strFlexTypeName = "N/A";
                                    foreach (var flex in lstFlex)
                                    {
                                        dctFlexTypeName.TryGetValue(flex, out strFlexTypeName);
                                        var strFlexNumber = item.GetValue<string>(string.Format("{0}_NUMBER", flex));
                                        var strFlexName = item.GetValue<string>(string.Format("{0}_NAME", flex));
                                        if ((strFlexNumber == strUnknownItemName && strFlexName == strUnknownItemName) ||
                                            (strFlexNumber.Trim().Length == 0 && strFlexName.Trim().Length == 0))
                                        {
                                            sb.AppendFormat("[{0}]{1};", strFlexTypeName, unknownItemName);
                                        }
                                        else
                                            sb.AppendFormat("[{0}]{1}/{2};", strFlexTypeName,
                                                strFlexNumber.Trim().Length == 0 ? "N/A" : strFlexNumber,
                                                strFlexName.Trim().Length == 0 ? "N/A" : strFlexName);
                                    }
                                }
                            }

                            dct[strKey] = sb.ToString();
                        }
                    }
                }
                CommonFunction.DropTempTable(ctx, new List<string>() { strTempTable, strFinalTable }, true);
            }
            return dct;
        }

        /// <summary>
        /// 获得所有维度的名称
        /// </summary>
        /// <param name="ctx"></param>
        /// <returns>FFLEXNUMBER,FNAME</returns>
        private static Dictionary<string, string> GetFlexTypeName(Context ctx)
        {
            var service = Kingdee.K3.FIN.GL.Contracts.ServiceFactory.GetService<Kingdee.K3.FIN.GL.Contracts.IGLCommonService>(ctx);
            var tup = service.GetFlexInfo(ctx);
            return tup.ToDictionary(d => d.Item1, d => d.Item2);
        }

        /// <summary>
        /// 创建科目内码FACCOUNTID和FDETAILID的临时表
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="lstDetailIDAccount">科目,核算维度组合</param>
        /// <returns>临时表名</returns>
        private static string GetDetailIDAccountTable(Context ctx, List<Tuple<long, long>> lstDetailIDAccount)
        {
            if (lstDetailIDAccount == null || lstDetailIDAccount.Count == 0) return null;

            string strTempTable = CommonFunction.GetTempTableName(ctx);
            string strCreateTableSql = string.Format("CREATE TABLE {0}(FACCOUNTID INT,FDETAILID INT)", strTempTable);
            DBUtils.Execute(ctx, strCreateTableSql);
            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("FACCOUNTID", typeof(long)));
            dt.Columns.Add(new DataColumn("FDETAILID", typeof(long)));
            dt.BeginLoadData();
            foreach (var item in lstDetailIDAccount)
            {
                DataRow row = dt.NewRow();
                row["FACCOUNTID"] = item.Item1;
                row["FDETAILID"] = item.Item2;
                dt.Rows.Add(row);
            }
            dt.EndLoadData();
            //批量插入临时表
            dt.TableName = strTempTable;
            DBUtils.BulkInserts(ctx, dt);

            return strTempTable;
        }

        //以上代码可直接使用,只需要增加合适的引用,无需修改逻辑内容



赞 43