FastReport 使用技巧篇

FastReport 使用技巧篇

使用技巧篇

1.FastReport中如果访问报表中的对象?

可以使用FindObject方法。

TfrxMemoView(frxReport1.FindObject(‘memo1‘)).Text:=‘FastReport‘;

2.FastReport中如何使用上下标?

设置frxmemoview.AllowHTMLTags:= True;在Text输入如下

上标:mm<sup>2</sup>

下表:k<sub>6</sub>

举一反三,你还可以使用其他HTML标记。

3.FastReport中如何打印总页数?

设置两次报表后加入引号内内容 "第[Page#]页共[TotalPages#]页"

4.FastReport中如何动态加入变量及变量组?

建立变量组名

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,初始值)

5.FastReport中如何加入自定义函数?

Fastreport可以自己加入需要的函数,来实现特定的功能。过程就是:

1)添加函数到报表中。

frxreport1.AddFunction(‘完整的函数声明‘);

如有一个自定义函数,为GetName(Old:String):String;这个函数通过数据集的一个字段,得到另一个返回值。

则语句为:frxreport1.AddFunction(‘Function GetName(Old:String):String;‘);

2)脚本中使用函数。

在脚本中或报表中使用自定义函数,就像使用其它Fastreport内置函数一样。

3)程序中处理函数。

使用函数是通过frxreport1的OnUserFunction函数来实现的。

OnUserFunction的声明如下:Function(constMethodName: String;var Params: Variant): Variant;

比如上面的函数,首先要有一个函数,这个函数是GetName的实现部分。如有一个在程序中实现的函数。

function RealGetName(Old:String):String;这个函数名是无所谓的,也可以是GetName。

在OnUserFunction的事件处理中有如下代码即可完成自定义函数在报表中的使用。

if CompareText(MethodName,‘GetName‘)=0 thenResult:=RealGetName(VarToStr(Params[0]));

我一般都是使用CompareText来比较函数名,因为我发现二个版本的Fastreport,一个是

MethodName全部自动变成了小写,一个是全部自动变成了大写,所以干脆用CompareText来比较,

肯定不会出错。

如果有多个参数,则依次传递Params[0],Params[1]即可,要保持顺序一致。

这里要注意一点,如果参数为指针,则不能直接使用Pointer(Integer(Params[0]))。因为实际传

递过来的是指针的整数值,可以使用Pointer(StrToInt(VarToStr(Params[0])))。

6.FastReport中如何共用TFrxreport及TfrxDBDataSet?

一个程序中,不管多么大的程序,只要打印或预览时是模式的,则完全可以共用一个TFrxreport

变量及几个TfrxDBDataSet。只不过,要注意完成一个报表程序的步骤,主要是下面几步

1)清除报表,得到一个全新的报表内容。

Frxreport1.clear。

2)设置要使用的TfrxDBDataSet的别名,如果不需要可以省略这一步,但一般最好不同的报表用不

同的别名。

注意这一步要在加载报表文件之前,因为一般设计报表文件时已经包含了别名信息。

frxDBDataSet1.UserName:=别名;

3)加载报表或动态建立一个TfrxReportPage。

Frxreport1.LoadFromFile(报表文件的完整文件名);

4)关联TfrxDBDataSet与TDataset,并设置要使用哪些TfrxDBDataSet。

Frxreport1.DataSets.Clear;//先清除原来的数据集

frxDBDataSet1.DataSet:=dataset1;//关联Fastreport的组件与TDataset数据集。

Frxreport1.DataSets.Add(frxDBDataSet1);//加载关联好的TfrxDBDataSet到报表中。

经过这几步后,就可以像单独使用一个Tfrxreport一样使用共用的报表组件

7.FastReport中如何使用脚本,脚本中使用变量?

很多时候,我们希望把对报表的控制放到报表的脚本中,通常我这样做有二个原因:

1)能够根据字段内容的变化而使用不同的设置,因为如果想在程序中实现这样功能,就不得不用

