文章目录
呆滞料分析报表二开增加自定义字段
业务背景
物料资料添加了自定义字段,在呆滞料分析无法直观看到,同时不能直观看到物料在仓库多久了。
业务需求
在呆滞料分析报表显示物料的品牌型号,以及计算物料库龄。
方案设计
二开标准产品,添加字段,创建插件继承标准产品插件,重写方法,自定义临时表获取初步查询结果,然后关联计算得到新字段,插入到系统生成的临时表,在报表关闭时删除自定义临时表,替换标准产品插件。
详细设计和实现
标准报表引入到应用
查询《呆滞料分析》引入到应用,同样引入《呆滞料分析过滤》
标准报表扩展和字段
扩展《呆滞料分析》,重命名标识后保存。
新增字段,字段的标识名命名一致。
物料资料添加引用:品牌型号
报表单据体拖拽一个基础资料属性控件,关联物料资料的品牌型号
过滤框处理
扩展《呆滞料分析》,重命名标识后保存。
显示隐藏列集合新增字段,标识和后台命名需保持一致。
基础资料属性控件,对应基础资料要先引用。【 显示隐藏列:物料资料添加引用-品牌型号
添加一个基础资料属性控件,关联物料资料的品牌型号】
创建插件项目
新建类库 Krystal.K3.SCGL.App.Report,添加引用【如果原来已经有类库,可跳过】
我的框架是4.6
修改项目生成位置,到协同工作路径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());
}
}
绑定报表列头
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;
}
汇总列
/// <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;
}
完整代码
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 <事件>
}
}
编译后挂载dll到报表服务插件
取消标准插件,注册二开插件
测试
重启开发环境
打开测试网页
http://localhost:1200/