报表插件源码解读收获原创
金蝶云社区-abstrct
abstrct
97人赞赏了该文章 387次浏览 未经作者许可,禁止转载编辑于2024年09月15日 18:10:36
summary-icon摘要由AI智能服务提供

文本主要描述了一个关于采购执行明细报表的问题、需求及解决方案的探讨。问题在于现有的报表太过精细,包含了业务部门不需要的多个环节数据。需求是精简报表,仅保留采购申请、采购、来料、入库等环节的数据,并基于这些数据对采购和入库的及时性进行分析和考核。解决方案尝试通过直接SQL报表重新开发报表,但遇到无法添加权限项的问题。随后,作者通过反编译插件源码,尝试使用直接SQL数据源替代临时表来开发报表,但在确保数据关联关系正确性方面遇到了挑战。最后,展示了部分源码中的关联关系构建代码。

一.问题与需求

  1. 书接上回。采购申请执行明细报表,太过精细。从采购申请,采购,来料,入库,退料,检验,暂估付款,财务付款的一个全流程的数据。

  2. 业务部门只需要采购申请,采购,来料,入库。后面的都不需要。在这个数据基础上,对需求日期,到货日期,来货,入库。

  3. 对采购事宜,进行一个报表。分析他们采购是否及时,入库是否及时。入库率反应采购质量等维度的一个考核或者分析。

    那么这个报表我其实只需要减少一些关联关系,就可以出的。用是可以用的,但是用起来不方便。一个财务有暂估和财务应付,当财务数据出现核销时候,他们采购数据更多看起来重复的数据了。

二.解决方案

    1.方案1

                做个直接sql报表,重新开发个报表,什么问题都解决了。

    2.

                我就是这么想,这么做的时候。发现我做的直接sql报表好像加不了权限项。在社区找了下答案,大概率是没有买报表模块。发出采购的话,走流程的话。这个月就基本别想了。在社区逛的的时候,发现个替代方案。今天就是这个方案的真实实践。

    3.        开发账表是没问题的,开发账表插件也是没问题的。那么我在账表插件的时候,直接用直接sql的数据源替代原来的临时表可行么?按道理是可行的,单具体还是得做了才知道。

    4.       先在BOS划个简单账表。在直接用原来(采购申请执行明细)的过滤,原来得界面参数。这个工作就少了几分。

    5.       直接sql数据源整理。花了点时间还是整出来了。但是问题来了,我的关联怎么确保是正确的呢?关联关系这些我都知道,甚至我都执行了这个sql,但是怎么确保数据正确性呢?比较你一个订单,我多次入库,你用数量条数也无法确定是一一对应的。

    6.      不知道怎么回事,反正在一个不懂开发的同事交谈中,他就是叫我改,改成他们的样子,我回答到,这个封装的,我无法改数据源,我无法改他们的数据源,我无法改他们的数据源么?我明白了,我要搞他的源码。

    7.     打开BOS找到原来的插件,打开反编译工具。这就是源码的关联关系了。

取数:

// Kingdee.K3.SCM.App.Purchase.Report.PurReqExecuteRpt
// Token: 0x0600022C RID: 556 RVA: 0x00036C74 File Offset: 0x00034E74
public void GetDataSource(string rptFilterTable)
{
    string entityKey = "FEntity";
    long[] entryIds = this.GetEntryIds(base.Context, rptFilterTable, out this.filterSql);
    List<string> lstTable = new List<string>();
    if (entryIds.Length > 0)
    {
        BusinessFlowDataService businessFlowDataService = new BusinessFlowDataService();
        BuildBFTrackerTempTableArgs buildBFTrackerTempTableArgs = new BuildBFTrackerTempTableArgs("PUR_Requisition", entityKey, entryIds);
        buildBFTrackerTempTableArgs.OnTime = this.onTime;
        string text = PurchaseRptCommon.ReadEntryTableName(base.Context, "PUR_Requisition", entityKey);
        buildBFTrackerTempTableArgs.FirstTableName = text;
        buildBFTrackerTempTableArgs.IsNewTracker = true;
        buildBFTrackerTempTableArgs.IsInt64 = true;
        buildBFTrackerTempTableArgs.TableNames.Add(text);
        buildBFTrackerTempTableArgs.TableNames.Add(PurchaseRptCommon.ReadEntryTableName(base.Context, "PUR_PurchaseOrder", "FPOOrderEntry"));
        buildBFTrackerTempTableArgs.TableNames.Add(PurchaseRptCommon.ReadEntryTableName(base.Context, "PUR_ReceiveBill", "FDetailEntity"));
        buildBFTrackerTempTableArgs.TableNames.Add(PurchaseRptCommon.ReadEntryTableName(base.Context, "STK_InStock", "FInStockEntry"));
        buildBFTrackerTempTableArgs.TableNames.Add(PurchaseRptCommon.ReadEntryTableName(base.Context, "PUR_MRB", "FPURMRBENTRY"));
        buildBFTrackerTempTableArgs.TableNames.Add(PurchaseRptCommon.ReadEntryTableName(base.Context, "AP_Payable", "FEntityDetail"));
        buildBFTrackerTempTableArgs.TableNames.Add("T_QM_INSPECTBILLENTRY");
        buildBFTrackerTempTableArgs.TableNames.Add("T_QM_INSPECTBILLENTRY_A");
        BuildBFTrackerTempTableResult buildBFTrackerTempTableResult = businessFlowDataService.BuildBFTrackerTempTable(base.Context, buildBFTrackerTempTableArgs);
        if (buildBFTrackerTempTableResult != null)
        {
            string tempTableName = buildBFTrackerTempTableResult.TempTableName;
            this.deleteTables.Add(tempTableName);
            lstTable = buildBFTrackerTempTableResult.TableColumns;
            this.DeleteRepeatData(base.Context, lstTable, tempTableName, buildBFTrackerTempTableResult.SIDColumnsAlias);
            PurchaseRptCommon.GetNeedDataByFields(base.Context, lstTable, tempTableName, this.flowDataTable, buildBFTrackerTempTableResult.SIDColumnsAlias);
            this.InsertFlowData(base.Context, lstTable, this.flowDataTable, tempTableName, buildBFTrackerTempTableResult.RepeateColumnAlias, buildBFTrackerTempTableResult.SIDColumnsAlias, "T_PUR_ReqEntry");
            this.deleteTables.Add(this.flowDataTable);
            this.InsertFlowData(base.Context, this.flowTable, lstTable, this.flowDataTable, this.filterSql, this.showOtherFlow);
            if (this.tempTableList == null || this.tempTableList.Count <= 0)
            {
                return;
            }
            using (List<string>.Enumerator enumerator = this.tempTableList.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    string item = enumerator.Current;
                    this.deleteTables.Add(item);
                }
                return;
            }
        }
        this.InsertCustomFlowData(base.Context);
    }
}

关联关系:

stringBuilder.AppendLine(string.Format(" FROM {0} T1 ", this.flowTable));
    stringBuilder.AppendLine(" INNER JOIN T_PUR_REQENTRY TCT ON T1.FREQID=TCT.FENTRYID ");
    stringBuilder.AppendLine(" INNER JOIN T_PUR_REQUISITION TCH ON TCH.FID=TCT.FID ");
    stringBuilder.AppendLine(" INNER JOIN T_PUR_REQENTRY_S TCTS ON TCT.FENTRYID=TCTS.FENTRYID ");
    stringBuilder.AppendLine(" LEFT JOIN T_BD_STAFF TS ON TS.FSTAFFID = TCH.FAPPLICANTID");
    stringBuilder.AppendFormat(" LEFT JOIN T_BD_STAFF_L TSL ON TSL.FSTAFFID = TCH.FAPPLICANTID AND TSL.FLOCALEID={0}", base.Context.UserLocale.LCID);
    stringBuilder.AppendLine(string.Format(" LEFT JOIN T_BAS_BILLTYPE_L BL ON BL.FBILLTYPEID=TCH.FBILLTYPEID AND BL.FLOCALEID={0}", base.Context.UserLocale.LCID));
    stringBuilder.AppendLine(" LEFT JOIN T_PUR_POORDERENTRY TPUR ON T1.FORDERID=TPUR.FENTRYID  ");
    stringBuilder.AppendLine(" LEFT JOIN T_BD_MATERIAL TPURMATE ON TPUR.FMATERIALID = TPURMATE.FMATERIALID  ");
    stringBuilder.AppendLine(string.Format(" LEFT JOIN T_BD_MATERIAL_L TPURMATEL ON TPURMATE.FMATERIALID = TPURMATEL.FMATERIALID AND TPURMATEL.FLOCALEID={0} ", base.Context.UserLocale.LCID));
    stringBuilder.AppendLine(" LEFT JOIN T_PUR_POORDERENTRY_F TPURF ON TPUR.FENTRYID =TPURF.FENTRYID  ");
    stringBuilder.AppendLine(" LEFT JOIN T_PUR_POORDERENTRY_D TPURD ON TPUR.FENTRYID =TPURD.FENTRYID  ");
    stringBuilder.AppendLine(" LEFT JOIN T_PUR_POORDER TPOR ON TPUR.FID=TPOR.FID ");
    stringBuilder.AppendLine(" LEFT JOIN T_STK_INSTOCKENTRY TIN ON T1.FINSTOCKID=TIN.FENTRYID ");
    stringBuilder.AppendLine(" LEFT JOIN T_STK_INSTOCKENTRY_F TINF ON TINF.FENTRYID=TIN.FENTRYID ");
    stringBuilder.AppendLine(" LEFT JOIN T_STK_INSTOCK TINS ON TIN.FID=TINS.FID  ");
    stringBuilder.AppendLine(" LEFT JOIN T_PUR_RECEIVEENTRY TRE ON T1.FRECEIVEID=TRE.FENTRYID");
    stringBuilder.AppendLine(" LEFT JOIN T_PUR_RECEIVEENTRY_F TREF ON TREF.FENTRYID=TRE.FENTRYID");
    stringBuilder.AppendLine(" LEFT JOIN T_PUR_RECEIVE TRC ON TRE.FID=TRC.FID ");
    stringBuilder.AppendLine(" LEFT JOIN T_PUR_MRBENTRY TMR ON T1.FRETURNID=TMR.FENTRYID  ");
    stringBuilder.AppendLine(" LEFT JOIN T_PUR_MRBENTRY_F TMRF ON TMRF.FENTRYID=TMR.FENTRYID  ");
    stringBuilder.AppendLine(" LEFT JOIN  T_PUR_MRB TMRB ON TMR.FID=TMRB.FID ");
    stringBuilder.AppendLine(" LEFT JOIN T_AP_PAYABLEENTRY TPAYE ON T1.FPAYID=TPAYE.FENTRYID ");
    stringBuilder.AppendLine(" LEFT JOIN T_AP_PAYABLE TPAY ON TPAY.FID=TPAYE.FID ");
    stringBuilder.AppendLine(" LEFT JOIN (SELECT FTARGETBILLID,FTARGETENTRYID, SUM(ISNULL(FCUROPENAMOUNTFOR,0)) AS FCUROPENAMOUNTFOR FROM T_AP_BillingMatchLogEntry ");
    stringBuilder.AppendLine(" WHERE FTARGETFROMID='AP_Payable' AND FISADIBILL='1' GROUP BY FTARGETENTRYID,FTARGETBILLID) TB1 ON TB1.FTARGETENTRYID=TPAYE.FENTRYID ");
    stringBuilder.AppendFormat(" LEFT JOIN {0} RECNO ON RECNO.FRECID=T1.FORDERID", this.recPayablenoTable);
    stringBuilder.AppendFormat(" LEFT JOIN {0} TBNO ON TBNO.FRECID=TPAYE.FENTRYID", this.payablenoTable);
    stringBuilder.AppendFormat(" LEFT JOIN {0} TINO ON TINO.FRECID=TPAYE.FENTRYID", this.invoceBillnoTable);
    stringBuilder.AppendFormat(" LEFT JOIN T_PUR_ReqEntry_L TPOL ON TPOL.FENTRYID=TCT.FENTRYID  AND TPOL.FLOCALEID={0}", base.Context.UserLocale.LCID);
    stringBuilder.AppendLine(" LEFT JOIN T_BD_CURRENCY CU ON CU.FCURRENCYID=TCH.FCURRENCYID ");
    stringBuilder.AppendFormat(" LEFT JOIN T_BD_CURRENCY_L TCU ON TCU.FCURRENCYID=TCH.FCURRENCYID  AND TCU.FLOCALEID={0}", base.Context.UserLocale.LCID);
    stringBuilder.AppendFormat(" LEFT JOIN T_BD_DEPARTMENT_L TDEPTL ON TDEPTL.FDEPTID = TCH.FAPPLICATIONDEPTID AND TDEPTL.FLOCALEID={0} ", base.Context.UserLocale.LCID);
    stringBuilder.AppendLine(" LEFT JOIN T_BD_SUPPLIER TSU ON TCT.FSUGGESTSUPPLIERID=TSU.FSUPPLIERID");
    stringBuilder.AppendFormat(" LEFT JOIN T_BD_SUPPLIER_L TSUP ON TSUP.FSUPPLIERID=TCT.FSUGGESTSUPPLIERID AND TSUP.FLOCALEID={0}", base.Context.UserLocale.LCID);
    stringBuilder.AppendFormat(" LEFT JOIN T_BD_SUPPLIERGROUP_L TSUPG ON TSUPG.FID=TSU.FPRIMARYGROUP  AND TSUPG.FLOCALEID={0}", base.Context.UserLocale.LCID);
    stringBuilder.AppendFormat(" LEFT JOIN T_ORG_ORGANIZATIONS_L VIOL ON TCH.FAPPLICATIONORGID=VIOL.FORGID AND VIOL.FLOCALEID={0}", base.Context.UserLocale.LCID);
    stringBuilder.AppendFormat(" LEFT JOIN T_ORG_ORGANIZATIONS_L SORGL ON TCTS.FREQUIREORGID=SORGL.FORGID AND SORGL.FLOCALEID={0}", base.Context.UserLocale.LCID);
    stringBuilder.AppendLine(" LEFT JOIN t_BD_Unit TU ON TU.FUNITID=TCT.FUNITID  ");
    stringBuilder.AppendFormat(" LEFT JOIN t_BD_Unit_L TBU ON TBU.FUNITID=TCT.FUNITID  AND  TBU.FLOCALEID={0}", base.Context.UserLocale.LCID);
    stringBuilder.AppendLine(" LEFT JOIN t_BD_Unit TUPR ON TUPR.FUNITID=TCT.FPRICEUNITID  ");
    stringBuilder.AppendFormat(" LEFT JOIN t_BD_Unit_L TUPRL ON TUPR.FUNITID=TUPRL.FUNITID  AND  TUPRL.FLOCALEID={0} ", base.Context.UserLocale.LCID);
    stringBuilder.AppendLine(" INNER JOIN T_BD_MATERIAL T7 ON T7.FMATERIALID=TCT.FMATERIALID ");
    stringBuilder.AppendLine(" INNER JOIN T_BD_MATERIALBASE T21 ON T7.FMATERIALID=T21.FMATERIALID ");
    stringBuilder.AppendFormat(" LEFT JOIN T_BD_MATERIAL_L TBM ON TBM.FMATERIALID=TCT.FMATERIALID AND TBM.FLOCALEID={0}", base.Context.UserLocale.LCID);
    stringBuilder.AppendFormat(" LEFT JOIN T_BD_MATERIALGROUP_L TGOU ON TGOU.FID=T7.FMATERIALGROUP AND TGOU.FLOCALEID={0} ", base.Context.UserLocale.LCID);
    stringBuilder.AppendFormat(" LEFT JOIN T_BD_MATERIALCATEGORY_L TCA ON TCA.FCATEGORYID=T21.FCATEGORYID AND TCA.FLOCALEID={0} ", base.Context.UserLocale.LCID);
    stringBuilder.AppendLine(" LEFT JOIN  T_BD_MATERIALGROUP TMG ON TMG.FID=T7.FMaterialGroup");
    stringBuilder.AppendLine(" INNER JOIN (SELECT T2.FVALUE,T1.FCAPTION FROM T_META_FORMENUMITEM_L T1 INNER JOIN T_META_FORMENUMITEM T2 ON T1.FENUMID = T2.FENUMID ");
    stringBuilder.AppendFormat(" WHERE T2.FID = '{0}' AND T1.FLOCALEID = {1}) TENL ON T21.FERPCLSID = TENL.FVALUE ", "ac14913e-bd72-416d-a50b-2c7432bbff63", base.Context.UserLocale.LCID);