自定义函数,函数的实现要放到程序中,函数可能需要传递很多参数,效率低下。

2)把不同报表的控制放到脚本中,可以实现报表的模块化,程序只是简单的设置数据集的关系,

并加载硬盘上的报表文件,不同报表的不同实现方式,显示方式,均放到报表文件中,程序简洁

,易维护,易升级。

当然,这样的缺点就是程序中加载报表时的数据集别名必须与设计报表时的别名一致。

脚本的使用与通常程序的使用并没有太多的区别,就是像正常的程序那样引用控件的名称即可。

但注意对变量的使用,需要把变量名或表达式用<>括起来。

实现打印分组的页数。基本的原理就是:

1)必须使用二遍报表,因为FS算总页数就是需要二遍报表的。

2)在第一遍报表中,在GroupBand打印前,动态的建立整数型数组变量,用以保存上一个分组的

总页数。

3)在最后一遍报表时,需要显示分组页数的Tfrxmemoview取得数组中的数据,但最后一个分组

不会有总数,可以通过总页数减去GroupBand事件中保存的页数来取得。

4)代码中处理了一页多组,及一组多页打印分组头的情况。可以看到这些特殊处理的代码说明

5)我特意在分组尾及页脚都用了Tfrxmemoview来显示这些数据,说明在不同情况下的显示。

8.FastReport中如何在脚本中根据字段名改变Tfrxmemoview的内容?

假设有数据表“用户”,字段ID为用户标识,Name为用户名,打印时要求,如果用户名为空,则

打印“无用户名”,否则打印出“用户名:实际的用户”,则可以在ID的Tfrxmemoview控件的

OnAfterData事件中写如下脚本

if<frxDBDataSet1."Name">=‘‘ then

Memo2.Text:=‘无用户名‘

else

Memo2.Text:=‘用户名:[frxDBDataSet1."Name"]‘

Memo2是放置用户名称数据的Tfrxmemoview控件。

这里注意,要在脚本中访问变量需要把变量用<>包括起来。

9.FastReport中如何动态调整高度?

我经常使用下面的几个函数来实现Band及Tfrxmemoview高度的动态调整,需要注意的是:下面的

函数只能调整一个Band中多行的最后一行,如果只有一行(多数情况下应该是这样)就无所谓了

,而且这是在宽度已经固定的前提下。在想要调整高度的Band的OnBeforePrint事件中写

SetMemo(Sender);,代码如下,粘贴到代码页中就可以使用。

下面的代码也可以演变一些,实现动态宽度等。我多处都判断了Tag是否为7635,因为我经常需要

单独调用其中的某个函数。

//7635为保留数字,表示不作任何调整,通常用在多行的最上方

function Biger(Old:Extended):Integer;

begin

Result:=Trunc(Old);

if Frac(Old)>0 then

Result:=Result+1;

end;

procedure JustHeight(Sender:TfrxComponent);

var

RealHeight:Integer;

begin

RealHeight:=Biger(TFrxMemoView(Sender).CalcHeight+TFrxMemoView(Sender).Top);

ifBiger(TfrxBand(Sender.Parent).Height)<RealHeight then

begin

//若MEMO的高度小于BAND但计算高度大于BAND,则在调整BAND的函数中就会被调整

TfrxBand(Sender.Parent).Height:=Biger(RealHeight);

JustBandHeight(Sender.Parent);

end

else

TfrxMemoView(Sender).Height:=TfrxBand(Sender.Parent).Height

-TfrxMemoView(Sender).Top;

end;

procedureJustBandHeight(Sender:TfrxComponent);

var

I:Integer;

begin

for I:=0 to Sender.Objects.Count-1 do

if TObject(Sender.Objects.Items[I]) isTFrxMemoView then

ifTFrxMemoView(Sender.Objects.Items[I]).Tag=7635 then Continue

else

//如果小才改变,如果大则不能改变

