FastReport V2.4 开发人员指南中文翻译(部分,未完成,请帮助提前以让更多的人可以得到帮助) (0分)

  • 主题发起人 主题发起人 京工之鸟
  • 开始时间 开始时间

京工之鸟

Unregistered / Unconfirmed
GUEST, unregistred user!
一个人翻译实在太慢,工作量巨大,有一百三十多页呢,有没有兄弟愿意一起干?大家分头翻译一部分应该
一两个礼拜就可以搞定,然后制作成一个pdf:)
FastReport V2.4 FAQ
---------------- 使用自定义函数 ----------------------------------------
问: 我怎样才可以自己添加函数?
答: 用TfrReport.OnUserFunction事件。简单的范例如下:
procedure TForm1.frReport1UserFunction(const Name: String;
p1, p2, p3: Variant;
var val: Variant);
begin

if AnsiCompareText('SUMTOSTR', Name) = 0 then

val := My_Convertion_Routine(frParser.Calc(p1));
end;

然后你就可以在报表中使用SumToStr函数:)

问: Ok, 但是这个函数仅仅在一个TfrReport组件中其作用.可以让这个函数在所有的
TfrReport组件中都能使用吗?
答: 给所有报表组件的OnUserFunction事件赋句柄:)如果你不想这么干的话,你就
只好创建一个函数库了:
type
TMyFunctionLibrary = class(TfrFunctionLibrary)
public
constructor Create;
override;
proceduredo
Function(FNo: Integer;
p1, p2, p3: Variant;
var val: Variant);
override;
end;

constructor TMyFunctionLibrary.Create;
begin

inherited Create;
with Listdo

begin

Add('DATETOSTR');
Add('SUMTOSTR');
end;

end;

procedure TMyFunctionLibrary.DoFunction(FNo: Integer;
p1, p2, p3: Variant;
var val: Variant);
begin

val := 0;
case FNo of
0: val := My_DateConvertion_Routine(frParser.Calc(p1));
1: val := My_SumConvertion_Routine(frParser.Calc(p1));
end;

end;

注册函数库可以调用:
frRegisterFunctionLibrary(TMyFunctionLibrary);
同样,取消注册可以用:
frUnRegisterFunctionLibrary(TMyFunctionLibrary);

问: 怎样可以把自定义函数增加到函数列表中去?
答: 用frAddFunctionDesc过程(在FR_Class单元中):
frAddFunctionDesc(FuncLib, 'SUMTOSTR', 'My functions',
'SUMTOSTR(<Number>/Converts number to its verbal presentation.');

注意: "/"符号是必需的!它标示了哪段是函数的声明部分哪段是描述部分.
FuncLib指向你的函数库(可以为nil如果你没有使用函数库的话),当函数库取消注册时,
它包含的所有函数自动从函数列表中移出。

---------------- 使用变量 -------------------------------------
问:怎样在程序中给数据字典的变量列表赋值?
答:数据字典中的所有分类和变量都可以用TfrReport.Dictionary.Variables来访问存取。
with frReport1.Dictionarydo

begin

// creating category (space in category name required!)
Variables[' New category'] := '';
// creating variables
Variables['New Variable'] := 'CustomerData.Customers."CustNo"';
Variables['Another Variable'] := 'Page#';
end;

问:我自定义了一个变量并赋了一个字符串值给它,
with frReport1.Dictionarydo

Variables['Month'] := 'March';

但当我运行报表时却出错,为什么?
答:因为FastReport把你赋给变量的值当作了一个需要解析和计算的表达式。你可以加一个引号上去:
with frReport1.Dictionarydo

Variables['Month'] := '''' + 'March' + '''';

或者,用frVariables来传递静态的值给报表。
问:有什么办法可以不要把所有的数据集都显示在数据字典中?
答:用TfrReport.Dictionary.DisabledDatasets:
with frReport1.Dictionarydo

begin

// turn of this dataset
DisabledDatasets.Add('CustomerData.Bio');
// or, turn off entire datamodule/form
DisabledDatasets.Add('CustomerData*');
end;


问:怎样传递数据给报表?
答:有几种方法都可以实现,第一个方法是使用全局对象frVariables(定义在FR_Class单元中的)
frVariables['My variable'] := 10;

这行代码用My variable作为名字创建一个新变量并赋值为10。
这是传递静态数据给报表的最好方法。
第二个方法是用TfrReport.OnGetValue事件。可以用这个方法来传递动态数据,比如值随着记
录的不同而改变的数据。
procedure TForm1.frReport1GetValue(ParName: String;
var ParValue: Variant);
begin

if ParName = 'MyField' then

