Grid++格式化脚本常用操作

通过在脚本属性中编写 JScript 代码实现对报表生成与行为进行自定义控制。报表脚本编程可以在报表模板中直接实现对报表的自定义控制,通过修改报表模板而不是修改源程序达到对报表运行行为的维护修改。

报表脚本属性的名称为对应事件的名称再加上“Script”。如果事件由某个报表子对象的相关行为触发,则对应报表脚本属性定义在此子对象上;反之,其它的事件脚本属性定义在报表主对象上。

在所有的事件脚本中,都有一个内建变量 Report 可以使用,其是对报表主对象的引用。如果事件有一个触发子对象与之关联,则有一个内建变量 Sender 可以使用,它是对触发事件的子对象的引用。

报表脚本都有一个触发报表对象,一般这个触发报表对象对应脚本中的内建 Sender 变量。下面就根据触发报表对象分类列出各个报表脚本属性并进行简要说明。

报表脚本概述

报表主对象上的脚本属性

  1. 初始化脚本(InitializeScript): 在报表生成开始时执行本脚本。报表开发者可以对报表模板定义进行修改调整。例如用户要从所有可选的列中选择一部分列显示,就可以在此事件中以编程方式动态定义列。
  2. 导出前脚本(ExportBeginScript): 在报表导出数据执行之前触发,可以在本脚本中改变导出选项参数,自定义报表的默认导出行为。本脚本对应的 Sender 变量为 IGRExportOption 接口引用,根据导出数据类型,可以把 Sender 对象转换为具体的导出类型对象,具体请参考 IGRExportOption 接口的编程参考帮助。
  3. 开始处理脚本(ProcessBeginScript): 当报表准备对填入的数据进行分析处理之前触发,可以在此脚本中对已填入的数据进行一些修改与补充,例如根据需要在记录集的后面追加一些空白记录。
  4. 结束处理脚本(ProcessEndScript): 当报表对填入的数据进行分析处理完成之后触发。
  5. 排序前脚本(BeforeSortScript): 当要对记录集中的记录进行重新排序之前触发本。如果设置了记录集的排序字段(SortFields)属性,在每次生成报表时,在 BeginPeocessRecord 事件之前会触发 BeforeSort 事件。另当查询显示器设定为可排序时,点击明细网格的列标题会按点击的列对记录进行重新排序,此时也会触发BeforeSort事件。
  6. 页开始脚本(PageStartScript): 在开始生成一个打印页面时触发。
  7. 页结束脚本(PageEndScript): 在完成一个打印页面生成时触发。
  8. 预览前脚本(ShowPreviewWndScript): 在显示默认打印预览窗口时触发。本脚本对应的 Sender 变量为 IGRPrintViewer 接口引用,在本脚本中通过 Sender 变量改变打印显示控件的属性,从而达到定制打印预览窗口的目的,如隐藏工具栏上的某些按钮等。

记录集上的脚本属性

  1. 处理记录脚本(ProcessRecordScript): 当报表生成时,会按顺序遍历每一条记录,每当遍历一条记录时触发执行本脚本。在此脚本中,可以取记录的各个字段的值。报表开发者可以在此脚本中对数据进行一些自定义的分析统计。
  2. 取记录脚本(FetchRecordScript): 在报表生成时,报表主对象请求数据时触发。
  3. 提交记录前脚本(BeforePostRecordScript): 在向报表记录集中填入记录数据的过程中,每当提交一条记录之前触发件。在此脚本中,我们可以对当前记录的各个字段值进行重新设置。譬如可以设置需要由其它字段通过计算得来的字段值。
  4. 页处理记录脚本(PageProcessRecordScript): 当报表在生成打印页面数据时,会再次按顺序遍历每一条记录,此遍历果城中每当遍历一条记录时触发。

分组上的脚本属性

  1. 分组开始脚本(GroupBeginScript): 在生成报表时,开始一个新分组项时触发。
  2. 分组结束脚本(GroupEndScript): 在生成报表时,一个新分组项结束时触发。