ifBiger(TfrxMemoView(Sender.Objects.Items[I]).Height+

TfrxMemoView(Sender.Objects.Items[I]).Top)<>Biger(TfrxBand(Sender).Height)then

TfrxMemoView(Sender.Objects.Items[I]).Height:=

Biger(TfrxBand(Sender).Height-TfrxMemoView(Sender.Objects.Items[I]).Top);

end;

procedure JustMemo(Sender:TfrxComponent);

begin

if not Engine.FinalPass then Exit;

if Sender.Tag<>7635 then

JustHeight(Sender);

end;

procedure SetMemo(Sender:TfrxComponent);

var

I:Integer;

begin

for I:=0 to Sender.Objects.Count-1 do

if TObject(Sender.Objects.Items[I]) isTFrxMemoView then

ifTfrxMemoView(Sender.Objects.Items[I]).Tag<>7635 then

TfrxMemoView(Sender.Objects.Items[I]).OnAfterData:=‘JustMemo‘;

end;

10.FastReport中如何实现套打

纸张是连续的带锯齿的已经印刷好的,类似于通信公司发票这里设计的是客户销售记录。

客户有两个要求:

1、因为打印纸张是印刷的,明细记录只有8行,所以,如果明细记录如果不到8行,就将公司名称

、销售记录打印在上面,下一个公司的信息打印在下一页,而不能接在该页上(呵呵,是啊,如

果接在一起,那印刷单就失去意义了)

2、如果销售记录超过8行,则从第9行开始的销售记录打印在下一页(所谓下一页,其实就是锯齿

分割的下一*,称呼“下一份”比较妥切?),并且抬头(也就是公司名称)也要打上(如果不打

印抬头,撕下了后,可能弄混淆了,不知道这一页是哪个公司的)

问题描述标准说法是不是应该叫“打印固定行”、“强制换页”?

回答:每页打印抬头的问题,就是把包含公司名称的Band每页重复打印即可。属性中有一个的。

勾选就行了。

至于固定行,实际上设计套打时,页面大小都是固定的,每一行的高度也都是固定的,页眉与页

脚也是固定的,这样设计出来的报表可打印的行数自然就是你要求的 8行了。根本不需要什么强

制换页。因为根据纸张会自动换页的。你要做的就是设计好纸张尺寸、页面布局,就得了,套打

是一种最简单的打印,不用想的太复杂。

11.FastReport中如何实现连续打印?

很多人认为Fr不能实现连续打印,以为只能通过自己写函数调用打印函数来实现连续打印,实际

上,Fr可以轻易的实现连续打印,同时,实现时又是非常简单,你甚至可以在你的程序的打印设

置中简单的让客户选择是否连续打印,其它都可以保持不变。

function PelsTomm(Pels:Extended):Extended;

begin

Result:=Pels/Screen.PixelsPerInch*25.4;

end;

procedurePrintSerial(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) thenBreak;

R:=Pelstomm(Frx.Engine.TotalPages*Frx.Engine.PageHeight-

Frx.Engine.FreeSpace)+R1;

P.PaperHeight:=R;

end;

{必须用上面的循环代码来得到准确的空白区域

不能用通过计算总页数减去各页的页边距的方法来获得空白区域

因为如果碰到一条记录过宽的情况导致换页,就不准确了。}

R:=Pelstomm(Frx.Engine.TotalPages*Frx.Engine.PageHeight-

Frx.Engine.FreeSpace)+R1;

P.PaperHeight:=R;

end;

在预览或打印前先调用PrintSerial即可。

12.如何在程序中指定打印机名称?

frxReport1.Report.PrintOptions.Printer := ‘打印机名称‘;

13.如何使用打印机直接打印?

implementation

uses Printers;

{$R *.dfm}

procedure TForm1.Button1Click(Sender:TObject);

begin

Printer.PrinterIndex := 0;{网络打印机也是要安装在你本地的操作系统中的,直接使用顺序

试试吧}

