Appearance
前言:本文专门为DELPHI开发程序员学习而写,普通的二次开发和项目实施人员无需阅读。
第26章 特殊事件
OnGetValue事件:在对象文本中的变量需要数据时触发。
OnBeforePrint事件:在画出所有对象之前触发,常用于调入备注字段的内容或从数据库调入图像。
OnUserFunction事件:当对象文件中的变量或表达式包含函数时触发。
第27章 TRMReport对象其它事件
| 事件 | 描述 |
|---|---|
| OnBeginBand | 数据部分被定义时触发 |
| OnBeginColumn | 报表切换不同分栏时触发 |
| OnBeginDoc | 报表生成之前触发 |
| OnBeginPage | 页面生成之前触发 |
| OnEndBand | 数据部分正确生成之后触发 |
| OnEndDoc | 报表生成之后触发 |
| OnEndPage | 页面生成之后触发 |
| OnManualBuild | 生成报表定制时触发 |
| OnPrintColumn | 生成交叉报表栏时触发 |
| OnProgress | 标明当前生成进度时触发 |
第28章 变量
可以在ReportMachine的对象和表达式中使用变量。
变量的查找顺序:
- 数据字典中有这个变量
- 它是一个数据字段
- 它是一个专用变量(Page#、Date、Time等)
- 它是RmVariables列表中的变量
- 它是一个对象的属性
- 它是RmConsts中的常量
在数据字典,我们建议大家提前定义自己需要的中文保留,目的是 —— 降低代码阅读的困难程度。
变量赋值方法:
通过frVariables:
pascal
frVariables['Reporting Period'] := 'January';
frReport1.ShowReport;通过OnGetValue事件:
pascal
procedure TForm1.frReport1GetValue(const ParName: String; var ParValue: Variant);
begin
if AnsiCompareText(ParName, 'Reported Period') = 0 then
ParValue := Table1OtchPeriod.Value;
end;通过编程为变量列表赋值:
pascal
with frReport1.Dictionary do
begin
Variables['Number'] := 1;
Variables['Sum'] := '0.2 * Table1."Summa"';
Variables['Date'] := '''' + 'January' + '''';
end;第29章 扩展ReportMachine函数
ReportMachine生成器是开放的,可通过自己的函数库、新的可视控件、输出文件格式和向导来扩展。
29.1 设计自己的预览窗口
使用TRMPreview控件。
主要功能:
- First, Prev, Next, Last —— 导航
- SaveToFile —— 保存已生成的报表
- LoadFromFile —— 调入已生成的报表
- Print —— 打印已生成的报表
- OnePage —— 设置预览比例为1页
- PageWidth —— 设置预览的页面宽度
29.2 扩展函数
可写一个TRMFunction的继承类:
pascal
TRMFunction = class(TObject)
public
procedure DoFunction(p1, p2, p3: Variant; var val: Variant;
Const FunctionName : String = ''); virtual; abstract;
end;注册函数:调用RegisterRMFunction方法。
第七篇:报表示例
第30章 示例概览
ReportMachine配套有示例项目:
- 在报表中插入图表(Chart目录)
- 存储临时报表到Delphi窗体(DFMSTORE目录)
- 组织“最终用户”工作环境(USER目录)
- 使用数据感知控件(ENDUSER1目录)
- 运用OnManualBuild事件控制报表逻辑结构(MANUAL目录)
- 运行时使用代码手工合成报表(RUNTIME目录)
- 打印可变栏数或未知栏数的报表(PRNTBL1目录)
- 打印可变栏数和栏宽可变的报表(PRNTBL2目录)
- 使用标准和Delphi设计器创建不同的报表(REPORTS目录)
第31章 在报表中插入图表
在报表窗体上放置Chart对象,在图表编辑器的“数据”页中设置“图例”和“值”。
“前X个分组”仅显示前X个值,其它值放在“其它”栏中。
第32章 运用OnManualBuild事件控制报表逻辑结构
通过OnManualBuild事件处理控制报表内容的逻辑结构。
pascal
procedure TForm1.frReport1ManualBuild(Sender: TRMPage);
begin
Sender.ShowBandByType(btReportTitle);
for i := 0 to 3 do
begin
Sender.ShowBandByName('Band2');
for j := 0 to 2 do
Sender.ShowBandByName('Band3');
if i <> 3 then
Sender.NewPage;
end;
end;第33章 运行时使用代码手工合成报表
当报表结构在设计阶段不确定或需要在运行时改变时,动态创建报表模板。
pascal
procedure TForm1.Button1Click(Sender: TObject);
var
v: TRMView;
b: TRMBandView;
Page: TRMPage;
begin
frReport1.Pages.Clear;
frReport1.Pages.Add;
Page := frReport1.Pages[0];
b := TRMBandView(RMCreateObject(gtBand, ''));
b.SetBounds(0, 20, 0, 20);
b.BandType := btMasterData;
b.Dataset := 'frDBDataSet1';
Page.Objects.Add(b);
v := RMCreateObject(gtMemo, '');
v.SetBounds(20, 20, 200, 16);
v.Memo.Add('[Table1."Company"]');
Page.Objects.Add(v);
frReport1.ShowReport;
end;第34章 打印可变栏数或未知栏数的报表
使用交叉表达到目的。
在OnGetValue事件中设定字段值:
pascal
procedure TForm1.frReport1GetValue(const ParName: String; var ParValue: Variant);
begin
if ParName = 'Cell' then
ParValue := Table1.Fields[frUserDataset1.RecNo].Value;
if ParName = 'Header' then
ParValue := Table1.Fields[frUserDataset2.RecNo].FieldName;
end;第35章 打印可变栏数和栏宽可变的报表
使用OnPrintColumn事件动态定义栏宽:
pascal
procedure TForm1.frReport1PrintColumn(ColNo: Integer; var Width: Integer);
var
Field: TField;
begin
Field := Table1.Fields[ColNo - 1];
if Field is TStringField then
Width := Field.Size * Canvas.TextWidth('W')
else if Field is TDateTimeField then
Width := 15 * Canvas.TextWidth('W')
else
Width := 64;
FWidth := Width;
end;OnBeforePrint事件处理中将栏宽设为上面定义的宽度:
pascal
procedure TForm1.frReport1EnterRect(Memo: TStringList; View: TRMView);
begin
View.dx := FWidth;
end;