ParValue := Table1MyField.Value;
end;

最后,第三种方法是用代码在数据字典中定义变量(可参考上面的问题):
with frReport1.Dictionarydo

begin

Variables['MyVariable'] := 'CustomerData.Customers."CustNo"';
Variables['Another Variable'] := '10';
end;


问:可以从报表中传递数据给程序吗?
答:用frVariables对象,如果在报表中任意一个对象的脚本里有写下面的代码:
MyVariable := 10
在程序中可以用如下的代码来获取MyVariable变量的值:
v := frVariables['MyVariable'];

---------------- 脚本 (FastReport Pascal) ---------------------------------
问:band有脚本吗?
答: 有,选中band,然后按下Ctrl+Enter 或在对象查看器里选择"OnBeforePrint"属性。

问: 报表页有脚本吗?
答: 有,选择页面(点击空白的地方),并在对象查看器里选择"OnBeforePrint"属性。
如果页面是对话框窗体,选择"OnActivate"属性。

问: 有两个对象:Memo1和Memo2. 可以在Memo1的脚本中调用memo2的属性和方法吗?
答: 可以,用逗号。像ObjectName.PropertyName.

问: 哪个对象的属性可以在脚本中使用?
答: 几乎所有你能在对象查看器中看到的属性都可以。字体属性可以用Font.Name, Font.Size
来调用。
---------------- 其他问题 --------------------------------------------
问: 多页报表中怎样改变页面的顺序?
答: 拖动页面的tab到你想放的位置.

问: 可以在同一个列表中显示所有想要插入到报表中的字段和变量吗?
答: 设置TfrReport.MixVariablesAndDBFields := True. 这样所有的字段和变量都将一起
出现在“插入数据字段”列表框中。

问: 可以不显示输出选项对话框吗?
答: 在输出组件(比如TfrTextExport)中设置所有可用的选项,可以用把ShowDialog属性
设置为Fasle来关闭输出对话框。

问: 为什么变量TotalPages不起作用?它的值总是为0.
答: 在设计器的文件-报表选项中给设置两遍报表选项。

问: 在把报表存在BLOB字段中时,如果用设计器打开报表,在标题栏会显示报表名为“未命名”。
答: 在打开设计器前,插入类似下面的代码:
frReport1.FileName := 'Name of my report';

问: 像上面一样时,在设计器中怎么才能插入自己的“打开文件”和“保存文件”事件?
答: 看一下TfrDesigner组件.它提供了所需要的事件:OnLoadReport和OnSaveReport. 下面是一
个简单的范例:
procedure TForm1.frDesigner1LoadReport(Report: TfrReport;
var ReportName: String;
var Opened: Boolean);
begin

with MyOpenDialogdo

begin

Opened := ShowModal = mrOk;
if Opened then

begin

Report.LoadFromBlobField(...);
ReportName := ...;
end;

end;

end;

procedure TForm1.frDesigner1SaveReport(Report: TfrReport;
var ReportName: String;
SaveAs: Boolean;
var Saved: Boolean);
begin

if SaveAs then

with MySaveDialogdo

begin

Saved := ShowModal = mrOk;
if Saved then

begin

Report.SaveToBlobField(...);
ReportName := ...;
end;

end
else

Report.SaveToBlobField(...);
end;


问: 在QR中,可以写类似这样的代码:QRLabel1.Caption := 'Some text'. 在FR中可以吗?
答: FR的对象不是像QR,RB中那样是一个组件. 请用TfrReport.FindObject方法来查找对象:
var
t: TfrMemoView;
begin

t := TfrMemoView(frReport1.FindObject('Memo1'));
if t <> nil then

t.Memo.Text := 'FastReport';
end;


问: 在自定义的预览界面中可以定义快捷键吗?
答: 预览控件有一个窗体属性,在窗体的OnKeyDown事件中写事件代码。

问: 怎样才可以在不先预览的情况下直接打印报表?
答: 代码如下:
frReport1.PrepareReport;
frReport1.PrintPreparedReport('', 1, True, frAll);
or
frReport1.PrintPreparedReportDlg;

问: 想放一个在程序中创建的图片到报表中,有什么办法可以在报表打印前动态调用
这个图片到报表中吗?
答: 使用TfrReport的OnBeforePrint事件:
if View.Name = 'Picture1' then