Printers.Printer.SetPrinter(‘HP1020‘,‘HP1020‘,‘LPT1‘,0);{打印机名字,驱动,端口等,

自查,我是用虚拟打印机测试的}

Printers.Printer.BeginDoc;

Printers.Printer.Canvas.TextOut(10,10,‘打印这一行字‘);

Printers.Printer.EndDoc;

end;

14.如何打印空白处?

在打印报表的Band处的OnBeforePrint事件中添加代码:

while FreeSpace > 20 do

ShowBand(Child1)

15.如何打印指定行数后换页?

在master band中OnBeforePrint事件中写代码:

var

vLineCount: integer;

begin

vLineCount := vLineCount + 1;

if vLineCount = 10 then

begin

vLineCount := 0;

NewPage;

end;

end;

16.fastreport中如何把数据显示为百分比

DisplayFormat属性,其中的Kind你设置成fkNumeric,FormatStr

[<frxDBDataset1."sjl">*100#n%2.2f]%”。

17.FastReport如何打印表格式的空行?

var

PageLine: integer; //在页列印到第几行

PageMaxRow: integer=15; //设定每页列数

procedure MasterData1OnBeforePrint(Sender:TfrxComponent);

begin

PageLine := <Line> mod PageMaxRow;

if(PageLine = 1) and (<line> > 1) then

Engine.newpage;

child1.visible := False;

end;

//Footer1高度设为0

procedure Footer1OnBeforePrint(Sender:TfrxComponent);

var

i:integer;

begin

i:= iif(PageLine=0, PageMaxRow, PageLine);

child1.visible := True;

while i < PageMaxRow do

begin

i:= i + 1;

Engine.ShowBand(Child1); //印空白表格

end;

child1.visible := False;

end;

begin

end.

========================================================================

早期版本

---------------- 使用自定义函数----------------------------------------

Q: 我怎样添加我的自定义函数?

A: 使用TfrReport.OnUserFunction 事件. 这里有一个简单的例子:

procedureTForm1.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 函数了。

Q: 但是它仅仅能工作在一个TfrReport组件中。可我想在任何地方(在所有的TfrReport组件中)

使用的我的自定义函数?

A: 使 OnUserFunctionevent 句柄作为所有组件的公用句柄。如果你不能做到这一点,你需要创

建函数库:

type

TMyFunctionLibrary =class(TfrFunctionLibrary)

public

constructor Create; override;

procedure DoFunction(Fno: Integer; p1, p2,p3: Variant;

var val: Variant); override;

end;

constructor TMyFunctionLibrary.Create;

begin

inherited Create;

with List do

begin

Add(‘DATETOSTR‘);

Add(‘SUMTOSTR‘);

end;

end;

procedureTMyFunctionLibrary.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);

Q: 我怎样将我的函数添加到函数列表中 (用表达式生成器)?

A: 使用 frAddFunctionDesc 过程 (在FR_Class 单元中):

frAddFunctionDesc(FuncLib, ‘SUMTOSTR‘, ‘Myfunctions‘,

‘SUMTOSTR(<Number>)/Converts number toits verbal presentation.‘);

注意: "/" 符号是必须的! 它从它的描述中分隔函数语法。

FuncLib 被声明为你自己的函数库 (如果你不使用函数库可以将其设置为nil). 当函数库未注册

时,所有它的函数将自动从函数列表中删除。

---------------- 使用变量-------------------------------------

Q: 我怎样编程实现填充变量列表(在数据词典中)?

A:数据词典中的所有变量及分类都被存储在TfrReport.Dictionary.Variables 中.

with frReport1.Dictionary do

begin

// 创建分类(名称用空白)

Variables[‘ New category‘] := ‘ ‘;

// 创建变量

Variables[‘New Variable‘] := ‘CustomerData.Customers."CustNo"‘;

Variables[‘Another Variable‘] := ‘Page#‘;

end;

Q: 我定义了字符串变量:

with frReport1.Dictionary do

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

但是当我运行报表是,出现了错误,为什么?