字段上的脚本属性

  1. 取显示文字脚本(GetDisplayTextScript): 当准备获取字段对象的显示文字时触发。在此脚本中可以改写子段的显示文字,通过设置子段的 DisplayText 属性改变其显示文字。例如可以将一个整数字段的显示文字改为任意的非数字文字。

报表节上的脚本属性

  1. 格式化脚本(FormatScript): 当报表节在输出之前触发。包括查询显示与打印生成显示。一般在本脚本中改变节及节中的部件框或单元格的显示外观属性,达到某些突出显示的效果。也可以改变节及节中的部件框或单元格的 Visible 属性,实现按条件动态显示或隐藏报表内容。本脚本会频繁执行到,应注意脚本的运行性能。

部件框上的脚本属性

  1. 自绘脚本(CustomDrawScript): 报表部件框自绘脚本。当部件框为自绘部件框时(部件框的“自绘”属性设置为“是”),部件框在输出显示时会触发本事件,报表开发者应该在本事件中实现部件框的显示输出。

文字部件框上的脚本属性

  1. 取显示文字脚本(GetDisplayTextScript): 当准备获取文字框的显示文字时触发。在此脚本中可以改写文字框的显示文字,通过设置文字框的 DisplayText 属性改变其显示文字。文字框包括静态框、字段框、统计框、系统变量框与综合文本框。

编写报表脚本代码

脚本语言类型可以为 JScript 或 VBScript,新建报表默认为 JScript。如果要使用 VBScript 脚本语言,通过报表主对象的“脚本类别(ScriptType)”属性指定为 VBScript。

首先选中要编写报表脚本的报表对象,然后在属性编辑窗口选中对应脚本属性,执行脚本属性行右边的“...”按钮可以打开脚本编辑窗口,在此窗口中输入脚本代码。下图为脚本编辑窗口界面:


image.png

在所有的事件脚本中,都有两个内建变量 Report 与 Sender 可以使用,Report 变量是对报表主对象的引用。如果事件脚本有一个触发报表子对象与之关联,内建变量 Sender 是对触发事件的报表子对象的引用;反之 Sender 与 Report 都是对报表主对象的引用;如 FieldGetDisplayTextScript 脚本中,Sender 表示触发此事件的字段对象(IGRField)。通过 Report 与 Sender 变量就可以获取或设置报表对象的属性,调用报表对象的方法,请借助本帮助中编程参考部分应用对象的属性与方法。

在上面的脚本编辑窗口中,为字段的“取显示文字脚本”属性上的报表脚本。其中的 Sender 表示字段对象,当其值为空时,将字段的显示文本属性设为“待定”;当其布尔值为真时,将字段的显示文本属性设为“热卖中”,反之设为另外的“停止销售”。

浏览报表脚本 - 开发指南

整个报表脚本代码浏览功能就是在一个窗口中集中查看整个报表中的全部脚本代码,这样可以方便了解整个报表中的脚本定义情况,以及各个脚本之间的关联关系。

执行报表主对象上的“浏览报表脚本”属性命令可以打开整个报表脚本代码浏览窗口,如下图。


image.png

在脚本代码浏览窗口中不能编辑脚本,从列表中选择对应的脚本并执行“编辑脚本...”按钮,或双击下面编辑框中的脚本代码可以打开对应的脚本编辑窗口。

浏览报表脚本代码

报表参数可以用来存储脚本运行得到的计算值,以供脚本下一次运行使用,或在另一个脚本中应用。如果某个脚本在报表的一次运行过程中会多次执行到,且一次运行需要用到上一次运行的结果值,这样的方式就需要借助报表参数来存储上一次运行的结果值。如果要实现某项功能需要编写多个报表脚本才能达到,且不同脚本之间需要传递计算值,也需要借助报表参数。

例子1:用报表脚本实现收发存功能

