本文是对“Python插件入门”系列中的一篇关于“简单账表服务插件”的扩展,主要介绍了账表表单插件的概念、应用场景、新建方法及常用事件。账表表单插件通过继承AbstractDynamicFormPlugIn基类实现,用于丰富报表界面功能,如设置数据颜色、修改报表单元格数据、单据关联查询等。文中提供了账表表单插件的详细开发步骤和代码示例,包括初始化、加载、数据绑定、按钮点击等事件的处理方法,展示了如何通过Python代码对报表进行自定义和扩展。
往期回顾:
【Python插件入门】第1篇:Python插件入门讲解
【Python插件入门】第2篇:基本开发过程介绍
【Python插件入门】第3篇:插件中如何进行数据操作
【Python插件入门】第4篇:单据表单插件
【Python插件入门】第5篇:单据列表插件
【Python插件入门】第6篇:操作服务插件
【Python插件入门】第7篇:简单账表服务插件
接上一篇,简单账表服务插件主要是完成了报表查询数据的构建,已经完成了简单账表查询功能的开发,那么对于查询界面在做一些"锦上添花"的功能,会让报表功能更加丰富,或者基于报表查询结果,再做一些单据联查、穿透查询等功能,可以通过账表表单插件来完成。
一、账表表单插件简介
C#开发时,账表表单插件的基类是AbstractSysReportPlugIn,与单据的表单插件基类不同,C#开始时要注意一下!Python插件开发的话,了解就行了,他也是AbstractDynamicFormPlugIn的派生类,和单据表单插件算是"兄弟"关系。账表表单插件是依赖于账表界面触发的,也属于界面类插件,既然都是继承于AbstractDynamicFormPlugIn,所以很多表单插件中的事件方法也是可以使用的。
账表表单插件中的一些重要属性和成员这里就不单独介绍了,下面的常用事件讲解中会做介绍,继续往下看!
账表表单插件常见应用场景
①账表查询界面设置数据颜色。
②修改报表单元格数据:转换百分数、千分号分隔符、修改底部合计结算逻辑等。
③单据关联查询。
④报表穿透查询,关联弹出其他账表。
⑤关闭表头排序功能
⑥报表表头字段赋值
⑦...
二、新建一个账表表单插件
注意:这里提供一个引用比较全的账表表单插件示例模板,在附件中下载示例代码,复制到BOS里面注册!
Python账表表单插件注册方法:如下图所示,以上一篇测试示例报表为例,其他账表类似。
三、账表表单插件常用事件介绍
这里做了表单插件的示例,对报表界面做了一些丰富,测试效果图如下:
下面看下账表表单插件中常用事件介绍:
#初始化
def OnInitialize(e):
openPara=this.View.OpenParameter;#获取打开报表时传入的参数
myPara=openPara.GetCustomParameter("参数标识");#根据参数标识获取某个打开参数
if(myPara<>None):#若参数不为空
myParaStr=("{0}").format(myPara);#将参数转换为字符串
#将参数传递给过滤框,可在过滤框注册表单插件获取此参数
param=SysReportShowParameter();
param.CustomParams.Add("参数标识",myParaStr);
#账表页面加载完毕
def OnLoad(e):
return;#这里示例不执行后面的代码
#若报表没有显示表头字段,可通过如下代码隐藏表头部分,以免显示一块空白区域,影响用户体验
sp=this.View.GetControl[SplitContainer]("FSpliteContainer");
sp.HideFirstPanel(True);#折叠分割容器上面部分
#报表页面数据加载完毕
def AfterBindData(e):
listGrid=this.View.GetControl("FList");
listGrid.SetCustomPropertyValue("AllowSorting", False);#关闭表头的排序功能
reportModel=this.Model;#SysReportModel类型,报表数据模型
billObj=reportModel.DataObject;#报表页面实体数据包
reportView=this.View;#SysReportView类型,报表界面View
titles=reportModel.ReportTitles;#获取账表服务插件中构建的报表表头字段集
msg="";
for title in titles:
fldKey=title.TitleKey;#表头字段标识
fldValue=title.TitleValue;#表头字段值
fldCtl=reportView.GetControl(title.TitleKey);#获取表头字段控件
#fldCtl.Enabled=True;#默认是锁定的,可通过此代码放开表头字段,允许编辑
#fldCtl.Visible=False;#隐藏表头字段
customFilterObj=reportModel.FilterParameter.CustomFilter;#报表过滤框快捷过滤实体数据包
orgObj=customFilterObj["F_BPW_OrgId"];#获取组织过滤字段
orgId=orgObj["Id"] if(orgObj<>None) else "0";#获取组织Id
this.Model.SetItemValueByID("F_BPW_OrgId",orgId,0);#给表头组织字段赋值成基础资料
#this.View.ShowMessage(msg);
#按钮点击事件
def ButtonClick(e):
key=e.Key.ToUpperInvariant();#按钮标识大写
if(key=="F_BPW_TestBtn".ToUpperInvariant()):
this.Model.SetItemValueByID("F_BPW_OrgId",0,0);
reportModel=this.Model;#SysReportModel类型,报表数据模型
customFilterObj=reportModel.FilterParameter.CustomFilter;#报表过滤框快捷过滤实体数据包
customFilterObj["F_BPW_OrgId"]=None;#清空过滤数据包中的组织字段
customFilterObj["F_BPW_OrgId_Id"]=0;
this.View.Refresh();#清空组织后刷新,获取所有组织数据
#表头菜单点击事件
def BarItemClick(e):
key=e.BarItemKey.ToUpperInvariant();#菜单标识大写
if(key=="F_BPW_MyBtn".ToUpperInvariant()):
reportModel=this.Model;#SysReportModel类型,报表数据模型
rowCount=reportModel.GetRowCount();#报表数据总行数
tab=reportModel.DataSource;#账表数据源DataTable,报表所有行数据
x=rowCount;
mytab=reportModel.GetData(0,x);#获取报表0-x行数据,返回DataTable对象
tempTabName=tab.TableName;#账表临时表名称,每一次查询报表都会不一样
msg=("表头菜单{0}点击啦!").format(key);
this.View.ShowMessage(msg);
#格式化行数据,每一行会运行一次
#在此事件中可以设置报表数据的颜色
def OnFormatRowConditions(args):
if(args.DataRow.ColumnContains("orgName")==True):#根据字段标识判断是否显示了该字段
ss= ("{0}").format(args.DataRow["orgName"]); #获取字段值,这里是取组织名称
if("蓝海" in ss):#组织名称包含"蓝海"
fc=FormatCondition();
fc.BackColor="#ccffff";#背景色
fc.ForeColor = "#FF0000";#前景色
#fc.ColorField = "orgName";#颜色字段
#fc.ApplayRow = False;#适用整行,默认值为True,设置ColorField时,才会单独对字段设置颜色,否则应用整行
args.FormatConditions.Add(fc);
reportModel=this.Model;
tab=reportModel.DataSource;
allFlds=tab.Columns;#报表所有字段
#循环对动态列进行判断,数量不为0显示颜色
for fld in allFlds:
fldKey=fld.ColumnName;
if("_" not in fldKey or fldKey.StartsWith("F")==False):#非数量动态列,不做处理
continue;#自定义的动态列名规则,我示例报表动态数量列名是F开头且包含下划线,其他字段均不满足此条件
if(args.DataRow.ColumnContains(fldKey)==True):
qty= float(args.DataRow[fldKey]);
if(qty<>0):
fc=FormatCondition();
fc.BackColor="#CCCCCC";#背景色
fc.ForeColor ="#FF0000";#前景色
fc.ColorField = fldKey;#颜色字段
fc.ApplayRow = False;
args.FormatConditions.Add(fc);
#去除尾0,自定义方法供参考
def remove_exponent(i):
t=str(i);
return t.rstrip('0').strip('.') if '.' in t else t;
#单元数据格式化
#在这个事件里面可以对报表原输出的单元格内容做修改
def FormatCellValue(args):
fldkey=args.Header.Key;#字段标识
if(fldkey=="F2018_1_4" ):
dr=args.DataRow;#获取当前行的数据
valueStr= ("{0}").format(args.FormateValue);#获取该字段原输出值
args.FormateValue=("{0}%").format(round(float(valueStr)*100,2));#转换成百分数
elif(fldkey=="orgName"):
dr=args.DataRow;#获取当前行的数据
valueStr= ("{0}").format(args.FormateValue);#获取该字段原输出值
args.FormateValue=valueStr.Replace("蓝海","***");#将组织名称中的"蓝海"替换成***
elif("_" in fldkey and fldkey.StartsWith("F")==True):
args.FormateValue=remove_exponent(args.FormateValue);#去除尾0
#oldValue=Decimal.Parse(args.FormateValue);#转换成Decimal
#args.FormateValue =oldValue.ToString("N");#设置千分位分隔符
cellTye=int(args.CellType);#单元格类型,0:普通,1:合计,2:小计
if(cellTye==1 and fldkey=="F2018_1_6"):#判断底部合计行,可对底部合计行做自定义计算修改
#这里演示将F2018_1_6底部合计修改成:F2018_1_4+F2018_1_5
newSumValue=float(args.DataRow["F2018_1_4"])+float(args.DataRow["F2018_1_5"]);
args.FormateValue=("{0}").format(newSumValue);
#单元格超链接点击事件
def EntryButtonCellClick(e):
row=e.Row;#点击超链接所在序号,从1开始
fldKey=e.FieldKey.ToUpperInvariant();#点击单元格字段标识大写
msg=("点击了第{0}行的[{1}]").format(row,fldKey);
this.View.ShowMessage(msg);
#e.Cancel=True;#取消点击事件
#获取当前单元格的值
reportModel=this.Model;
tab=reportModel.DataSource;
value=("{0}").format(tab.Rows[row-1][e.FieldKey]);
#单元格双击事件
#简单账表 表单不会触发EntityRowDoubleClick事件,用此事件代替
def CellDbClick(Args):
#Args.Cancel=True;#取消事件,若二开标准报表,可以此取消标准功能自带的双击事件
row=Args.CellRowIndex;#双击序号,从1开始
fldKey=Args.Header.FieldName;#双击单元格的字段名
#获取当前单元格的值
reportModel=this.Model;
tab=reportModel.DataSource;
value=("{0}").format(tab.Rows[row-1][fldKey]);#也可以传其他字段名,即可获取其他字段值
msg=("点击了第{0}行的[{1}],{1}值={2}").format(row,fldKey,value);
this.View.ShowMessage(msg);
#行点击事件
def EntityRowClick(e):
row=e.Row;#点击的行序号,从1开始
#msg=("点击了第{0}行!").format(row);
#this.View.ShowMessage(msg);
reportView=this.View;
selectedDataRows=reportView.SelectedDataRows;#获取选中行,若启用了允许多选,则可获取到所有选中行
if(selectedDataRows==None or selectedDataRows.Length==0):#无选中行数据
return;
#下面实现选中行合计功能
dt=selectedDataRows[0].Table;
allFlds=dt.Columns;#报表所有字段
jsonArr=JSONArray();
DIC={};
DIC["F2018_1_4"]="2018-1-4";#添加需要合计的字段标识和字段标题的字典
DIC["F2018_1_5"]="2018-1-5";
for fldKey in DIC.keys():
columnIndex=allFlds.IndexOf(fldKey);
sumValue=0;
for selectRow in selectedDataRows:
fldValue=float(selectRow.ItemArray[columnIndex]);#取出选中行对应字段的值
sumValue=sumValue+fldValue;
jsonObj=JSONObject();
jsonObj.Put("Value",remove_exponent(sumValue));
jsonObj.Put("Caption",("{0}:").format(DIC[fldKey]));
jsonArr.Add(jsonObj);
listGrid=this.View.GetControl("FList");
listGrid.SetSelectRowsTips(jsonArr);#输出到前端,按下alt键并把鼠标放到选中行的区域,即可看到效果
四、经典实践案例参考
有了账表表单插件确实可以丰富很多功能,以下是整理的各位大佬分享的一些账表表单插件的常用案例。
大多是C#插件示例,但是结合上面常用事件介绍中的Python示例,使用Python插件实现也不是难事。
......
==========================本篇正文结束=====================================
用2篇文章把Python账表开发的核心介绍完了,应该能满足95%以上的报表需求了。
示例代码已经上传附件,老规矩,大家按需下载!
感谢大家持续关注,点赞、评论、收藏,您的点赞、评论就是我前进的动力。
简单账表-表单插件示例(全).rar(3.86KB)
发布于 金蝶云星空BOS开发交流圈 社群