有数据库基础的朋友,应该能看懂这个连接关系。

没看懂的,我自己写的,可能需要修改

select t16.FNAME AS 供应商名称,t3.FENTRYNOTE as 备注,t17.FNAME AS 申请人,t2.fbillno as 申请单号,t2.FApproveDate as 审核日期,t18.FNAME as 物料名称,t19.FNUMBER as 物料编码, t18.FSPECIFICATION AS 规格型号,
t3.freqqty as 申请数量,t3.fapproveqty as 批准数量,t3.farrivaldate as 需求日期,t6.fbillno as 订单单号,t5.FSEQ AS 订单行号,t6.Fdate as 订单日期,t16.fshortname as 供应商简称,t20.FDELIVERYDATE as 计划到货日期,
t5.fqty as 采购数量,t21.ftaxprice as 含税单价,t9.fbillno as 到货单号,t9.fdate as 到货日期,t8.FActReceiveQty as 交货数量,t12.fbillno as 入库单号,t12.fdate as 入库日期,t11.FRealQty as 入库数量 from T_PUR_Requisition t2 
left join T_PUR_ReqEntry t3 on t2.FID=t3.FID 
left join T_PUR_POORDERENTRY_LK t4 on t4.fsid=t3.FENTRYID and t4.FRULEID='PUR_Requisition-PUR_PurchaseOrder' and t4.FSTABLENAME='T_PUR_ReqEntry' and t4.FSBILLID=t3.FID
left join T_PUR_POORDERENTRY t5 on t4.FENTRYID=t5.FENTRYID
left join T_PUR_POORDERENTRY_D t20 on t20.FENTRYID=t5.FENTRYID
left join T_PUR_POORDER t6 on t6.fid=t5.fid
left join T_PUR_POORDERENTRY_F t21 on t21.FENTRYID=t5.FENTRYID
left join T_PUR_ReceiveEntry_LK t7 on t7.fsid=t5.FENTRYID and t7.FRULEID='PUR_PurchaseOrder-PUR_ReceiveBill' and t7.FSTABLENAME='t_PUR_POOrderEntry' and t7.FSBILLID=t5.FID
left join T_PUR_ReceiveEntry t8 on t7.FENTRYID=t8.FENTRYID
left join T_PUR_Receive t9 on t8.fid=t9.fid
left join T_STK_INSTOCKENTRY_LK t10 on t10.FSID=t8.FENTRYID and t10.FRULEID='PUR_ReceiveBill-STK_InStock' and t10.FSTABLENAME='T_PUR_ReceiveEntry' and t10.FSBILLID=t8.FID
left join T_STK_INSTOCKENTRY t11 on t10.FENTRYID=t11.FENTRYID
left join T_STK_INSTOCK t12 on t11.fid=t12.fid
left join T_PUR_MRBENTRY_LK t13 on t13.FSID=t8.FENTRYID and t13.FRULEID='PUR_ReceiveBill-PUR_MRB' and t13.FSTABLENAME='T_PUR_ReceiveEntry' and t13.FSBILLID=t8.FID
left join T_PUR_MRBENTRY t14 on t14.FENTRYID=t13.FENTRYID
left join T_PUR_MRB t15 on t14.fid=t15.fid
left join T_BD_SUPPLIER_l t16 on t16.FSUPPLIERID=t6.FSUPPLIERID
left join T_BD_STAFF_l t17 on t17.FSTAFFID=t2.FAPPLICANTID
left join T_BD_MATERIAL_L t18 on t18.fmaterialid=t3.FMATERIALID and t18.fuseorgid=t2.FApplicationOrgId
left join T_BD_MATERIAL t19 on t19.fmaterialid=t3.FMATERIALID and t19.fuseorgid=t2.FApplicationOrgId

希望对在学习的各位能有所帮助。有所启发。后续有新的内容会持续更新。

图标赞 97
97人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!

您的鼓励与嘉奖将成为创作者们前进的动力,如果觉得本文还不错,可以给予作者创作打赏哦!

请选择打赏金币数 *

10金币20金币30金币40金币50金币60金币
可用金币: 0