TfrPictureView(View).Picture.LoadFromFile(...) or
.Assign or
.everything_what_you_want
=====================================================================================================
FastReport V2.4开发人员指南中文翻译
前言
本手册假设你已经对制作报表相当的熟练,并且已经理解了制作报表所必须掌握的基本概念,像诸如边条(band)、数据源(data sources)、两遍报表(two-pass reports)等等。这本手册将帮助你学会怎样使用FastReport来创建报表,但并不会给你讲那些非常基础的报表知识。
如果你对制作报表不是很熟练的话,我建议你先参考QuickReports的帮助系统。正常的话,这个帮助文件应该在你的Delphi中可以找到。你在QuickReports中学到的报表制作的基本概念在绝大多数的FastReport案例中都同样适用。但是FastReport在灵活性和最终用户自定义方面提供了更大的自由度。

关于FASTREPORT的说明
FastReport是一个具有高度灵活性的报表设计器,在报表中处理的数据可以从几乎任何类型的数据源中获得,包括字符串列表(strings lists)、BDE数据源、ADO数据源、Interbase数据库、Pascal数组和记录等等各种数据源。
整个FastReport系统完全用Delphi Pascal写成,没有附带任何额外的动态链接库。在Delphi5中使用FastReport将把你的空项目的大小增加大约400k。如果需要支持最终用户自定义设计报表的功能,你的可执行文件的大小将大约会增加500k 。虽然这看起来好象有点大,但实际上这个大小相对于其他报表工具所干的数字来说,你就会发现它真的是很小了呢。同时要提醒你的是,FastReport给最终用户提供的功能并不仅仅是改变报表的设计,同时也可以改变数据的查询和来源。FastReport内置了自己的脚本语言,以确保开发人员和最终用户都可以非常简单的设计或改变所有的报表。如果你的多个应用系统都使用FastReport的话,你只需简单的配置一下FastReport的bpl(大约1400k),这样,你的所有程序都可以共用这个包,从而可以避免额外的扩大可执行文件的大小。
可能你已经发现,FastReport有一个非常友好的用户界面,比如可停靠的工具条等等。这是因为我们使用了最新的用户界面控件。在我们的设计器中,几乎所有的报表都可以仅仅通过使用鼠标来创建,这一定会让你的最终用户感到非常的满意。
FastReport之所以起名FastReport:很简单,和任何Delphi的报表工具相比,你会发现在快速上没有任何一个工具可以与之相比。相对于其他工具,报表预览窗口的完美无暇也同样将使你的应用程序看起来非常的专业。
FastReport是一个一步一步、一点一点的改进了三年多的报表工具,它逐步发展完善的各种强大的功能是其他Delphi报表工具所无法相比的。

FASTREPORT的版本历史
FastReport是应需而生的。我97年在写一个薪资系统时,费劲心思四处寻找一个可以简单方便的创建报表并且又能够在运行期修改报表的报表设计工具,但是,最后我没有找到这样一个适合我的需要的组件,所以我决定做一个自己的报表工具,它就是FastReport。
FastReport的基本思路是从“1S-Bookkeeping” 6.0 for Windows中来的,在这个工具中,基本的报表对象是一个带边框的其中有多行文本的矩形。其中的文本包括标准的文本也包括变量,这些变量类似于数据字段,被一对方括号所包含。第一版的FastReport仅包含一个边条(band),但它已经可以创建多层的报表。那个时候它还不是一个组件,仅仅是几个单元而已。
后来,在98年,FastReport开始成为一个真正羽翼丰满的Delphi组件。也就是从那个时候开始,它被命名为FastReport,并且逐渐的增强了功能。到现在,FastReport已经成为一个完全成熟的、工业化的可视化报表开发工具。它的主要特性包括:
&amp;#8226;
内置可以在设计期和运行期使用的报表设计器,支持最终用户自定义报表!
&amp;#8226;
类似于MS Word打印预览窗体的预览界面;
&amp;#8226;
直接编译进Delphi产生的可执行文件,不需额外的动态连接库;
&amp;#8226;
支持JPEG (使用Delphi库文件)和 GIF (使用 RX 库文件)格式;
&amp;#8226;
快速的执行效率堪与QuickReport1 媲美,并拥有更多的特性和功能;
&amp;#8226;
简洁优美的纯Delphi代码;
&amp;#8226;
强大的基于面向边条技术的报表设计工具,类似于QuickReports 和ReportBuilder ;
&amp;#8226;
一系列非常有用的组件,包括:Text, Line, Picture, Shape, OLE object, RichText, RX Rich 2.0, Chart, Barcode, shadowed text;
&amp;#8226;
可生成无限制页数报表;
&amp;#8226;
多页报表;复合报表;子报表;分组;多列报表;主从报表;交叉表报表;两遍报表;
&amp;#8226;
全程打印控制;支持各种字张类型;
&amp;#8226;
可输出为TXT、 RTF (带图片)、 CSV、 HTML (带图片) 等各种格式;
&amp;#8226;
预览时仍可进行文本查找;
&amp;#8226;
附带的TfrDataStorage组件可在运行期动态创建表单和查询,这对最终用户完全控制报表处理具有非常突出的好处;
&amp;#8226;
报表预览时可直接修改;
&amp;#8226;
内置的Pascal语法解析器可以支持非常灵活的报表;如果使用一个完全免费的第三方控件将支持语法高亮显示;
&amp;#8226;
报表数据可以储存在Delphi的 DFM文件、外置文件、数据表的BLOb字段中,并且可以流化(streamed);
&amp;#8226;
可以方便的开发你自己的报表组件、向导和函数库;
&amp;#8226;
不需要BDE即可由报表内核直接支持IBObjects;
&amp;#8226;
支持Interbase Express (IBX);
&amp;#8226;
报表内核支持ADO;
&amp;#8226;
不需要BDE即可实现完全的数据管理功能;
=======================================================================================================
后面的先翻译了,先帖出来吧:)
编程

