# 报表表单插件 — IronPython

源：[金蝶python插件示例/简单账表-表单插件示例(全).txt](../../../../../金蝶python插件示例/简单账表-表单插件示例(全)/简单账表-表单插件示例(全).txt)

```python
# -*- coding: utf-8 -*-
import clr

#添加对cloud插件开发的常用组件的引用
clr.AddReference('System')
clr.AddReference('System.Data')
clr.AddReference('Kingdee.BOS')
clr.AddReference('Kingdee.BOS.Model')
clr.AddReference('Kingdee.BOS.Core')
clr.AddReference('Kingdee.BOS.App')
clr.AddReference('Kingdee.BOS.ServiceHelper')
clr.AddReference('Newtonsoft.Json')
#导入cloud基础库中的常用实体对象（分命名空间导入，不会递归导入）
from Kingdee.BOS import *
from Kingdee.BOS.Core import *
from Kingdee.BOS.Core.DependencyRules import *
from Kingdee.BOS.Core.Bill import *
from Kingdee.BOS.Core.DynamicForm.PlugIn import *
from Kingdee.BOS.Core.DynamicForm.PlugIn.ControlModel import *
from Kingdee.BOS.Core.Metadata import * 
from System import *
from System.Data import *
from Kingdee.BOS.App.Data import *
from System.Collections.Generic import List
from Kingdee.BOS.ServiceHelper import *
from Kingdee.BOS.Model.Report import *
from Kingdee.BOS.Core.Report.PlugIn import *
from Kingdee.BOS.Core.Report import *
from Newtonsoft.Json import JsonConvert
from Newtonsoft.Json.Linq import *
from Kingdee.BOS.JSON import *

#初始化
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;#适用整行,默认值为True,设置了ColorField时,才会单独对某个字段设置颜色，否则应用整行
				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键并把鼠标放到选中单元格的地方,即可看到效果
```