实现一个库存收发存报表,库存有一个期初数,列出每笔库存变动记录,并计算出变动后的结余库存数。用一个报表参数存储期初数,在记录集的“提交记录前脚本”中计算出余额值。

//余额字段的值由上一笔的余额值加上本笔入库数量减去本笔出库数量
Report.FieldByName("Balance").AsFloat = Report.ParameterByName("Balance").AsFloat + 
Report.FieldByName("IncQty").AsFloat - Report.FieldByName("DecQty").AsFloat

//更新参数的值为本笔的余额,以供下笔计算使用
Report.ParameterByName("Balance").AsFloat = Report.FieldByName("Balance").AsFloat;

例子2:实现自定义统计计算

实现分组统计自定义计算,要求统计金额大于1000以上的数据的合计值。实现这样需要定义一个报表参数存储中间运算值,在分组的“分组开始脚本”中设置报表参数的值为0,在记录集的“处理记录脚本”中按条件累加报表参数的值,在分组的“分组结束脚本”中将报表参数的值传递给要展现这个统计值的统计框。

分组开始脚本如下:

//初始统计值设为0
Report.ParameterByName("SumAmt").AsFloat = 0;
处理记录脚本如下:
//按条件累加报表参数的值
var AmtField = Report.FieldlByName("Amt");
if (AmtField.AsFloat >= 1000)
{
  var AmtParam = Report.ParameterByName("SumAmt");
  AmtParam.AsFloat= AmtParam.AsFloat + AmtField.AsFloat;
}

分组结束脚本如下:

//将报表参数的值传递给要展现这个统计值的统计框
Report.ControlByName("SumBox").Value = Report.ParameterByName("SumAmt").AsFloat;

调试报表脚本

报表主对象的初始化脚本实现根据报表参数动态确定列的可见性

说明:根据参数值确定某个列实现显式出来


Report.ColumnByName("Column1").Visible = Report.ParameterByName("ShowColumn1").AsBoolean;
Report.ColumnByName("Column2").Visible = Report.ParameterByName("ShowColumn2").AsBoolean;

报表主对象的开始处理脚本实现追加空白记录

描述:报表中有金额线列,每页打印固定行数,最后一页用空白行补齐,让空白行也显示出金额线列。直接用明细网格的追加空白行不能达到金额线列也显示出金额线,而是应该通过追加空白记录的方式来实现。

//假设每页要显示20 行,求出最后要补充的行数
var AppendRows = 20 - (Report.DetailGrid.Recordset.RecordCount % 20);
if (AppendRows == 20)
  AppendRows = 0;
for (i=0; i<AppendRows; ++i)
{
  Report.DetailGrid.Recordset.Append();
  Report.DetailGrid.Recordset.Post();
}
报表主对象的预览前脚本实现隐藏打印显示器的工具栏上的部分按钮
//隐藏发送电子邮件按钮与保存报表文档菜单相
Sender.RemoveToolbarControl(6); //grtctMail
Sender.RemoveToolbarControl(7); //grtctSaveDocument

//显示出导航窗口,以单页模式查看报表
Sender.ShowBookmark = true; //显示出导航窗口
Sender.ViewMode = 2; //grpvmSinglePage 按单页模式查看。 

记录集的提交记录前脚本实现计算字段

//字段值根据其它子段计算得来
Report.FieldByName("CalcAmount").AsFloat = Report.FieldByName("Quantity").AsFloat * Report.FieldByName("Unitprice").AsFloat; 

字段的取显示文字脚本实现字段显示文字的改变

//将一个整数字段根据不同的值显示不同的文字
if (Sender.AsInteger == 5)
  Sender.DisplayText = "优秀";
else if (Sender.AsInteger == 4)
  Sender.DisplayText = "良好";
else if (Sender.AsInteger == 3)
  Sender.DisplayText = "达标";
else
  Sender.DisplayText = "不及格";
报表节的格式化脚本实现突出显示