A: 因为 FastReport 假定数据词典中的字符串变量值是一个表达式,它需要分析、计算它。

可以使用其它的方法:

with frReport1.Dictionary do

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

或者, 使用 frVariables 来传输固定数据到报表。

Q: 我不想在数据词典中显示某些数据集?

A: 使用TfrReport.Dictionary.DisabledDatasets:

with frReport1.Dictionary do

begin

// 关闭该数据集

DisabledDatasets.Add(‘CustomerData.Bio‘);

// 或者, 关闭整个数据模块/窗体

DisabledDatasets.Add(‘CustomerData*‘);

end;

Q: 我怎样将数据传送到报表?

A: 有几个方法可以实现它. 第一是使用全局对象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.Dictionary do

begin

Variables[‘MyVariable‘] :=‘CustomerData.Customers."CustNo"‘;

Variables[‘Another Variable‘] := ’10’;

end;

Q: 我能在报表和程序间传送数据吗?

A: 使用 frVariables 对象. 如果你在报表的任何对象的脚本中写入以下代码:

MyVariable := 10

那么,在你的程序中,你可以使用以下代码来获取 MyVariable 的值:

v := frVariables[‘MyVariable‘];

----------------脚本(FastReport Pascal) ---------------------------------

Q: Band 中是否可以使用脚本?

A: 当然. 选择 band ,然后按Ctrl+Enter 或在对象浏览器中选择 "OnBeforePrint" 属性。

Q: 报表页中是否可以使用脚本?

A: 当然. 选择页 (在空白处单击) ,然后在对象浏览器中选择"OnBeforePrint" 属性。如果该

页是一个对话框窗体,那么这个属性就是 "OnActivate".

Q: 我有两个对象: Memo1 和 Memo2. 我能否在 Memo1 的脚本中调用 Memo2 的属性和方法?

A: 当然, 例如,你可以这样做: 对象名.属性名.

Q: 在脚本中,我可以使用对象的哪些属性?

A: 几乎所有你能在对象浏览器中看到的属性。例如,可以使用 Font .Name, Font.Size等来存取

字体属性。

---------------- 其它问题--------------------------------------------

Q: 怎样改变多页报表中某一页的顺序?

A: 拖动页标签到目的位置。

Q: 我想查看所有的字段及变量,我想在报表中使用列表来实现它?

A: 设置TfrReport.MixVariablesAndDBFields := True.所有的数据字段及变量可在“插

入数据字段”对话框中可存取了。

Q: 我不想显示导入选项对话框?

A: 在导入组件(比如,TfrTextExport)中设置所有必需的选项,然后通过设置ShowDialog属性为

False来关闭此对话框。

Q: 为什么 TotalPages变量不起作用? 它总是返回 0.

A: 在你的报表中设置 Two-pass 选项. 要设置它,你需要在报表设计器的“文件”菜单中,打开

“报表选项”对话框。

Q: 我用BLOB字段来存储我的报表。当我运行报表设计器时,它显示我的报表未命名

A: 在运行报表设计器前,这样做:

frReport1.FileName := ‘Name of my report‘;

Q: 我想在重新定义报表设计器中的“打开”及“保存”按钮的功能?

A: 查看 TfrDesigner 组件. 它有几个必需的事件:OnLoadReport 和

OnSaveReport. 这里有一小段代码例子:

procedureTForm1.frDesigner1LoadReport(Report: TfrReport;

var ReportName: String; var Opened:Boolean);

begin

with MyOpenDialog do

begin

Opened := ShowModal = mrOk;

if Opened then

begin

Report.LoadFromBlobField(…);

ReportName := …;

end;

end;

end;

procedureTForm1.frDesigner1SaveReport(Report: TfrReport;

var ReportName: String; SaveAs: Boolean;var Saved: Boolean);

begin

if SaveAs then

with MySaveDialog do

begin

Saved := ShowModal = mrOk;

if Saved then

begin

Report.SaveToBlobField(…);

