首页 > 其他分享 >呆滞料分析报表二开增加自定义字段

呆滞料分析报表二开增加自定义字段

时间:2024-08-06 14:09:21浏览次数:15  
标签:自定义 二开 StockYears 呆滞 Context sb Krystal new 库龄

 

业务背景

物料资料添加了自定义字段,在呆滞料分析无法直观看到,同时不能直观看到物料在仓库多久了。

 

业务需求

在呆滞料分析报表显示物料的品牌型号,以及计算物料库龄。

 

方案设计

二开标准产品,添加字段,创建插件继承标准产品插件,重写方法,自定义临时表获取初步查询结果,然后关联计算得到新字段,插入到系统生成的临时表,在报表关闭时删除自定义临时表,替换标准产品插件。

 

详细设计和实现

标准报表引入到应用

查询《呆滞料分析》引入到应用,同样引入《呆滞料分析过滤》

 

 

 

 

 

物料资料添加引用:品牌型号

 报表单据体拖拽一个基础资料属性控件,关联物料资料的品牌型号

 

 

 

  显示隐藏列:物料资料添加引用-品牌型号

添加一个基础资料属性控件,关联物料资料的品牌型号

 

 

 

创建插件项目

新建类库 Krystal.K3.SCGL.App.Report,添加引用【如果原来已经有类库,可跳过】

 

 

 

 修改项目生成位置,到协同工作路径bin下

 

 添加引用

 

创建类,继承报表原插件

 

 

重写BuilderReportSqlAndTempTable。
如果生产日期存在,计算库龄,今天-生产日期,生产日期为空,库龄=0;如果生产日期不显示,那无需计算。