//这是一个写在内容行上的脚本,通过改变外观属性实现以不同方式显示不同类别的内容
//当Amount字段的值大于等于5000时,将Amount显示为粗体,绿色,背景色为白色
//当Amount字段的值大于等于1000时,将Amount显示为正常体,黄色,背景色为蓝色
//当Amount字段的值小于1000时,将Amount显示为正常体,红色,背景色为白色
var AmountContentCell = Sender.ContentCells.Item("Amount");
var AmountField = Report.FieldByName("Amount");
var FontBold;
var FontItalic;
var TextColor;
var BackColor;
if (AmountField.AsFloat >= 5000)
{
  FontBold = true;
  FontItalic = false;
  TextColor = GetColorValue(0, 255, 0);
  BackColor = GetColorValue(255, 255, 255);
}
else if (AmountField.AsFloat >= 1000)
{
  FontBold = false;
  FontItalic = false;
  TextColor = GetColorValue(255, 255, 0);
  BackColor = GetColorValue(0, 0, 255);
}
else
{
  FontBold = false;
  FontItalic = true;
  TextColor = GetColorValue(255, 0, 0);
  BackColor = GetColorValue(255, 255, 255);
}

//当为打印输出状态时,文字颜色始终为黑色,背景色始终为白色
//if (Report.DisplayMode == grrdmPrintGenerate)
if (Report.DisplayMode == 2)
{
  TextColor = GetColorValue(0, 0, 0);
  BackColor = GetColorValue(255, 255, 255);
}

AmountContentCell.Font.Bold = FontBold;
AmountContentCell.Font.Italic = FontItalic;
AmountContentCell.ForeColor = TextColor;
AmountContentCell.BackColor = BackColor;

function GetColorValue(r,g,b)
{
  return r + g*256 + b*256*256;
}
报表节的格式化脚本实现分组尾按条件隐藏
//这是一个写在分组尾上的脚本,根据条件动态设置 Visible 属性
Sender.Visible = (Report.FieldByName("Type").AsInteger == 0);
报表节的格式化脚本根据页号显示或隐藏报表节或部件框
//只在第一页显示当前报表节
Sender.Visible = (Report.SystemVarValue(3) == 1);

//如果是第一页不显示一个部件框
Report.ControlByName("MemoBox1").Visible = (Report.SystemVarValue(3) != 1);
控制某个部件框在最后一页显示
Report.ControlByName("MemoBox1").Visible = (Report.SystemVarValue(3) == Report.SystemVarValue(2));
部件框的自绘脚本实现自定义图形与文字绘出
function GetColorValue(r,g,b)
{
  return r + g*256 + b*256*256;
}

var Graphics = Report.Graphics;

var x = Graphics.Left;
var y = Graphics.Top;
var width = Graphics.Width;
var height = Graphics.Height;

var PartSize = height/3;
var DrawLeft = x + (width - PartSize)/2;
var DrawRight = DrawLeft + PartSize;
var DrawXCenter = (DrawLeft + DrawRight)/2;

var DrawTop = y;
var DrawBottom = y + height;

//设定绘出线型
Graphics.SelectPen(2, GetColorValue(255, 0, 0), 0/*grpsSolid*/);

//设定填充色
Graphics.SelectFillColor( GetColorValue(0, 255, 255) );

//画箭头两边斜线
Graphics.MoveTo(DrawLeft, DrawTop+PartSize);
Graphics.LineTo(DrawXCenter, DrawTop);
Graphics.LineTo(DrawRight, DrawTop+PartSize);

//画箭头竖线
Graphics.MoveTo(DrawXCenter, DrawTop);
Graphics.LineTo(DrawXCenter, DrawTop+PartSize*2);

//画出圆圈
Graphics.Ellipse(DrawLeft, DrawTop+PartSize*2, PartSize, PartSize, true);

//恢复填充色设定,SelectFillColor调用之后,必须对应调用RestoreFillColor
Graphics.RestoreFillColor();

//恢复绘出线型设定,SelectPen调用之后,必须对应调用RestorePen
Graphics.RestorePen();
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容