ReportName := …;

end;

end

else

Report.SaveToBlobField(…);

end;

Q: 在 QR 中, 我可以写这样的代码:QRLabel1.Caption := ’Some text’. 我可以用FR这样做

吗?

A: FR 对象并不是一个组件 (这并不像 QR, RB).但使用 TfrReport.FindObject 方法可以通过

对象名称找到该对象。

var

t: TfrMemoView;

begin

t :=TfrMemoView(frReport1.FindObject(’Memo1’));

if t <> nil then

t.Memo.Text := ’FastReport’;

end;

Q: 我想在用户预览(TfrPreview组件)中自定义热键

A: 这个组件有个窗口: Tform 属性. 将自定义句柄指定到Window.OnKeyDown 属性.

Q: Fast Report 2.4 不能装载FreeReport 2.21 文件?

A: 这仅需要使用16进制数改变报表文件的第一字节,然后在源代码中修改下面的部分。在这些修

改之后,装载报表并保存它. 最后,返回到源代码处.

FR_Class:

function ReadString(Stream: Tstream):String;

begin

{ if frVersion >= 23 then}

Result := frReadString(Stream) {else

Result := frReadString22(Stream);}

end;

procedure ReadMemo(Stream: Tstream; Memo:Tstrings);

begin

{ if frVersion >= 23 then}

frReadMemo(Stream, Memo){ else

frReadMemo22(Stream, Memo);}

end;

FR_Utils:

procedure frReadMemo(Stream: Tstream; l:Tstrings);

var

s: String;

b: Byte;

n: Word;

begin

l.Clear;

l.Text := frReadString(Stream); exit;

Stream.Read(n, 2);

if n > 0 then

repeat

Stream.Read(n, 2);

SetLength(s, n);

Stream.Read(s[1], n);

l.Add(s);

Stream.Read(b, 1);

until b = 0

else

Stream.Read(b, 1);

end;

function frReadString(Stream: Tstream):String;

var

s: String;

n: Integer;

b: Byte;

begin

Stream.Read(n, 4);

SetLength(s, n);

Stream.Read(s[1], n);

