FastReport 使用笔记
FastReport 使用笔记
1.在脚本中使用变量
在Script脚本方法中中定义变量和Delphi 一样,不做说明,这里主要说一下在报表中定义的变量如何在脚本中读写:
(1) 定义变量类型 vars
在 vars
类别下增加变量 v1
- 在Memo1 上使用 memo1.text:=[v1]
- 在Script 中读取 get('v1') 或者
- 在Script 中写,只能用 set('v1',10)
示例
在Delphi程序中访问报表对象
-
最基本的方法就是
frxReport1.FindObject
。然后把返回的对象强制转换成它的类型,当然,在报表中必须真的有这么个东东。如改变一个Tfrxmemoview
的内容,可以这样写TfrxMemoView(frxReport1.FindObject('memo1')).Text:='jade'
; -
还可以用
TfrxReportPage
的FindBand
方法,这个方法的参数是Band
类,如报表抬头就可以直接使用这个方法,因为抬头一个页中只有一个,如果有多个同样的类。则不能使用这种方法。如果要使用TfrxreportPage,一般可以用这样的代码
TfrxReportPage(frxReport1.Pages[0])。当然,如果你的这个页是对话框型的,则不行了,但一般都是报表型的。
使用上下标
在Fastreport中使用上下标是很简单的,只要用一个TfrxMemoView
,把AllowHTMLTags
属性设为真,就可以使用网页标签来实现上下标了,如12<sup>2</sup>与24<sub>3</sub>
。就分别是2为上标,3为下标。
打印页码
打印页码是很简单的,只要加入一些常量即可,如打印第几页共几页就可以使用
第[Page#]页 共[TotalPages#]页
这里要注意的一点是如果想正确显示总页数,必须选中二次报表
动态建立变量及变量组
注意:报表中不能声明同样的变量
- 建立变量组名
frxreport1.Variables.Add.Name:=' '+变量组名
; - 建立变量名
frxreport1.Variables.AddVariable('组名,如果为不存的组或空,则为默认组,这里不需要空格',变量名,变量初始值)
;
例如,要建立变量组Yuan,二个变量Yuan1,Yuan2,则为
frxreport1.Variables.Add.Name:=' Yuan';注意前面是空格
frxreport1.Variables.AddVariable('Yuan',Yuan1,初始值)
frxreport1.Variables.AddVariable('Yuan',Yuan2,初始值)
共用TFrxreport及TfrxDBDataSet
一个程序中,不管多么大的程序,只要打印或预览时是模式的,则完全可以共用一个TFrxreport变量及几个TfrxDBDataSet。只不过,要注意完成一个报表程序的步骤,主要是下面几步
- 清除报表,得到一个全新的报表内容。
Frxreport1.clear。 - 设置要使用的TfrxDBDataSet的别名,如果不需要可以省略这一步,但一般最好不同的报表用不同的别名。
注意这一步要在加载报表文件之前,因为一般设计报表文件时已经包含了别名信息。
frxDBDataSet1.UserName:=别名
; - 加载报表或动态建立一个TfrxReportPage。
Frxreport1.LoadFromFile
(报表文件的完整文件名); - 关联TfrxDBDataSet与TDataset,并设置要使用哪些TfrxDBDataSet。
Frxreport1.DataSets.Clear;//先清除原来的数据集
frxDBDataSet1.DataSet:=dataset1;//关联Fastreport的组件与TDataset数据集。
Frxreport1.DataSets.Add(frxDBDataSet1); 加载关联好的TfrxDBDataSet到报表中。
经过这几步后,就可以像单独使用一个Tfrxreport一样使用共用的报表组件了。
加入自定义函数
Fastreport
可以自己加入需要的函数,来实现特定的功能。过程就是:
- 添加函数到报表中。
frxreport1.AddFunction('完整的函数声明');
如有一个自定义函数,为GetName(Old:String):String;这个函数通过数据集的一个字段,得到另一个返回值。
则语句为:frxreport1.AddFunction('Function GetName(Old:String):String;'); - 脚本中使用函数。
在脚本中或报表中使用自定义函数,就像使用其它Fastreport内置函数一样。 - 程序中处理函数。
使用函数是通过frxreport1的OnUserFunction函数来实现的。
OnUserFunction
的声明如下:Function(const MethodName: String;var Params: Variant): Variant;
比如上面的函数,首先要有一个函数,这个函数是GetName
的实现部分。如有一个在程序中实现的函数。
function RealGetName(Old:String):String;这个函数名是无所谓的,也可以是GetName。
在OnUserFunction的事件处理中有如下代码即可完成自定义函数在报表中的使用。
if CompareText(MethodName,'GetName')=0 then Result:=RealGetName(VarToStr(Params[0]));
-
我一般都是使用CompareText来比较函数名,因为我发现二个版本的Fastreport,一个是MethodName全部自动变成了小写,一个是全部自动变成了大写,所以干脆用CompareText来比较,肯定不会出错。
-
如果有多个参数,则依次传递Params[0],Params[1]即可,要保持顺序一致。
这里要注意一点,如果参数为指针,则不能直接使用Pointer(Integer(Params[0]))。因为实际传递过来的是指针的整数值,可以使用Pointer(StrToInt(VarToStr(Params[0])))。
使用脚本,脚本中使用变量
很多时候,我们希望把对报表的控制放到报表的脚本中,通常我这样做有二个原因:
- 能够根据字段内容的变化而使用不同的设置,因为如果想在程序中实现这样功能,就不得不用自定义函数,函数的实现要放到程序中,函数可能需要传递很多参数,效率低下。
- 把不同报表的控制放到脚本中,可以实现报表的模块化,程序只是简单的设置数据集的关系,并加载硬盘上的报表文件,不同报表的不同实现方式,显示方式,均放到报表文件中,程序简洁,易维护,易升级。
当然,这样的缺点就是程序中加载报表时的数据集别名必须与设计报表时的别名一致。
脚本的使用与通常程序的使用并没有太多的区别,就是像正常的程序那样引用控件的名称即可。
但注意对变量的使用,需要把变量名或表达式用<var1>
括起来。
在脚本中根据字段名改变Tfrxmemoview
的内容
- 假设有数据表“用户”,字段ID为用户标识,Name为用户名,打印时要求,如果用户名为空,则打印“无用户名”,否则打印出“用户名:实际的用户”,则可以在ID的Tfrxmemoview控件的OnAfterData事件中写如下脚本。
if <frxDBDataSet1."Name">='' then
Memo2.Text:='无用户名'
else
Memo2.Text:='用户名:[frxDBDataSet1."Name"]'
Memo2
是放置用户名称数据的Tfrxmemoview
控件。
这里注意,要在脚本中访问变量需要把变量用<>
包括起来
procedure Page1OnBeforePrint(Sender: TfrxComponent);
begin
if (<salary> >=30000) and (<salary> <40000) then
begin
sal_level.text:='中薪级别';
sal_level.font.color:=clBlue;
end
else if(<salary> >=40000) then
begin
sal_level.text:='高薪级别';
sal_level.font.color:=clRed;
end
else
begin
sal_level.text:='普薪级别';
sal_level.font.color:=clGreen;
end;
end;
实现连续打印
- 很多人认为Fr不能实现连续打印,以为只能通过自己写函数调用打印函数来实现连续打印,实际上,Fr可以轻易的实现连续打印,同时,实现时又是非常简单,你甚至可以在你的程序的打印设置中简单的让客户选择是否连续打印,其它都可以保持不变。
function PelsTomm(Pels:Extended):Extended;
begin
Result:=Pels/Screen.PixelsPerInch*25.4;
end;
procedure PrintSerial(Frx:TFrxReport;SequencePage:Byte=0);
var
P:TfrxReportPage;
R,R1:Extended;
begin
{必须是二遍报表,否则无法计算总页数。
下面的方法只适用于没有页脚的情况,因为如果有页脚的话
FreeSpace就始终为0了。可以用报表脚来代替。
因为是连续打印,也可以看作只有一页,报表脚也就相当于页脚了}
if not Frx.Engine.DoublePass then Exit;
//SequencePage指要连续打印的页面,普通报表就是0
P:=TfrxReportPage(Frx.Pages[SequencePage]);
R1:=P.TopMargin+P.BottomMargin;
while Frx.PrepareReport do
begin
if (Frx.Engine.TotalPages<=1) then Break;
R:=Pelstomm(Frx.Engine.TotalPages*Frx.Engine.PageHeight-
Frx.Engine.FreeSpace)+R1;
P:=TfrxReportPage(Frx.Pages[SequencePage]);
P.PaperHeight:=R;
end;
{必须用上面的循环代码来得到准确的空白区域
不能用通过计算总页数减去各页的页边距的方法来获得空白区域
因为如果碰到一条记录过宽的情况导致换页,就不准确了。}
R:=Pelstomm(Frx.Engine.TotalPages*Frx.Engine.PageHeight-
Frx.Engine.FreeSpace)+R1;
P:=TfrxReportPage(Frx.Pages[SequencePage]);
P.PaperHeight:=R;
end;
// 在预览或打印前先调用PrintSerial即可。
- 问题描述,正如rainee所说:程序设计时Memo中的中文显示正常,预览也正常。程序运行时Memo中的中文只能显示前几个汉字,有时甚至不能显示。再次打开程序源码,会发现Memo中的中文没保存下来或保存不完全。如果用Memo显示字段或变量的值,其中的中文显示正常。
除 了文章提到的方法外,FastReport4.7.91的TfrxReport有StoreInDFM属性,将其设为false, 在运行时动态加载报表文件,语句如下frxrprtPrintCheck.LoadFromFile('a.fr3');然后预览打印都没有问题。
在FastReport中添加变量,设置Memo的内容为变量的值,在报表的GetValue事件中给变量赋值。如果你的报表中有许多Memo的值相同,用这种方法最方便。
procedure TForm1.frxReport1GetValue(VarName: String; var Value: Variant); //该方法在报表渲染时会回调该方法,对每一个变量进行遍历回调
begin
if CompareText(VarName, 'MyVar1') = 0 then
Value := 'Hello.';
end;
设计时Memo内容为空,在Show报表前给Memo控件赋值。
procedure SetMemoData(aReport: TfrxReport; aMemoName, aString: string);
var
mv: TfrxMemoView;
begin
mv := aReport.FindObject(aMemoName) as TfrxMemoView;
if mv<>nil then
mv.Text := aString;
end;
frxDesigner 元件是报表设计器,当使用此元件,你的工程文件就可以使用报表设计器,此元件它只包含一些报表设计器的设定,当加入”frxDesign” 单元到uses 清单中,就表明与报表设计器连接上了。
- frxDesigner 元件包含下列的属性:
property CloseQuery: Boolean default True; //定义结束设计报表是否询问储存报表之用。
property OpenDir: String; // 打开报表的预置数据目录
property SaveDir: String; //储存报表的预置数据目录。
property Restrictions: TfrxDesignerRestrictions; //报表设计环境下,限制不同的报表操作标识(flag),此标识包含单一或混合数据值:
drDontInsertObject //禁止插入物件
drDontDeletePage //禁止刪除页面
drDontCreatePage //禁止建立新的页面
drDontChangePageOptions //禁止修改页面属性
drDontCreateReport //禁止建立新报表
drDontLoadReport //禁止载入报表
drDontSaveReport //禁止储存报表
drDontPreviewReport //禁止预览报表
drDontEditVariables //禁止编辑变量
drDontChangeReportOptions //禁止修改报表属性
property OnLoadReport: TfrxLoadReportEvent;
TfrxLoadReportEvent = function(Report: TfrxReport): Boolean of object; //此事件发生在储存报表之时。利用此事件,你可以将报表储存于数据库中。
property OnShow: TNotifyEvent;//此事件发生在启动报表设计环境时。
TfrxPreview //此元件专供建立自定义报表合预览窗口使用。
procedure AddPage; //加入空白页面到报表末端。
procedure DeletePage; //删除当前页。
procedure Print; //打印报表。
procedure LoadFromFile; //显示文件载入窗口。
procedure LoadFromFile(FileName: String); //载入指定的文件。
procedure SaveToFile; //显示文件储存窗口。
procedure SaveToFile(FileName: String); //储存文件到指定的文件名称
procedure Edit; //载入当前页至设计模式供编辑使用。
procedure Export(Filter: TfrxCustomExportFilter); //使用指定的导出过滤器导出报表。
procedure First; //第一页。
procedure Next; //下一页。
procedure Prior; //上一页
procedure Last; //最后一页。
procedure PageSetupDlg; //显示页面设定窗口。
procedure Find; //显示文字搜寻窗口。
procedure FindNext; //继续找下一个。
procedure Cancel; //取消创建报表。
procedure Clear; //清除报表。
* 你可以使用下列属性:
property PageCount: Integer readonly;//报表页数。
property PageNo: Integer;//目前报表页码(起始值为1)。要移至其它页面,指定此属性的值即可。
property Tool: TfrxPreviewTool;//选取工具。
property Zoom: Extended;//显示比例,“1” 代表100% 。
property ZoomMode: TfrxZoomMode;//显示模式,可以的显示模式如下:zmDefault 预置值,显示比例根据“Zoom” 属性而定zmWholePage 整页模式zmPageWidth 与页面宽度相同 zmManyPages 屏显示多页
property OutlineVisible: Boolean;//是否显示报表大纲(树状结构)。
property OnPageChanged: TfrxPageChangedEvent;//目前页面要改变时,此事件将被触发。
TfrxBarcodeObject TfrxOLEObject TfrxChartObjectTfrxRichObject //注意:如果报表中使用BarCode 条码控件,需要在程序引用单元`frxBarcode`或者增加`frxbarCodeObject`
TfrxCrossObject
TfrxCheckBoxObject
TfrxGradientObject
// 可在报表内部使用的物件,这些元件自己没做任何事情,它们会自动将元件的单元加入uses 清单,加入你打算打开一份报表,此功能会自动被加入报表,未包括此物件至工程文件的话,打开报表时将会发生错误。
载入指定的报表,假如第二个参数的值等于”True ” 且指定的文件不存在,然后它会产生一个例外。假如文件载入成功,它返回“True”。
procedure LoadFromStream(Stream: TStream); //从数据流(stream)载入报表。
procedure SaveToFile(const FileName: String); //储存报表至指定的文件名。
procedure SaveToStream(Stream: TStream); //储存报表至数据流(stream) 。
- 报表预置的后缀名称为“FR3”。范例:
frxReport1.LoadFromFile('c:\1.fr3');
frxReport1.SaveToFile('c:\2.fr3');
Designing a report 设计报表
- 通过
TfrxReport.DesignReport
方法调用报表设计器reportdesigner
,要具有设计报表的功能,你必须在工程文件中加入“TfrxDesigner”元件,或在uses 加入“frxDesgn.pas”单元。
范例:
frxReport1.DesignReport;
Running a report 执行报表
- 应用下列两个
TfrxReport
元件的方法启动报表:
procedure ShowReport(ClearLastReport: Boolean = True);
- 启动报表并显示结果在浏览窗口。假如
ClearLastReport
参数等于False
,然后报表将会清前一份报表的末端,否则前一份报表的内容将会被清除。
function PrepareReport(ClearLastReport: Boolean = True):Boolean;
- 启动报表,但不开启预览窗口,参数用法同
ShowReport
方法,假如报表建立成功,它返回True
。在大部分的情況下,采用第一种方法比较方便,当报表建立的过程中,它会立刻显示预览窗口。当我们要把报表加入上一份报表的后面时,ClearLastReport
参
数是非常方便的技巧在批次报表打印时特别有效)。
范例:
frxReport1.ShowReport;
Previewing a report 预览报表
*在报表预览窗口显示报表有两种方式:不管是调用TfrxReport.ShowReport
方法(前面已提及)或使用TfrxReport.ShowPreparedReport
方法。在第二种状况,报表创建的过程不会执行,但是报表的结果会显示于屏幕。这个意思是说,你应该使用PrepareReport
方法创建报表或载入先前已经建立的报表。
范例:
if frxReport1.PrepareReport then
frxReport1.ShowPreparedReport;
在这个案例中,报表创建完成在先,然后显示报表于浏览窗口。创建大型的报表可能耗费许多时间,那也是为什么使用ShowReport
方法会比PrepareReport/ShowPreparedReport
来的好的原因,我们指定“TfrxReport.PreviewOptions” 属性,指定预览的参数。
Printing a report 打印报表
- 在大部份的情況,你会从预览窗口打印报表。要手动打印报表,你应该使用
TfrxReport.Print
方法,
例如:
frxReport1.Print;
在此同时,你可以设定打印对话窗口的参数。你可以从TfrxReport.PrintOptions
属性指定打印的预置值及取消显示打印窗口。
Loading and saving a finished report 存取已完成的报表
- 它可以从预览窗口执行,这也可以手动的用“TfrxReport.PreviewPages”方法执行:
function LoadFromFile(const FileName: String;
ExceptionIfNotFound: Boolean = False): Boolean;
procedure SaveToFile(const FileName: String);
procedure LoadFromStream(Stream: TStream);
procedure SaveToStream(Stream: TStream);指定参数与TfrxReport 对应的方法类似,报表文件后缀名必须是”FP3” 。例:
frxReport1.PreviewPages.LoadFromFile('c:1.fp3');
frxReport1.ShowPreparedReport;//注:当已完成报表载入后,预览报表必须通过 “ShowPreparedReport”方法来执行。
Exporting a report 导出报表
它可从预览窗口执行,此项功能也可以用TfrxReport.Export
方法来执行,在此方法的参数中,你必须指定要使用的导出过滤元件:如:frxReport1.Export(frxHTMLExport1)
;导出过滤元件必须是可用的(你必须将它放入工程文件的表单上)且设定正确。
creating a custom preview window 建立自定义预览窗口
FastReport
显示报表于标准的预览窗口。假如为了某种理由它无法满足你,你可以使用自定义的预览窗口。为此,FastReport
的TfrxPreview
元件于是诞生了,要显示报表这个元件必须连接到TfrxReport.Preview
属性。
Building a composite report (batch printing) 建立复合报表(批量打引)
在某些情况下,我们必须一次打印数份报表,或封装及实现多份报表于同一个预览窗口。要执行这项工作,在FastReport 中有多个工具,允许建立一份新的报表,置于另一份已存在的报表末端,TfrxReport.PrepareReport
方法有此ClearLastReport
, True
,此参数定义是否清除前一份已建立的报表。下列的程序码示范如何从两个报表定义文件,批次建立一份报表:
frxReport1.LoadFromFile('1.fr3');
frxReport1.PrepareReport;
frxReport1.LoadFromFile('2.fr3');
frxReport1.PrepareReport(False);
frxReport1.ShowPreparedReport;
我们载入第一个报表并在后台处理报表(不显示),然后我们载入第二份报表到同一TfrxReport
物件,并置参数 ClearLastReport
的值为假(False)建立报表。此功能允许第二份报表的结果接在第一份报表的后面。最后,我们将两份报表显示在同一个预览窗口中。
Numbering of pages in a composite report 复合报表中的页数
你可以使用 Page
, Page#
, TotalPages
及 TotalPages#
系统变量显示页码或总页数。在复合式报表,这些变量代表的意义如下:
Page //目前报表的页码
Page# //批次报表的页码
TotalPages //目前报表的总页数(报表必须设定为two-pass)
TotalPages# //批次报表的总页数
Combination of pages in a composite report 复合报表的合并页
如上所述,当打印时,报表设计的属性 PrintOnPreviousPage
可以利用前一页的可用空间打印下一页的内容。在复合报表中,它允许你在前一份报表最后一页的可用空间上建立一份新的报表,要执行此功能,必须在每一份连续报表的第一个设计页面启动属性PrintOnPreviousPage
。
Interactive reports 交互式报表
- 在交互式报表中,我们可以在预览窗口定义任何报表物件对鼠标按下的反应。例如,使用者选择数据列,然后做一份新的报表,显示选取列的明细数据。任何报表都可以成为交互式报表,要执行此操作,你只需建立
TfrxReport.OnClickObject
事件处理程序。下面是此事件处理的范例:
procedure TForm1.frxReport1ClickObject(Page: TfrxPage;View: TfrxView; Button: TMouseButton; Shift:TShiftState;var Modified: Boolean);
begin
if View.Name = 'Memo1' then
ShowMessage('Memo1 contents:' + #13#10 +TfrxMemoView(View).Text);
if View.Name = 'Memo2' then
begin
TfrxMemoView(View).Text := InputBox('Edit', 'EditMemo2 text:', TfrxMemoView(View).Text);
Modified := True;
end;
end;
在 ?OnClickObject? 事件处理程序中,你可以执行下列工作:-修改物件或页面的內容,但前提是?Modified?属性必须被指定。-调用 ?TfrxReport.PrepareReport? 方法重新建立报表。在此范例中,点选 ?Memo1? 物件将显示此物件的內容,当点选?Memo2,?将显示Dialog 窗口,物件的内容可于此窗口内被修改。设定?Modified? 标识为?True? 允許保留及显示修改后的內容。同样的方法,它也可被定义为一个单击,有不同的反映。例如,执行一个新的报表。下列的注释是必要的。在中,在一个预览窗口仅显示一个报告,由一个元件组成(不像FastReport 2.x 版)。这就是运行一个报告,其它 TfrxReport 物件,必须删除的原因。
- 要给使用者按下物件一个提示,我们可以在鼠标指针移至物件上方时变更鼠标指针显示。要达到此目的,请在报表设计环境下,选取想要的物件,并设定不同于预置的Cursor 属性即可。可单击(clickable)物件有许多详细的定义规则。在简单的报表中,可以随意定义目录
(contents)
中物件的名称。可是,在复杂报表的报表中却不行。例如,创建逐条的报表在有序的数据中。一个用户单击目录为“12”的Memo1
物件。在该物件上数据将怎样排序?这就是你该明确知道主键值排列顺序的原因。FastReport
可分配一个包含任何数据(我们的例子中是主键值的数据)的字符串到任何报表的物件。此字符串储存在TagStr
属性中。让我们以FastReport 的范例FastReportDemo.exe
内的【Simple list】)来说明,这是一家公司的客户明细,打印的內容包括【client’s name】,【address】 【contact person】 等字段,数据来源是DBDEMOS 演示数据库的Customer.db
数据表,该数据表有一个主键值【CustNo】字段,它并未输出在报表。我们的工作是决定点下的物件是哪一笔记录,然后取得该记录的主键值。要执行该工作,必须在Master Data 区域所有物件的TagStr
属性在报表建立期间,TagStr
属性的內容会以相同的方法被重新计算,当字符物件的內容被计算,所有用到此变量的值将会被取代。假如主鍵值Primary Key
是复合字段(它包含多个字段),TagStr
属性的內容可以是下列的写法:[Table1."Field1"];[Table1."Field2"]
fastreport2.5
*报表模板扩展为frf
1.Band
Page Header //显示在报表每页的上面 (页眉)
Page Footer //显示在报表每页的下面 (页脚)
Report Title //显示在第一页报表的上面,但在Page Header的下面。
Report Summary //显示在报表的最后一页的空白处。
-
字段:
[frxDbDataSet1."Contact_Person"] -
字段计算
[<frxDBDataSet."Length_In">*2.54]
在此方括号和尖括号都用了,但记住方括号被默认的作为公式的边界,它包含在了组件的文本中。 -
变量
我们可以调用任何报表变量列表中的变量,变量名称用<变量>符号
如:
if <frxDBCustomerOrders."ItemsTotal">>5000 then
begin
Memo6.Color:=clRed;
end;
如果是脚本中定义的变量,则和Delphi中使用一样
调用数据表字段:像访问变量一样,我们使用<> 来访问数据表字段
if (<Table."Field1">)=1 then
begin
end;
脚本中调用汇总函数
- 汇总函数的一个特性就是如果需要在脚本中调用需要和"Text"组件配合。如果脚本单独进行调用,
运行报表时会产生错误信息。这是因为这些汇总函数总是依赖于band 进行运行的。
变量值可以显示在"Text"组件中,例如输入[Myvarible],变量名称应该是唯一的,意思是在
报表中不能和其他组件常量、函数名称、过程名称等相一致,如果那样,在报表中就会产生
一个错误。
在报表的开始,report组件的OnStartReport事件被调用,页面打印预览之前,页面的BeforePrint事件被调用,这个时间在报表每个页面生成之间都调用一次。
- DataBand生成时间调用顺序:
1.OnBeforePrint 事件被调用
2.Band组件上的���他组件的OnBeforePrint事件被调用
3.添加组件内容,然后调用组件的OnAfterPrint事件
4.计算Band的位置,高度,进行拉伸
5.调用band的OnAfterCaluHeight事件
6.如果页面没有足够的空间,生成一个新的页面
7.所有的Band和组件显示在报表中
8.所有band上组件的OnAfterPrint事件被调用
9.Band本身的OnAfterPrint事件被调用
当连接到Band的数据源进行连接后,Band被打印显示。然后报表生成结束,调用报表页的OnAfterPrint事件,在调用Report组件
的OnStopReport事件。
在组头打印组的汇总信息
-
这是脚本十分有用的方法,因为一般情况下,汇总信息是在报表全部信息处理完毕后进行的。要在组的开头显示汇总和的信息,
以下运算方法可以使用:
选中报表选项中的double pass选项
第一个过程就是将每个组的计算结果保存到数组中
第二个过程就是将计算的结果显示在每个组的开头 -
除了报表中的组件以外,还有一些组件在脚本中可以使用,如下:
Report Report组件
Engine 报表之间的联接
OutLine 报表中和ReportTree的联接 -
代码说明:
path:=ExtractFilePath(ParamStr(0))+'rt1.frf';
frReport1.Clear;
frReport1.LoadFromFile(path); //加载报表模板
frReport1.Title:='测试报表'; //设置报表文件的名称
frReport1.PrepareReport();
frReport1.ShowReport; //打印预览
frReport1.PrintPreparedReportDlg; //直接打印,不预览 ShowPrintDialog 是否显示打印份数和打印机选择,true 预览 false 不预览
- 设置Bands和组件的Strech属性为Enable 可使组件自动伸缩。
Text组件自动调节其高度和宽度,以有足够的空间显示其内容。可以通过“AutoWidth”“AutoHeight”和"StrechMode"属性来实现。这个组件
在文本中只有一行并且不会影响右边组建的显示情况下非常有用。"Strech"属性能让组件自动调整高度,而不改变宽度的情况下,以显示容纳
- 全部文本,这个属性:
SmDontStrech //不进行拉伸操作,默认
SmActualHeight //自动调整每一行的高度适应全部文字
SmMaxHeight //自动调整高度适应Band的最大高度
-
当设置Text 的StrechMode=smActualHeight 同时需要设置Band的Strech属性为Enable 配合使用。
-
在数据Band上通过右键菜单设置 “AllowSplit”(允许拆分) 属性,来减少页之间的空白。
-
通过 页面设置-其他选项-栏数 来控制一页分几栏显示
分组-集合体
-
GroupBand
-
Group Header
-
ReprintOnNewPage 属性为true,fastReport 允许在打印新的页面时重新打新租的内容
还有另外一个办法避免分组拆开,就是设置Group Header 的Keep together属性,这样
报表当发现没有足够的空间显示组内容时,添加新的一页开始显示。 -
ResetPageNumber 允许打印一个分组报表时从新设置页码属性。同时还要设置StartNewPage,
这样每个组从新的页面开始,页码独立计算。打印页码和总页数可以使用系统变量[Page]
[TotalPages] -
Group header有一个叫drilldown的属性,如果drilldown属性设为 true,则在报表时变为交互式报表,
意思是在预览窗口用户可用通过鼠标在组的标题上单击,以实现展开和关闭详细信息内容。
[line]每个分组详情的行号,如果让第二个Band的页码成顺序号延续,可以再band中将[line]改为
[line#]
*函数集
sum() //返回公式的和
max //返回给定参数的最大值
min //返回公式的最小值
avg //返回公式的平均值
count //返回数据行数
除count函数外的其他函数的语法如下
sum(公式,band,标记)
sum(公式,band)
sum(公式)
- 公式:要显示数据的公式
band:数据Band的名称 - 标记:一个字节,可以是以下数据之一或他们的和
1.计算式包含不可见band
2.对计算值进行累计
公式是必须的参数,其他是可选的,不过,有歧义时,应该 使用band这个参数
count函数的语法
count(band,标记)
count(band)
对所有的函数有一个规定,就是只适用于数据band或数据band的footer band
[sum(<frxDBCustomerOrders."ItemsTotal">,MasterData1)]
[sum(<frxDBCustomerOrders."ItemsTotal">,MasterData1,1)]
- 如果我们设置数据band的visible属性为false,在打印时是不可见,为了计算这些不可见的数据行,需要添加上这个参数
- 如果设置标志参数为2,显示以后结果不在重新设置。每个显示结果为运行期的总和,3是1和2 的和,意思是计算不可见
的数据,并对计算结果不进行重新复位。
*格式化
[sum(<frxDBCustomerOrders."ItemsTotal">,MasterData1)#n%2,2m]
- 格式化语法;
[公式 #格式化符号]
#n 格式化符号:对数字文件进行格式化
#d 格式化符号:对日期进行格式化
#b false,true:对布尔结果进行格式化
格式化类型对数字类型的可以参考delphi 中的Format函数,对日期型可以参考Delphi
FormatdateTime。一下是Format中设计的格式:
数字格式:
%g
%2.2f
%2.2n
%2.2m
日期格式
dd.mm.yyyy
dd mm yyyy
- 数字格式化字符串中间可以加入“,”或“-”。这些符号可以用在整数和小数之间的分隔符号
#b
格式化是布尔
型,这个用在用逗号分开的两种结果的格式化,第一个是“否”,第二个
是“是”
根据行号设置组件显示颜色,添加text 设置为DataBand 的宽度,在其条件窗口中输入
<line>
mod 2=1
其他 颜色设置为想要的颜色即可。
嵌套报表(子报表)
脚本
- 关键词:case try catch except with
- 数据类型:integral fractional logical character line multidimensional arrays set variant
访问普通变量和Delphi一样
fastreport4 以上版本
- 代码说明:
path:=ExtractFilePath(ParamStr(0))+'rt2.fr3';
frxReport1.Clear;
frxReport1.LoadFromFile(path);
frxReport1.PrepareReport(true);
frxReport1.PrintOptions.ShowDialog:=False; {不显示打印机设置窗口}
// frxReport1.ShowPreparedReport; {打印预览}
frxReport1.Print; {直接打印}
比较:
- 区别:
1.报表模板格式不同,fastreport4
以前版本扩展名是.frf
,fastreport4
及以后版本报表模板扩展名是fr3
2.打印预览弹窗不同,fastreport4
以前版本调用的是ShowReport
方法来显示预览界面,而fastreport4
及
以后版本是通过调用ShowPreparedReport
来显示打印预览窗口
3.打印设置对话框属性不同,fastreport4以前版本是通过ShowPrintDialog属性来控制是否显示打印机设
置窗口,而fastreport4
以后版本是通过调用printOptions.ShowDialog
属性来控制的。
4.打印方法不同,老版本是通过调用PrintPrepareReportDlg
来打印,新版本是通过Print
方法来打印
5.打印报告文件名设置不同,老版本通过frReport.Title
来设置打印输出文档的名称,而新版本暂未找到
类似方法。