public override void BuilderReportSqlAndTempTable(IRptParams filter, string tableName)
{
    // base.BuilderReportSqlAndTempTable(filter, tableName);

    //测试表是否存在,是否有数据
    //string sql1 = string.Format(@"select top 10000 * from {0}", tableName);
    //var sd = DBUtils.ExecuteDynamicObject(this.Context, sql1);


    IDBService dbservice = Kingdee.BOS.App.ServiceHelper.GetService<IDBService>();
    rptTempTableNames = dbservice.CreateTemporaryTableName(this.Context, 1);
    string strTable = rptTempTableNames[0];

    //调用基类的方法,获取初步的查询结果到临时表
    base.BuilderReportSqlAndTempTable(filter, strTable);

    //判断临时表是否存在某个字段
    string _sql = string.Format(@"{0}SELECT 1 FROM syscolumns, systypes  
                    WHERE syscolumns.xusertype = systypes.xusertype  
                    AND syscolumns.id = object_id('{1}') 
                    and syscolumns.name='FProduceDate'",OtherConst.DIALECT, strTable);
    var sd = DBUtils.ExecuteDynamicObject(this.Context, _sql);
    //初步结果处理,然后回写积累的数据到临时表
    if (sd!=null && sd.Count>0)
    {
        haveProductDate = true;
        StringBuilder sb = new StringBuilder();
        sb.AppendLine("SELECT T1.*,ROUND(isnull(datediff(month,T1.FProduceDate,GETDATE())/12.0,0),2)  F_Krystal_StockYears");
        sb.AppendFormat(" into {0} ", tableName);
        sb.AppendFormat(" FROM {0} T1", strTable);
        //DBUtils.Execute(this.Context, "DROP TABLE " + tableName);
        DBUtils.Execute(this.Context, sb.ToString());
    }
    else
    {
        haveProductDate = false;
        StringBuilder sb = new StringBuilder();
        sb.AppendLine("SELECT T1.*,0 F_Krystal_StockYears");
        sb.AppendFormat(" into {0} ", tableName);
        sb.AppendFormat(" FROM {0} T1", strTable);
        //DBUtils.Execute(this.Context, "DROP TABLE " + tableName);
        DBUtils.Execute(this.Context, sb.ToString());
    }

          
           
}
View Code

 

绑定报表列头

public override ReportHeader GetReportHeaders(IRptParams filter)
{
    ReportHeader header = base.GetReportHeaders(filter);


    //header.AddChild("F_Krystal_StockYears", new LocaleValue("库龄", this.Context.DefaultLocale.LCID), SqlStorageType.SqlDecimal);

    //List<ListHeader> childs = header.GetChilds();
    //childs.Select(s=>s.FieldName.Equals("FProduceDate")).ToList().FirstOrDefault()
    #region 生产日期存在,才添加库龄标题
    //if (!childs.Select(s => s.FieldName.Equals("FProduceDate")).ToList().FirstOrDefault())
    //{
    //    header.AddChild("F_Krystal_StockYears", new LocaleValue("库龄", this.Context.DefaultLocale.LCID), SqlStorageType.SqlDecimal);
    //}
    #endregion

    #region 添加库龄标题,如果生产日期不存在,库龄不可见
    //header.AddChild("F_Krystal_StockYears", new LocaleValue("库龄", this.Context.DefaultLocale.LCID), SqlStorageType.SqlDecimal);
    //if (!haveProductDate)
    //{
    //    var sy = childs.Where(s => s.FieldName.Equals("F_Krystal_StockYears")).ToList().FirstOrDefault();
    //    sy.Visible = false;
    //}
    #endregion
    //header.AddChild("F_Krystal_StockYears", new LocaleValue(ResManager.LoadKDString("库龄", "004021030009048", SubSystemType.SCM)), SqlStorageType.SqlDecimal);

    #region 生产日期存在,才添加库龄标题
    if (haveProductDate)
    {
        header.AddChild("F_Krystal_StockYears", new LocaleValue("库龄", this.Context.DefaultLocale.LCID), SqlStorageType.SqlDecimal);
    }
    #endregion
    return header;
}
View Code

 

汇总列

 /// <summary>
/// 字段汇总
/// </summary>
/// <param name="filter"></param>
/// <returns></returns>
public override List<SummaryField> GetSummaryColumnInfo(IRptParams filter)
{
    var lstGroupField = base.GetSummaryColumnInfo(filter);
    if (haveProductDate)//测试过 生产日期勾选,库龄不勾选不报错
    {
        lstGroupField.Add(new Kingdee.BOS.Core.Report.SummaryField("F_Krystal_StockYears", BOSEnums.Enu_SummaryType.SUM));
    }
    return lstGroupField;
}
View Code

 

 完整代码

using Kingdee.BOS;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.Core.Enums;
using Kingdee.BOS.Core.Report;
using Kingdee.BOS.Util;
using Kingdee.K3.SCM.App.Stock.Report;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace Krystal.K3.App.Report.STK
{
    /// <summary>
    /// 功能描述    :DullMaterialAnalysisRptExtend  
    /// 创 建 者    :Administrator
    /// 创建日期    :2024/7/9 17:34:24 
    /// 最后修改者  :Krystal
    /// 最后修改日期:2024/7/9 17:34:24 
    /// </summary>
    [Description("呆滞料分析服务端插件二开-报表插件"), HotUpdate]
    public class DullMaterialAnalysisRptExtend: DullMaterialAnalysisRpt
    {
        #region <常量>
        private const string DIALECT = "/*dialect*/";
        #endregion <常量>

        #region <变量>
        /// <summary>
        /// 申请的临时表
        /// </summary>
        private string[] rptTempTableNames;

        /// <summary>
        /// 生产日期存在,才计算库龄,和显示
        /// </summary>
        private bool haveProductDate = false;
        #endregion <变量>

        #region <属性>
        #endregion <属性>

        #region <构造方法和析构方法>
        #endregion <构造方法和析构方法>

        #region <方法>
        #endregion <方法>

        #region <事件>

        public override ReportHeader GetReportHeaders(IRptParams filter)
        {
            ReportHeader header = base.GetReportHeaders(filter);


            //header.AddChild("F_Krystal_StockYears", new LocaleValue("库龄", this.Context.DefaultLocale.LCID), SqlStorageType.SqlDecimal);

            //List<ListHeader> childs = header.GetChilds();
            //childs.Select(s=>s.FieldName.Equals("FProduceDate")).ToList().FirstOrDefault()
            #region 生产日期存在,才添加库龄标题
            //if (!childs.Select(s => s.FieldName.Equals("FProduceDate")).ToList().FirstOrDefault())
            //{
            //    header.AddChild("F_Krystal_StockYears", new LocaleValue("库龄", this.Context.DefaultLocale.LCID), SqlStorageType.SqlDecimal);
            //}
            #endregion

            #region 添加库龄标题,如果生产日期不存在,库龄不可见
            //header.AddChild("F_Krystal_StockYears", new LocaleValue("库龄", this.Context.DefaultLocale.LCID), SqlStorageType.SqlDecimal);
            //if (!haveProductDate)
            //{
            //    var sy = childs.Where(s => s.FieldName.Equals("F_Krystal_StockYears")).ToList().FirstOrDefault();
            //    sy.Visible = false;
            //}
            #endregion
            //header.AddChild("F_Krystal_StockYears", new LocaleValue(ResManager.LoadKDString("库龄", "004021030009048", SubSystemType.SCM)), SqlStorageType.SqlDecimal);

            #region 生产日期存在,才添加库龄标题
            if (haveProductDate)
            {
                header.AddChild("F_Krystal_StockYears", new LocaleValue("库龄", this.Context.DefaultLocale.LCID), SqlStorageType.SqlDecimal);
            }
            #endregion
            return header;
        }

        public override void BuilderReportSqlAndTempTable(IRptParams filter, string tableName)
        {
            // base.BuilderReportSqlAndTempTable(filter, tableName);

            //测试表是否存在,是否有数据
            //string sql1 = string.Format(@"select top 10000 * from {0}", tableName);
            //var sd = DBUtils.ExecuteDynamicObject(this.Context, sql1);


            IDBService dbservice = Kingdee.BOS.App.ServiceHelper.GetService<IDBService>();
            rptTempTableNames = dbservice.CreateTemporaryTableName(this.Context, 1);
            string strTable = rptTempTableNames[0];

            //调用基类的方法,获取初步的查询结果到临时表
            base.BuilderReportSqlAndTempTable(filter, strTable);

            //判断临时表是否存在某个字段
            string _sql = string.Format(@"{0}SELECT 1 FROM syscolumns, systypes  
                            WHERE syscolumns.xusertype = systypes.xusertype  
                            AND syscolumns.id = object_id('{1}') 
                            and syscolumns.name='FProduceDate'",  DIALECT, strTable);
            var sd = DBUtils.ExecuteDynamicObject(this.Context, _sql);
            //初步结果处理,然后回写积累的数据到临时表
            if (sd != null && sd.Count > 0)
            {
                haveProductDate = true;
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("SELECT T1.*,ROUND(isnull(datediff(month,T1.FProduceDate,GETDATE())/12.0,0),2)  F_Krystal_StockYears");
                sb.AppendFormat(" into {0} ", tableName);
                sb.AppendFormat(" FROM {0} T1", strTable);
                //DBUtils.Execute(this.Context, "DROP TABLE " + tableName);
                DBUtils.Execute(this.Context, sb.ToString());
            }
            else
            {
                haveProductDate = false;
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("SELECT T1.*,0 F_Krystal_StockYears");
                sb.AppendFormat(" into {0} ", tableName);
                sb.AppendFormat(" FROM {0} T1", strTable);
                //DBUtils.Execute(this.Context, "DROP TABLE " + tableName);
                DBUtils.Execute(this.Context, sb.ToString());
            }


        }

        /// <summary>
        /// 字段汇总
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public override List<SummaryField> GetSummaryColumnInfo(IRptParams filter)
        {
            var lstGroupField = base.GetSummaryColumnInfo(filter);
            if (haveProductDate)//测试过 生产日期勾选,库龄不勾选不报错
            {
                lstGroupField.Add(new Kingdee.BOS.Core.Report.SummaryField("F_Krystal_StockYears", BOSEnums.Enu_SummaryType.SUM));
            }
            return lstGroupField;
        }

        #endregion <事件>
    }
}
View Code

 

编译后挂载dll到报表服务插件

 

取消标准插件,注册二开插件

 

测试

  重启开发环境

 打开测试网页:http://localhost:1200/

 

标签:自定义,二开,StockYears,呆滞,Context,sb,Krystal,new,库龄
From: https://www.cnblogs.com/lanrenka/p/18291218

相关文章

  • linux进程篇总结——实战——自定义shell
        前言:经过过去两章十二篇文章的学习,我们已经知道了进程的基本概念以及进程的控制方法。本篇内容就是使用过去学习的内容自己写一个功能简单的shell外壳程序,也就是我们使用的bash命令行。本篇内容是过去进程知识的集大成者。我们在这个实战程序中,将过去学过的......
  • (已解决)QT4 自定义信号函数调用报错 error: C2248: “Boss::DeadSignal”: 无法访问 pr
     (解决方法见文章末尾)报错语句如下 DeadSignal是自定义槽函数,是放在public下的,不知道为什么报错说是protected,不知道是不是版本问题Boss类和DeadSignal定义如下 mboss是在自定义类Widget中调用的Boss对象 调用位置是Widget的自定义槽函数 解决方法在Boss中定......
  • 为什么 xgboost.QuantileDMatrix 使用自定义数据迭代器对数据进行四次传递?
    我正在尝试使用自定义数据迭代器,如下所示此处,因为我的数据集太大。只是为了测试它是如何工作的,我正在使用示例的子集并运行以下代码。X是我的数据的numpy数组。我的迭代器如下所示classIterForQDMatrix(xgb.core.DataIter):def__init__(self,d......
  • C#自定义快捷操作键的实现 - 开源研究系列文章
          这次想到应用程序的快捷方式使用的问题。      Windows已经提供了API函数能够对窗体的热键进行注册,然后就能够在窗体中使用这些注册的热键进行操作了。于是笔者就对这个操作进行了整理,将注册热键操作写成了帮助类,并且用此博文来记录这个使用DEMO,便于其他读者......
  • 【Vitepress系列】-- 自定义组件及布局,配置tailwindcss、配置Markdown
    Vitepress自定义页面,以及配置tailwindcssvitepress中,除了使用一些配置项目,还可以通过写vue代码,来做一个定制化的UI。下面这个UI主页便是vue组件+tailwindcss做的一.自定义vitepress中,如果内置的home、doc、page不满足需求,还可以自己写vue代码进行自定义1.1自定义布......
  • 自定义异常
    自定义异常目录自定义异常分类检查性异常类:自定义异常类继承于Exception。运行时异常类:自定义异常类继承于RuntimeException自定义检查性异常类(MyException)自定义运行时异常类(MyRuntimeException)自定义异常的使用实例分类检查性异常类:自定义异常类继承于Exception。运行时......
  • 自定义线程池
    自定义线程池  概要  自JDK1.5起,util包提供了ExecutorService线程池的实现,主要目的是为了重复利用线程,提高系统效率。我们知道Thread是一个重量级的资源,创建、启动以及销毁都是比较耗费系统资源的,因此对线程的重复利用一种是非常好的程序设计习惯,加之系统中可创建的线程数......
  • echarts自定义x轴和tooltip数据格式
    echarts自定义x轴和tooltip数据格式x轴和y轴数据格式如下x:[0,1,2,3,4,5,6,.....,23],y:[2.5,3.1,3.2,2.2,2.3,3.1,3.1,null,null,null,....,null]//接口返回0-23点的数据,每一个小时一个间隔,没有的话则为null 修改后xy轴数据格式如下//每五分钟一......
  • vue + quill2.0+ 工具栏自定义行高
    在网上查了好多,基本都是基于1.0+版本的,拿过来都用不了,官方又没有文档,只能参考各位前辈的经验+解析源码查找问题。目前已经解决,下面是实现过程。实现代码  先看效果图我用的是原生quill库,正常引入quill,注册行高插件importQuillfrom'quill'import'quill/dist/quill.......
  • 打造Perl中的词法分析器:深入自定义文本处理
    打造Perl中的词法分析器:深入自定义文本处理Perl作为一种强大的文本处理语言,提供了丰富的工具来实现词法分析器(Lexer)。词法分析是编译原理中将源代码分解成一系列词素(Tokens)的过程,是构建编译器或解释器的第一步。本文将详细探讨如何在Perl中实现一个自定义的词法分析器,包括......