if (n > 0) and (s[n] = #$0A) then

SetLength(s, n - 2);

// Stream.Read(b, 1);

Result := s;

end;

Q: 怎样不在打印预览中打印报表?

A: 这里有一段代码:

frReport1.PrepareReport;

frReport1.PrintPreparedReport(‘‘, 1, True,frAll);

frReport1.PrintPreparedReportDlg;

Q: 我想在报表中旋转图片。问题是这张图片是由我的应用程序生成的。是否有方法可以在打印前

将这幅图片装载到报表中?

A: 使用TfrReport.OnBeforePrint 事件:

if View .Name = ‘Picture1‘ then

TfrPictureView(View).Picture.LoadFromFile(…) 或

.Assign 或

.你所想要做的任何事情

FastReport套打全攻略

//以设计套打行为6行为例进行说明

一、定义变量

TaoDa 0 是套打1 不套打

cPage系统变量页#

caPage系统变量总页数

二、TfrPage.OnBeforePrint事件中写

{

ifTaoDa = ‘0‘ then

begin

title.visible:=false; //不用打印的设置Visible为False;

danweiv.frametyp := 0; //只打印数据的不需要打印边框的设置 frametyp 为 0;

...

end;

i :=0 ; //定义一个变量并进行初始化。

}

二、主项数据.OnBeforePrint事件中写

{

ifTaoDa = ‘0‘ then

begin

i:= i + 1;

bm.memo := i;

if(i > 5 ) then

if ((i-1) mod 6 ) = 0 then newpage;

end;

}

三、主项脚.OnBeforePrint事件中写

{

j :=i mod 6;

if j<> 0 then

begin

for k := j to 5 do

begin

ShowBand(Child1); //Child1是子的名称 显示空白行

end;

end;

}

四、栏目脚.OnBeforePrint事件中写

{

ifcpage <> capage then

begin

shi.memo := ‘‘; //十

bai.memo := ‘‘; //百

qian.memo := ‘‘; //千

wan.memeo := ‘‘; //万

end

else begin

shi.memo := v1;

bai.memo := v2;

qian.memo := v3;

wan.memo := v4;

end;

}

这段代码是用来控制在有多页情况下,在最后一页上显示总金额。

其中:v1,v2,v3,v4 是自定义变量

报表结构组成:

栏目头 //画报表的标头

主项数据 //显示的数据,会与数据源进行绑定

主项脚 //什么也不用放,只用来控制 visible := false;

子 //画出空白行显示的组件

栏目脚 //显示总的金额、数量

页脚//显示页数

调用方法:

frReportA.LoadFromFile(s); s 是文件

frReportA.Dictionary.Variables[‘taoda‘]:=‘1‘;

进行查询

打印:

frReportA.PrepareReport;

frreportA.PrintPreparedReport(‘‘,1,true,frall);

预览:

frReportA.ShowReport;

FastReport打印CxGrid数据

用惯了FastReport,就不愿意再使用其他的Print Component。用FastReport打印CxGrid Filter后的数据,网上一直没有很好的办法和例程。看到有将CxGrid的Fileter Text取出后再赋给DataSet的说明,没有具体去试验,太麻烦。如此著名的Component肯定有解决此问题的方法。于是今天到Dev Express英文站点去浏览了一番,在该站上搜索了一下,居然出来N多此问题的提问者,看了几个这类的问题后,终于解决了。

解决此问题可以使用以下方法:

1、将View的datacontroller.filter.autodatasetfilter属性设为True。

此方法需要DataSet支持才能设置。

2、是在FastReport的frDBDataSet的CheckEofEvent里写如下代码:

EOF := frUserDataset1.RecNo >=Grid.ViewData.RecordCount;

在frReport的GetValue Event里写代码:

if ParName=‘Field1‘ then

ParValue :=Grid.ViewData.Records[frDataset1.RecNo].Values[2]);

此代码也可这样写:

ParValue:=Grid.ViewData.Records[frDataset1.RecNo].Values[View.GetColumnByFieldName(ParName).Index]);

ReportMachine

1.如何使用代码指定打印机?

RMReport1.LoadFromFile(‘Untitled.rmf‘);

rmreport1.PrinterName:=‘\\192.168.10.1\HP LaserJet 1022‘;

时间: 2024-08-07 04:32:18

FastReport 使用技巧篇的相关文章

2天驾驭DIV+CSS (技巧篇)(转)