事件句柄
变量
功能扩展

事件句柄
有时候我们要从非数据库的数据源(比如文件、数组等等)获取数据。TfrUserDataset组件就是为了解决这个问题而设计的。它产生如下几个事件:OnFirst, OnNext, OnCheckEOF,除此之外,TfrReport组件的OnGetValue和OnBeforePrint事件句柄也必须实现。
每次当一个对象的文本中包含变量并且需要获得这个变量的值时,OnGetValue事件句柄就会被调用。当变量取到值后组件内部的句柄就会处理这个变量。否则的话,它就必须附加到别的外部句柄上,比如:
procedure TForm1.Doc1GetValue(const ParName: string;
var ParValue: Variant);
begin
if ParName = 'Var1' then
ParValue := '1'
else
if ParName = 'Var2' then
ParValue := 2
end;

OnBeforePrint事件句柄会在打印前的内部描绘时被调用。通常,它被用来从数据库中装载memo字段或图片的内容给对象。这个句柄的范例如下:

procedure TForm1.Doc1BeforePrint(Memo: TStringList;
View: TView);
begin
if Memo.Count > 0 then
if Memo[0] = '[Memo]' then
Memo.Assign(Table1Memo)
else
if (Memo[0] = '[Picture]') and (View is TPictureView) then
(View as TPictureView).Picture.Assign(Table1Picture);
end;

OnUserFunction事件句柄会在对象的文本中发现包含函数调用的变量或表达式时被调用。函数最多可以有三个任意类型的参数。该句柄范例如下:
procedure TForm1.Doc1UserFunction(const name: string;
p1, p2, p3: Variant;
var val: Variant);
var
d:do
uble;
begin
if name <> 'MONEYTOSTR' then
Exit;
d := frParser.Calc(p1);
val := MyMoneyToStr(d);
end;

TfrUserDataset 组件是用来连接非数据库的数据源用的。它会产生OnFirst, OnNext 和 OnCheckEOF事件。显然,这几个事件的使用都非常简单。

TfrReport 对象的其他事件
除了上面写的那些事件以外,FastReport 还有很多其他的事件句柄:
&amp;#8226;
Onbegin
Band – 该事件会在数据块成型前被调用。数据正在处理的那个块将被句柄作为参数传递出来。
&amp;#8226;
Onbegin
Column – 该事件会在带轮替列的报表成型前被调用。参数边条(Band)显示当前哪一个多列的块正在被处理。这个事件句柄对用做切换数据源非常有用(使用不同的数据源可以让多列的块有台头、第一级数据、第二级数据…等等)。
&amp;#8226;
Onbegin
Doc – 该事件会在报表成型前被调用。
&amp;#8226;
Onbegin
Page – 该事件在页面成型前被调用。
&amp;#8226;
OnEndBand – 这个事件是在数据块成型后产生的。
&amp;#8226;
OnEndDoc – 该事件会在报表成型后被调用。
&amp;#8226;
OnEndPage –该事件会在页面成型后被调用。
&amp;#8226;
OnManualBuild – 这个事件允许手动(用代码控制)编译(building)报表,如果句柄没有赋值,报表就正常编译。在手动编译报表的时候,你可以改变块的输出顺序。
&amp;#8226;
OnPrintColumn – 这个事件在交叉表报表的列成型前被调用。列的序号和缺省宽度会传递给事件句柄。你可以通过改变宽度来使交叉表报表有不同的列宽。在这种情况下,你必须同时改变在列表单元格中的对象的宽度。
&amp;#8226;
OnProgress – 这个事件被调用以指示当前任务(报表编译、打印、输出)的处理进程。这个句柄可在你自定义的指示器中使用。