这是去年看到的一片文章,感觉在我的学习中,有不少的影响.于是把它分享给想很快了解css的兄弟们.本文是技巧篇. 基础篇[知识一] “DIV+CSS” 的叫法是不准确的[知识二] “DIV+CSS” 将你引入两大误区[知识三] 什么是W3C标准?[基础一] CSS如何控制页面[基础二] CSS选择器[基础三] CSS选择器命名及常用命名[基础四] 盒子模型[基础五] 块状元素和内联元素 实战篇[第一课] 实战小热身[第二课] 浮动[第三课] 清除浮动[第四课] 导航条(上) | 导航条(下)[大练

移动前端工作的那些事---前端制作之微信小技巧篇

移动前端工作的那些事---前端制作之微信小技巧篇_WebApp赵海洋_新浪博客 移动前端工作的那些事---前端制作之微信小技巧篇 (2013-11-15 15:20:47) 转载▼移动前端工作的那些事---前端制作之微信小技巧篇,布布扣,bubuko.com

Visual Studio调试之断点技巧篇补遗

原文链接地址:http://blog.csdn.net/Donjuan/article/details/4649372 讲完Visual Studio调试之断点技巧篇以后,翻翻以前看得一些资料和自己写的一些文章,发现还有几个关于中断程序的技巧在前面的文章里面遗漏了,决定还是在这里总结一下.当然啦,如果你知道这些技巧,忽略这篇文章好了,:) 在程序启动的时候将调试器附加上去 可能有人会对这个问题有一些争议,因为大部分情况下我们只需要在调试器(Debugger)里面直接启动被调试程序(Debugge

经济--理财--银行理财技巧篇

银行理财技巧篇 避开银保产品 银行卖的产品,有银行自己发行的产品,还有合作类的产品(银信(与信托公司合作),银保(与保险公司合作),银证信(与证卷.信托合作)) 合作类的产品,银行只是个超市.银保类产品投诉很高哦.买了银保产品,1.有15天犹豫期.2.12378来进行投诉. 期限搭配,让”钱“变活 有没有办法提高流动性呢? 将大额资金拆分成几分,分别购买. 12单法.60单法 上海车牌   7   8 万. 这样做,以后每个月都有一笔7W的资金到期. 巧选时点,收益大增 什么时候买最划算呢? 在

XSS的原理分析与解剖:第三章(技巧篇)**************未看*****************

??0×01 前言: 关于前两节url: 第一章:http://www.freebuf.com/articles/web/40520.html 第二章:http://www.freebuf.com/articles/web/42727.html 说的xss的原理及不同环境的构造方法.和XSS的分类及挖掘方法.那么本期则说XSS技巧,前面两个干货不太多,讲的都是比较基础的.而这期则是满满的干货. 从本期开始,XSS我就开始深入了.至 于下一章XSS编码,已经被0xExploit写过了( http:

【Unity技巧】开发技巧(技巧篇)

写在前面 和备忘录篇一样,这篇文章旨在总结Unity开发中的一些设计技巧,当然这里只是我通过所见所闻总结的东西,如果有不对之处欢迎指出. 技巧1:把全局常量放到一个单独的脚本中 很多时候我们需要一些常量,例如是否输出Log,正式服务器和测试服务器的IP等等,我们可以把这些常量写在同一个脚本里,并设置属性为public static,然后在其他脚本里直接访问该变量即可.当代码量越来越大时,你会发现这样会减少很多查找常量的时间.而且,这样更改时也非常方便,例如当需要发布新版本时,你只要把该脚本中的l

Visual Studio调试之断点技巧篇

原文链接地址:http://blog.csdn.net/Donjuan/article/details/4618717 函数断点 在前面的文章Visual Studio调试之避免单步跟踪调试模式里面我讲了如何设置函数断点,说实话,我个人喜欢设置函数断点,而不是在代码行里面设置断点.一般来说,函数断点在下面几种情形下有用: 1. 例如调试一个网站程序,你通过分析网站的日志发现最有可能发生错误的函数,打开调试器并将调试器附加到程序上去,设置函数断点,重新执行网站--这样做的好处是,不用到处打开源文件

XSS的原理分析与解剖:第三章(技巧篇)【转】

0×01 前言: 关于前两节url: 第一章:http://www.freebuf.com/articles/web/40520.html 第二章:http://www.freebuf.com/articles/web/42727.html 说的xss的原理及不同环境的构造方法.和XSS的分类及挖掘方法.那么本期则说XSS技巧,前面两个干货不太多,讲的都是比较基础的.而这期则是满满的干货. 从本期开始,XSS我就开始深入了.至 于下一章XSS编码,已经被0xExploit写过了( http://

源码阅读技巧篇

转载请注明原创出处,谢谢! 说在前面 本人水平有限,下面的一些都是本人的思考与理解,如果有那里不对,希望各位大佬积极指出,欢迎在留言区进行评论交流.探讨. 主题 为什么要读源码 读什么样的源码 有什么技巧 思考.交流 坚持 为什么要源码 说到读源码,让我想起来了读书,古语有云:"读破万卷书,下笔如有神". 多读读大师的想法技巧 通过大量阅读进行积累 把一些零碎的知识点整合起来 就拿RocketMQ来说,它是如何实现高性能.高可用.之前写过高可用的一些思考和理解里面的特性他应该都满足,R