变量
在FastReport的对象和表达式中你都可以使用变量。那么,这些变量起什么作用?他们的意图又是什么呢?
假设有一张表employees,它有字段names N, Name1, Name2 和 Name3。有时候确实很难记住每个字段名代表什么,即使是该数据库的开发人员。作为一个替代的方法,我们可以给这些数据库字段起一个通俗易懂的名称(比如表号、姓、名字、外号),然后插入到对象中。另外,变量并不仅可以用来给数据库字段命名,它同样可以用到数学表达式中。举例来说变量可以用做运行期的某个数据字段或日期、时间值等的统计值。更多关于变量的使用范例可以在Demo程序中找到。
在从“文件|数据字典”菜单打开的窗体中,可以设定一个变量列表。

这个变量列表在上图的左半边。从图上你可以看到,这个列表有两级的结构:它有一个类别的分组。每一个类别中可以有很多的变量。类别仅是用作给变量可视化分组,它不能真正插入到报表中。更多关于这部分技术的细节请参看“设计器”那章。
但是,FastReport并不能纯粹独立的使用在数据字典中定义的变量。如果在代码中有一个未知的定义,FastReport会按下面的顺序检查:
&amp;#8226;
在数据字典中是否有这样一个变量;
&amp;#8226;
它是否是一个数据库字段;
&amp;#8226;
它是否是一个特殊值,比如页码(Page#)、日期(Date)、时间(Time)或其他类型;
&amp;#8226;
它是否是frVariables 列表中的某个变量;
&amp;#8226;
它是否是一个对象的属性;
&amp;#8226;
它是否是frConsts 列表中的一个常量;
当然,如果组件的OnGetValue有被赋值,那么它会在以上的所有检查前被调用;如果句柄返回了值,那么这个变量就被当作已经初始化,不再做任何检查。
这样的处理流程提供了一个非常灵活的传递值给报表的途径。特别提醒:
&amp;#8226;
当传递一个不随记录变化而变化的静态值时,可以用frVariables 全局对象。比如:
frVariables['Reporting Period'] := 'January';
frReport1.ShowReport;
&amp;#8226;
当传递一个不随记录变化而变化的值时,可以用数据字典也可以用TfrReport.OnGetValue 事件句柄。比如:
procedure TForm1.frReport1GetValue(const ParName: String;
var ParValue: Variant);
begin
if AnsiCompareText(ParName, 'Reported Period') = 0 then
ParValue := Table1OtchPeriod.Value;
end;

&amp;#8226;
可以编程实现对变量列表的赋值:
with frReport1.Dictionarydo
begin
Variables['Number’] := 1;
Variables['Sum'] := '0.2 * Table1."Summa"';
Variables['Date'] := '''' + 'January' + '''';
end;

(给字符串常量赋值需要用额外的引号来实现).
FastReport把赋给数据字典中的变量的字符串值当作表达式来计算。如果一个变量不是被使用在数据字典中,它则像通常一样使用。
必须记住的是,如果你用了frVariables 列表中的变量或者如果通过OnGetValue事件句柄来给变量赋值,那么这些变量不能放到数据字典中。

FastReport功能扩展
FastReport 是一个开放式的报表工具,这就是说你可以通过添加自己的函数库、新的可视化组件、输出生成器和向导来扩展它的功能。这一节将介绍有关这方面的一些知识。
搭建一个你自己的预览窗体
有时候需要用你自己设计的窗体来替换标准的预览窗体。比如如果你需要在输出前添加额外的功能(像插入打印日期值到表中)或者内置的预览窗体无法满足开发人员的需要时。
无论是什么原因,FastReport 允许开发人员搭建他们自己的预览窗口。在FastReport组件面板页上的TfrPreview组件 就是用作这个用途的。这个组件的主要命令如下:
&amp;#8226;
First, Prev, Next, Last – 用于作第一页、上一页、下一页、最后一页等的报表页面导航。
&amp;#8226;
SaveToFile – 保存已生成的报表到外部文件中,文件格式可以是任何所支持的格式。
&amp;#8226;
LoadFromFile – 从后缀名为FRP格式的文件装载一个已经生成的报表。
&amp;#8226;
Print – 打印已生成的报表。
&amp;#8226;
OnePage – 设置整页显示在预览窗中。
&amp;#8226;
PageWidth – 设置以页宽显示报表。
除了上面介绍的这些命令外,TfrPreview组件有一个缩放的属性用来设置预览页面的大小。预览的页面可以按原始大小的某个百分比大小来显示。TfrPreview组件也会自动显示一个滚动条和带页码、页数的状态栏。
要替换掉FastReport的标准预览窗口,只要把TfrReport 组件的preview 属性指向你自己的预览窗口就好了。在FastReport的“Examples” 目录下的“Reports”子目录中,有一个自定义预览窗口的范例。

扩展函数列表
在本手册的前面有讲到FastReport的函数库可以扩展。这个扩展是基于TfrReport对象的OnUserFunction事件来实现的。这种方法有一个缺点:每个用到了用户函数的TfrReport对象都必须有一个OnUserFunction事件句柄。你可以有的另外一个选择是,把一系列的函数捆绑在一起成为一个独立的单元(函数库)。
这样,你可以编写一个继承自TfrFunctionLibrary的类来扩展你自己的函数库。这个类中定义了可以被开发者使用的基本的一系列属性和方法。
下面是TfrFunctionLibrary基础类在FR_Class模块中的定义:
TfrFunctionLibrary = class(TObject)
public
List: TStringList;
constructor Create;
virtual;
destructor Destroy;
override;
function OnFunction(const FName: String;
p1, p2, p3: Variant;
var val: String): Boolean;
proceduredo
Function(FNo: Integer;
p1, p2, p3: Variant;
var val: String);
virtual;
abstract;
end;

关键的几个方法是:
&amp;#8226;
Create –设计器给函数列表赋值,并按大写字母的顺序排序。
&amp;#8226;
DoFunction – 当调用这个方法时,将在实参部分返回已计算的函数。每一个函数可以有三个参数。这些参数的值会以P1, P2 和 P3的形式传递给DoFunction方法。
下面是一个带有两个函数的简单范例:
type
TMyFunctionLibrary = class(TfrFunctionLibrary)
public
constructor Create;
override;
proceduredo
Function(FNo: Integer;
p1, p2, p3: Variant;
var val: Variant);
override;
end;

constructor TMyFunctionLibrary.Create;
begin
inherited Create;
with Listdo
begin
Add('DATEPROPIS');
Add('SUMPROPIS');
end;
end;

procedure TMyFunctionLibrary.DoFunction(FNo: Integer;
p1, p2, p3: Variant;
var val: Variant);
begin
val := 0;
case FNo of
0: val := My_DateConvertion_Routine(frParser.Calc(p1));
1: val := My_SumConvertion_Routine(frParser.Calc(p1));
end;
end;

为了让一个已经写好的函数库可以在FastReport中使用,你必须先给它注册。注册的方法是调用frRegisterFunctionLibrary过程,并把函数库类的标识符作为参数传递给它。比如:
frRegisterFunctionLibrary(TMyFunctionLibrary);
为了把附加的函数显示在“插入函数”对话框的列表中,你必须带如下的几个参数来调用frAddFunctionDesc过程 :
&amp;#8226;
函数名;
&amp;#8226;
函数类别;
&amp;#8226;
函数语法和用途的文本描述。注意:在函数的描述中&amp;laquo;/&amp;raquo;符号是必不可缺的。它用来把函数的语法和描述分隔开。
记住要把每个函数用frAddFunctionDesc 分隔开来调用。下面是一个函数注册的例子:
frAddFunctionDesc('SUMPROPIS', 'My functions',
'SUMPROPIS(<Number>)/Returns value spelled out.');
=======================================================================================================================
报表范例
报表范例

报表范例
FastReport发布时随带了一些范例用来示范各种*作和制作各种类型报表的方法。范例文件都在Demo子目录下。
在标准的发布包中带了9个范例项目,这些项目演示了以下的一些技巧和方法:
&amp;#8226;
怎样把图片和图表插入到报表中 (在CHART 目录中);
&amp;#8226;
把报表模板保存在Delphi的窗体中,而不必保存到FRF文件中 (在DFMSTORE目录中);
&amp;#8226;
为最终用户搭建工作环境 (在USER目录中);
&amp;#8226;
数据组件的用法 (在 ENDUSER1目录中);
&amp;#8226;
用OnManualBuild 事件来编程控制报表生成的逻辑 (在MANUAL目录中);
&amp;#8226;
在运行期用代码手动控制报表 (在RUNTIME目录中);
&amp;#8226;
带变量或列数不确定的纵列报表的打印 (在PRNTBL1目录中);
&amp;#8226;
用变量控制列宽的报表打印 (在PRNTBL2目录中);
&amp;#8226;
使用标准的Delphi 设计器和开发环境创建各种报表 (在REPORTS 目录中).
上述提及这些范例将帮助你不需要先阅读文档便可以在短期内迅速的了解和掌握你手上这个新报表工具的大部分主要功能。
以下将介绍这些范例中部分项目的细节。

怎样把图片和图表插入到报表中
这个范例在Fastreport的examples 目录下的CHART子目录中。这个项目只包含了一个窗体,在这个窗体上有下面这些组件:
1. 一套TTable/TDataSource组件,用以从数据库的表中提取报表数据 (这个范例用到了Delphi的Demos自带的COUNTRY.DB数据库作为数据源);
2. TfrDBDataSet组件用来把DB的数据源捆绑进FastReport对象中。
3. TfrReport组件 – 报表本身;
4. TfrChartObject 组件 -"图表" 单元;
5. TfrDesigner 组件 – 运行期报表设计器(最终用户报表设计器).
窗体如下:

这个报表总共有三页,每页上都有一张图表。第一个图表显示了COUNTRY表中的AREA字段的垂直列的值。第二个图表描述了类似的数据,但取的是POPULATION字段。为了让这两个图表正确的显示它们的值,设置放在报表窗体上的“图表”对象很重要。通过双击可以打开“图表”对象的编辑器,在“数据”那一页,对象名称框中的“横轴”和“值”必须指定。

在这个范例中,这些字段的值包含有Memo2 和 Memo6。Memo2 和 Memo6 是连接到数据库中COUNTRY AREA 和 POPULATION字段的文本对象的名称。
这样,COUNTRY表中所有记录的对应字段数据将会被保存到“图表”对象中。
第三个图表演示了怎么做称之为“TopX-graphs”的图表。这种图表只显示最大的X个值。其他值的总和显示一个单独的“其他”列中。设置第三个图表需要在设置页面把“显示前…个值”中赋非空值,并且设置好“其他汇总标签”。这个属性设置器的截屏图如下:


这个报表也演示了把所有页面彼此紧凑打印的方法。这将使打印一份报表的多个页面时更加有效。这个功能可以在页面属性对话框中设置相应的标志来激活。

这份报表最终生成的预览窗口如下:


用OnManualBuild 事件来编程控制报表生成逻辑
该范例的源代码在MANUAL 子目录下。
这个范例只有一个简单的窗体,在这个窗体上有一个按下去就可以开始预览的按纽。该报表在设计器中的截屏图如下:

如果在设计器中你按下预览按钮,你只能看到一行绿色背景上面有“Hello!”的一个条。这是因为报表中的两个主项数据条都没有连接到数据源上,所以他们不会被打印出来。
但是,如果你运行这个范例,你看到的报表是一份四页的,并且在其上那两个主项数据条都紧跟着题头栏被打印出来了。这是因为在FastReport对象中的OnManualBuild事件写了下面的代码所以才出来的:
procedure TForm1.frReport1ManualBuild(Sender: TfrPage);
var
i, j: Integer;
begin
Sender.ShowBandByType(btReportTitle);
for i := 0 to 3do
begin
Sender.ShowBandByName('Band2');
for j := 0 to 2do
Sender.ShowBandByName('Band3');
if i <> 3 then
Sender.NewPage;
end;
end;

在这个事件句柄中,题头部分和它内部的所有字段用Sender.ShowBandByType(btReportTitle)控制打印在了第一页上。然后,用在一个循环中的Sender.NewPage 代码创建了四页报表。并且每一页中又用一个循环把&amp;laquo;Cu-cu!&amp;raquo;这个文本打印了三次。
这里,我们展示了怎样在OnManualBuild事件中控制报表逻辑的技巧。这个技巧将使报表多了很多的灵活性。

在运行期用代码手动控制报表
有些时候报表的结构在系统的设计期是不确定的,或有可能在运行期要调整。在这种情况下需要动态的创建报表模板。在诸如此类的情况下,报表不能被程序员固定死甚至不能事先定义好。
在Fastreport中,这种动态创建的报表是可能的。你只需要像动态创建VCL对象一样写上几句代码就可以了。
本范例在RUNTIME 子目录中。
在这个范例中,按下预览按钮后,一份从CUSTOMER.DB 表中取得公司列表的报表就会动态的创建出来。按钮的OnClick事件的源代码如下:

procedure TForm1.Button1Click(Sender: TObject);
var
v: TfrView;
b: TfrBandView;
Page: TfrPage;
begin
frReport1.Pages.Clear;
frReport1.Pages.Add;
// create page
Page := frReport1.Pages[0];
b := TfrBandView(frCreateObject(gtBand, ''));
// create MasterData band
b.SetBounds(0, 20, 0, 20);
b.BandType := btMasterData;
b.Dataset := 'frDBDataSet1';
Page.Objects.Add(b);
v := frCreateObject(gtMemo, '');
// create data field
v.SetBounds(20, 20, 200, 16);
v.Memo.Add('[Table1."Company"]');
Page.Objects.Add(v);
frReport1.ShowReport;
end;

在这段代码中,首先它删除了所有在报表中已经存在的页面,并创建一个空白的页面。
frReport1.Pages.Clear;
frReport1.Pages.Add;
// create page
然后,在这个页面上新建了一个主项数据边条,并把它关联到了数据源。
Page := frReport1.Pages[0];
b := TfrBandView(frCreateObject(gtBand, ''));
// create MasterData band
b.SetBounds(0, 20, 0, 20);
b.BandType := btMasterData;
b.Dataset := 'frDBDataSet1';
Page.Objects.Add(b);
下一步新建了一个文本对象,它关联了CUSTOMER.DB 表中的COMPANY 字段。
v := frCreateObject(gtMemo, '');
// create data field
v.SetBounds(20, 20, 200, 16);
v.Memo.Add('[Table1."Company"]');
Page.Objects.Add(v);
最后,这个事件把准备好的报表预览出来;

带变量或列数不确定的纵列报表的打印
在实际中,经常需要打印一个列数不确定或者列数可以在程序的运行期改变的纵列报表。这种情况下,通常可以用写程序代码来实现。但FastReport为这个问题提供了一个更加简单的解决方案。
我们把这种情况称之为交叉表报表。这种报表的与众不同之处在于打印出来的列的数据。它并不需要事先知道列数。这种报表最特殊的是命名为CrossXXX的部分放置在报表上是垂直的而不是水平的。在这些块上文本对象是放置在和横向边条交叉的部分。在这种情况下,报表的生成遵循下面的原则:横向边条的数据源中的所有记录都依据纵向边条的数据源中的记录来搜索和赋值。
所以,在打印主项数据的数据源所包含的表时,记录从表自身取,但每条记录的字段却是从交叉数据的数据源中取数据。
在PRNTBL1目录中有一个简单的交叉表范例。它的报表在设计期的界面如下:

上面的截图显示了文本对象是放置在主项数据和交叉表数据的交汇点的。如果现在报表已经用CUSTOMER.DB表作为主项数据数据源创建好了,报表的列数是由两个带了CUSTOMER.DB 表中字段数的TfrUserDataset虚拟数据源来决定的。字段的值由TfrReport对象的OnGetValue事件来获取。
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;

这个范例运行时,所有CUSTOMER.DB 表中的记录都将预览出来。下面是预览的屏幕截图:


用变量控制列宽的报表打印
在上一个范例中,它假设报表的所有列宽都是相同的。但是,更多情况下每个列的宽度都需要由内置的数据来指定。比如,有两列,一列中的内容只是行数而另一个列从memo字段读取数据。很显然,第一个列应该是要比第二个列窄很多的。
增强功能后的这个范例原代码放在PRNTBL2子目录中。这个范例和上一个范例完全相似,除了它的列宽是由内置的数据指定这一点外。范例中TfrReport对象新增的两个事件句柄使动态改变列宽成为可能。
列的宽度由TfrReport对象的OnPrintColumn事件句柄所使用的数据来指定。在这个范例中,一个带文本框的列的宽度是由字段的大小或类型和字母W的宽度来确定的。比如日期和时间型字段,列的宽度是15个字母W的大小。其他类型的列,列宽是64个像数。
OnPrintColumn事件的完整原代码如下:
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事件句柄内,设置列的宽度为上面这个事件中所指定的大小。
procedure TForm1.frReport1EnterRect(Memo: TStringList;
View: TfrView);
begin
View.dx := FWidth;
end;

TfrPrintTable和 TfrPrintGrid 组件在打印列时的工作原理和这个范例是类似的。

 
谢谢:)
 
好样的。
 
京工之鸟 百岁
 
呵呵,其实我昨天就说了,他原先就帖在www.pcjingning.com上,后续帖子也会帖出。
 
唉,可惜我E文太差,DELPHI初学,要不一定帮忙。
 
提了一下
 
好人哪,感谢你。
 
提前一下,试试看
 
先谢了!
我提议你老兄可以发起搞一个公益活动,发动大家一起参与<FastReport V2.4 开发人员指南>的翻译工作
具体操作可参照:
http://www.delphibbs.com/delphibbs/dispq.asp?LID=844029
 
不错
哥们!
 

Similar threads

回复
0
查看
863
不得闲
回复
0
查看
1K
不得闲
回复
0
查看
978
不得闲
D
回复
0
查看
930
DelphiTeacher的专栏
D
D
回复
0
查看
871
DelphiTeacher的专栏
D
后退
顶部