FastReport问题整理(转)
FastReport問(wèn)題整理
博客分類:- ?
- 軟件開(kāi)發(fā)
?
部分來(lái)自網(wǎng)上,部分來(lái)自網(wǎng)友,部分來(lái)自Demo
如果有新的內(nèi)容,會(huì)不斷更新..
更新歷史:
2009-02-27 加入套打方案全攻略(原:jinzhili博客)
2009-03-03?FastReport打印CxGrid數(shù)據(jù)
========================================================================
新版本
1.FastReport中如果訪問(wèn)報(bào)表中的對(duì)象?
可以使用FindObject方法。
TfrxMemoView(frxReport1.FindObject(’memo1′)).Text:=’FastReport’;
2.FastReport中如何使用上下標(biāo)?
設(shè)置frxmemoview.AllowHTMLTags := True;在Text輸入如下
上標(biāo):mm<sup>2</sup>
下表:k<sub>6</sub>
舉一反三,你還可以使用其他HTML標(biāo)記。
3.FastReport中如何打印總頁(yè)數(shù)?
設(shè)置兩次報(bào)表后加入引號(hào)內(nèi)內(nèi)容 “第[Page#]頁(yè) 共[TotalPages#]頁(yè)”
4.FastReport中如何動(dòng)態(tài)加入變量及變量組?
建立變量組名
frxreport1.Variables.Add.Name:=’ ‘+變量組名;
建立變量名
frxreport1.Variables.AddVariable(’組名,如果為不存的組或空,則為默認(rèn)組,這里不需要
空格’,變量名,變量初始值);
例如要建立變量組Yuan,二個(gè)變量Yuan1,Yuan2,則為
frxreport1.Variables.Add.Name:=’ Yuan’注意前面是空格
frxreport1.Variables.AddVariable(’Yuan’,Yuan1,初始值)
frxreport1.Variables.AddVariable(’Yuan’,Yuan2,初始值)
5.FastReport中如何加入自定義函數(shù)?
Fastreport可以自己加入需要的函數(shù),來(lái)實(shí)現(xiàn)特定的功能。過(guò)程就是:
1)添加函數(shù)到報(bào)表中。
frxreport1.AddFunction(’完整的函數(shù)聲明’);
如有一個(gè)自定義函數(shù),為GetName(Old:String):String;這個(gè)函數(shù)通過(guò)數(shù)據(jù)集的一個(gè)字段,得到另
一個(gè)返回值。
則語(yǔ)句為:frxreport1.AddFunction(’Function GetName(Old:String):String;’);
2)腳本中使用函數(shù)。
在腳本中或報(bào)表中使用自定義函數(shù),就像使用其它Fastreport內(nèi)置函數(shù)一樣。
3)程序中處理函數(shù)。
使用函數(shù)是通過(guò)frxreport1的OnUserFunction函數(shù)來(lái)實(shí)現(xiàn)的。
OnUserFunction的聲明如下:Function(const MethodName: String;var Params: Variant):
Variant;
比如上面的函數(shù),首先要有一個(gè)函數(shù),這個(gè)函數(shù)是GetName的實(shí)現(xiàn)部分。如有一個(gè)在程序中實(shí)現(xiàn)的
函數(shù)。
function RealGetName(Old:String):String;這個(gè)函數(shù)名是無(wú)所謂的,也可以是GetName。
在OnUserFunction的事件處理中有如下代碼即可完成自定義函數(shù)在報(bào)表中的使用。
if CompareText(MethodName,’GetName’)=0 then Result:=RealGetName(VarToStr(Params[0]));
我一般都是使用CompareText來(lái)比較函數(shù)名,因?yàn)槲野l(fā)現(xiàn)二個(gè)版本的Fastreport,一個(gè)是
MethodName全部自動(dòng)變成了小寫(xiě),一個(gè)是全部自動(dòng)變成了大寫(xiě),所以干脆用CompareText來(lái)比較,
肯定不會(huì)出錯(cuò)。
如果有多個(gè)參數(shù),則依次傳遞Params[0],Params[1]即可,要保持順序一致。
這里要注意一點(diǎn),如果參數(shù)為指針,則不能直接使用Pointer(Integer(Params[0]))。因?yàn)閷?shí)際傳
遞過(guò)來(lái)的是指針的整數(shù)值,可以使用Pointer(StrToInt(VarToStr(Params[0])))。
6.FastReport中如何共用TFrxreport及TfrxDBDataSet?
一個(gè)程序中,不管多么大的程序,只要打印或預(yù)覽時(shí)是模式的,則完全可以共用一個(gè)TFrxreport
變量及幾個(gè)TfrxDBDataSet。只不過(guò),要注意完成一個(gè)報(bào)表程序的步驟,主要是下面幾步
1)清除報(bào)表,得到一個(gè)全新的報(bào)表內(nèi)容。
Frxreport1.clear。
2)設(shè)置要使用的TfrxDBDataSet的別名,如果不需要可以省略這一步,但一般最好不同的報(bào)表用不
同的別名。
注意這一步要在加載報(bào)表文件之前,因?yàn)橐话阍O(shè)計(jì)報(bào)表文件時(shí)已經(jīng)包含了別名信息。
frxDBDataSet1.UserName:=別名;
3)加載報(bào)表或動(dòng)態(tài)建立一個(gè)TfrxReportPage。
Frxreport1.LoadFromFile(報(bào)表文件的完整文件名);
4)關(guān)聯(lián)TfrxDBDataSet與TDataset,并設(shè)置要使用哪些TfrxDBDataSet。
Frxreport1.DataSets.Clear;//先清除原來(lái)的數(shù)據(jù)集
frxDBDataSet1.DataSet:=dataset1;//關(guān)聯(lián)Fastreport的組件與TDataset數(shù)據(jù)集。
Frxreport1.DataSets.Add(frxDBDataSet1);//加載關(guān)聯(lián)好的TfrxDBDataSet到報(bào)表中。
經(jīng)過(guò)這幾步后,就可以像單獨(dú)使用一個(gè)Tfrxreport一樣使用共用的報(bào)表組件了
7.FastReport中如何使用腳本,腳本中使用變量?
很多時(shí)候,我們希望把對(duì)報(bào)表的控制放到報(bào)表的腳本中,通常我這樣做有二個(gè)原因:
1)能夠根據(jù)字段內(nèi)容的變化而使用不同的設(shè)置,因?yàn)槿绻朐诔绦蛑袑?shí)現(xiàn)這樣功能,就不得不用
自定義函數(shù),函數(shù)的實(shí)現(xiàn)要放到程序中,函數(shù)可能需要傳遞很多參數(shù),效率低下。
2)把不同報(bào)表的控制放到腳本中,可以實(shí)現(xiàn)報(bào)表的模塊化,程序只是簡(jiǎn)單的設(shè)置數(shù)據(jù)集的關(guān)系,
并加載硬盤上的報(bào)表文件,不同報(bào)表的不同實(shí)現(xiàn)方式,顯示方式,均放到報(bào)表文件中,程序簡(jiǎn)潔
,易維護(hù),易升級(jí)。
當(dāng)然,這樣的缺點(diǎn)就是程序中加載報(bào)表時(shí)的數(shù)據(jù)集別名必須與設(shè)計(jì)報(bào)表時(shí)的別名一致。
腳本的使用與通常程序的使用并沒(méi)有太多的區(qū)別,就是像正常的程序那樣引用控件的名稱即可。
但注意對(duì)變量的使用,需要把變量名或表達(dá)式用<>括起來(lái)。
實(shí)現(xiàn)打印分組的頁(yè)數(shù)?;镜脑砭褪?#xff1a;
1)必須使用二遍報(bào)表,因?yàn)镕S算總頁(yè)數(shù)就是需要二遍報(bào)表的。
2)在第一遍報(bào)表中,在GroupBand打印前,動(dòng)態(tài)的建立整數(shù)型數(shù)組變量,用以保存上一個(gè)分組的
總頁(yè)數(shù)。
3)在最后一遍報(bào)表時(shí),需要顯示分組頁(yè)數(shù)的Tfrxmemoview取得數(shù)組中的數(shù)據(jù),但最后一個(gè)分組
不會(huì)有總數(shù),可以通過(guò)總頁(yè)數(shù)減去GroupBand事件中保存的頁(yè)數(shù)來(lái)取得。
4)代碼中處理了一頁(yè)多組,及一組多頁(yè)打印分組頭的情況??梢钥吹竭@些特殊處理的代碼說(shuō)明
。
5)我特意在分組尾及頁(yè)腳都用了Tfrxmemoview來(lái)顯示這些數(shù)據(jù),說(shuō)明在不同情況下的顯示。
8.FastReport中如何在腳本中根據(jù)字段名改變Tfrxmemoview的內(nèi)容?
假設(shè)有數(shù)據(jù)表“用戶”,字段ID為用戶標(biāo)識(shí),Name為用戶名,打印時(shí)要求,如果用戶名為空,則
打印“無(wú)用戶名”,否則打印出“用戶名:實(shí)際的用戶”,則可以在ID的Tfrxmemoview控件的
OnAfterData事件中寫(xiě)如下腳本。
if <frxDBDataSet1.”Name”>=” then
Memo2.Text:=’無(wú)用戶名’
else
Memo2.Text:=’用戶名:[frxDBDataSet1."Name"]‘
Memo2是放置用戶名稱數(shù)據(jù)的Tfrxmemoview控件。
這里注意,要在腳本中訪問(wèn)變量需要把變量用<>包括起來(lái)。
9.FastReport中如何動(dòng)態(tài)調(diào)整高度?
我經(jīng)常使用下面的幾個(gè)函數(shù)來(lái)實(shí)現(xiàn)Band及Tfrxmemoview高度的動(dòng)態(tài)調(diào)整,需要注意的是:下面的
函數(shù)只能調(diào)整一個(gè)Band中多行的最后一行,如果只有一行(多數(shù)情況下應(yīng)該是這樣)就無(wú)所謂了
,而且這是在寬度已經(jīng)固定的前提下。在想要調(diào)整高度的Band的OnBeforePrint事件中寫(xiě)
SetMemo(Sender);,代碼如下,粘貼到代碼頁(yè)中就可以使用。
下面的代碼也可以演變一些,實(shí)現(xiàn)動(dòng)態(tài)寬度等。我多處都判斷了Tag是否為7635,因?yàn)槲医?jīng)常需要
單獨(dú)調(diào)用其中的某個(gè)函數(shù)。
//7635為保留數(shù)字,表示不作任何調(diào)整,通常用在多行的最上方
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);
if Biger(TfrxBand(Sender.Parent).Height)<RealHeight then
begin
//若MEMO的高度小于BAND但計(jì)算高度大于BAND,則在調(diào)整BAND的函數(shù)中就會(huì)被調(diào)整
TfrxBand(Sender.Parent).Height:=Biger(RealHeight);
JustBandHeight(Sender.Parent);
end
else
TfrxMemoView(Sender).Height:=TfrxBand(Sender.Parent).Height
-TfrxMemoView(Sender).Top;
end;
procedure JustBandHeight(Sender:TfrxComponent);
var
I:Integer;
begin
for I:=0 to Sender.Objects.Count-1 do
if TObject(Sender.Objects.Items[I]) is TFrxMemoView then
if TFrxMemoView(Sender.Objects.Items[I]).Tag=7635 then Continue
else
//如果小才改變,如果大則不能改變
if Biger(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]) is TFrxMemoView then
if TfrxMemoView(Sender.Objects.Items[I]).Tag<>7635 then
TfrxMemoView(Sender.Objects.Items[I]).OnAfterData:=’JustMemo’;
end;
10.FastReport中如何實(shí)現(xiàn)套打?
紙張是連續(xù)的帶鋸齒的已經(jīng)印刷好的,類似于通信公司發(fā)票這里設(shè)計(jì)的是客戶銷售記錄。
客戶有兩個(gè)要求:
1、因?yàn)榇蛴〖垙埵怯∷⒌?#xff0c;明細(xì)記錄只有8行,所以,如果明細(xì)記錄如果不到8行,就將公司名稱
、銷售記錄打印在上面,下一個(gè)公司的信息打印在下一頁(yè),而不能接在該頁(yè)上(呵呵,是啊,如
果接在一起,那印刷單就失去意義了)
2、如果銷售記錄超過(guò)8行,則從第9行開(kāi)始的銷售記錄打印在下一頁(yè)(所謂下一頁(yè),其實(shí)就是鋸齒
分割的下一*,稱呼“下一份”比較妥切?),并且抬頭(也就是公司名稱)也要打上(如果不打
印抬頭,撕下了后,可能弄混淆了,不知道這一頁(yè)是哪個(gè)公司的)
問(wèn)題描述標(biāo)準(zhǔn)說(shuō)法是不是應(yīng)該叫“打印固定行”、“強(qiáng)制換頁(yè)”?
回答:每頁(yè)打印抬頭的問(wèn)題,就是把包含公司名稱的Band每頁(yè)重復(fù)打印即可。屬性中有一個(gè)的。
勾選就行了。
至于固定行,實(shí)際上設(shè)計(jì)套打時(shí),頁(yè)面大小都是固定的,每一行的高度也都是固定的,頁(yè)眉與頁(yè)
腳也是固定的,這樣設(shè)計(jì)出來(lái)的報(bào)表可打印的行數(shù)自然就是你要求的 8行了。根本不需要什么強(qiáng)
制換頁(yè)。因?yàn)楦鶕?jù)紙張會(huì)自動(dòng)換頁(yè)的。你要做的就是設(shè)計(jì)好紙張盡寸、頁(yè)面布局,就得了,套打
是一種最簡(jiǎn)單的打印,不用想的太復(fù)雜。
11.FastReport中如何實(shí)現(xiàn)連續(xù)打印?
很多人認(rèn)為Fr不能實(shí)現(xiàn)連續(xù)打印,以為只能通過(guò)自己寫(xiě)函數(shù)調(diào)用打印函數(shù)來(lái)實(shí)現(xiàn)連續(xù)打印,實(shí)際
上,Fr可以輕易的實(shí)現(xiàn)連續(xù)打印,同時(shí),實(shí)現(xiàn)時(shí)又是非常簡(jiǎn)單,你甚至可以在你的程序的打印設(shè)
置中簡(jiǎn)單的讓客戶選擇是否連續(xù)打印,其它都可以保持不變。
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
{必須是二遍報(bào)表,否則無(wú)法計(jì)算總頁(yè)數(shù)。
下面的方法只適用于沒(méi)有頁(yè)腳的情況,因?yàn)槿绻许?yè)腳的話
FreeSpace就始終為0了??梢杂脠?bào)表腳來(lái)代替。
因?yàn)槭沁B續(xù)打印,也可以看作只有一頁(yè),報(bào)表腳也就相當(dāng)于頁(yè)腳了}
if not Frx.Engine.DoublePass then Exit;
//SequencePage指要連續(xù)打印的頁(yè)面,普通報(bào)表就是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;
{必須用上面的循環(huán)代碼來(lái)得到準(zhǔn)確的空白區(qū)域
不能用通過(guò)計(jì)算總頁(yè)數(shù)減去各頁(yè)的頁(yè)邊距的方法來(lái)獲得空白區(qū)域
因?yàn)槿绻龅揭粭l記錄過(guò)寬的情況導(dǎo)致?lián)Q頁(yè),就不準(zhǔn)確了。}
R:=Pelstomm(Frx.Engine.TotalPages*Frx.Engine.PageHeight-
Frx.Engine.FreeSpace)+R1;
P:=TfrxReportPage(Frx.Pages[SequencePage]);
P.PaperHeight:=R;
end;
在預(yù)覽或打印前先調(diào)用PrintSerial即可。
12.如何在程序中指定打印機(jī)名稱?
frxReport1.Report.PrintOptions.Printer := ‘打印機(jī)名稱’;
13.如何使用打印機(jī)直接打印?
implementation
uses Printers;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Printer.PrinterIndex := 0;{網(wǎng)絡(luò)打印機(jī)也是要安裝在你本地的操作系統(tǒng)中的,直接使用順序
試試吧}
Printers.Printer.SetPrinter(’HP1020′,’HP1020′,’LPT1′,0);{打印機(jī)名字,驅(qū)動(dòng),端口等,
自查,我是用虛擬打印機(jī)測(cè)試的}
Printers.Printer.BeginDoc;
Printers.Printer.Canvas.TextOut(10,10,’打印這一行字’);
Printers.Printer.EndDoc;
end;
14.如何打印空白處?
在打印報(bào)表的Band處的OnBeforePrint事件中添加代碼:
while FreeSpace > 20 do
ShowBand(Child1)
15.如何打印指定行數(shù)后換頁(yè)?
在master band中OnBeforePrint事件中寫(xiě)代碼:
var
vLineCount: integer;
begin
vLineCount := vLineCount + 1;
if vLineCount = 10 then
begin
vLineCount := 0;
NewPage;
end;
end;
16.fastreport中如何把數(shù)據(jù)顯示為百分比
DisplayFormat屬性,其中的Kind你設(shè)置成fkNumeric,FormatStr
[<frxDBDataset1."sjl">*100 #n%2.2f]%”。
17.FastReport如何打印表格式的空行?
var
PageLine: integer;?????? //在現(xiàn)在頁(yè)列印到第幾行
PageMaxRow: integer=15;? //設(shè)定每頁(yè)列數(shù)
procedure MasterData1OnBeforePrint(Sender: TfrxComponent);
begin
PageLine := <Line> mod PageMaxRow;
if (PageLine = 1) and (<line> > 1) then
Engine.newpage;
child1.visible := False;
end;
//Footer1高度設(shè)為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.
========================================================================
早期版本
—————- 使用自定義函數(shù) —————————————-
Q: 我怎樣添加我的自定義函數(shù)?
A: 使用 TfrReport.OnUserFunction 事件. 這里有一個(gè)簡(jiǎn)單的例子:
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;
然后,你就可以在報(bào)表(任何表達(dá)式或腳本)的任何地方使用 SumToStr 函數(shù)了。
Q: 但是它僅僅能工作在一個(gè)TfrReport組件中。可我想在任何地方(在所有的TfrReport組件中)
使用的我的自定義函數(shù)?
A: 使 OnUserFunction event 句柄作為所有組件的公用句柄。如果你不能做到這一點(diǎn),你需要?jiǎng)?chuàng)
建函數(shù)庫(kù):
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;
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;
要注冊(cè)函數(shù)庫(kù),調(diào)用
frRegisterFunctionLibrary(TMyFunctionLibrary);
要卸載函數(shù)庫(kù),調(diào)用
frUnRegisterFunctionLibrary(TMyFunctionLibrary);
Q: 我怎樣將我的函數(shù)添加到函數(shù)列表中 (用表達(dá)式生成器)?
A: 使用 frAddFunctionDesc 過(guò)程 (在FR_Class 單元中):
frAddFunctionDesc(FuncLib, ‘SUMTOSTR’, ‘My functions’,
‘SUMTOSTR(<Number>)/Converts number to its verbal presentation.’);
注意: “/” 符號(hào)是必須的! 它從它的描述中分隔函數(shù)語(yǔ)法。
FuncLib 被聲明為你自己的函數(shù)庫(kù) (如果你不使用函數(shù)庫(kù)可以將其設(shè)置為nil). 當(dāng)函數(shù)庫(kù)未注冊(cè)
時(shí),所有它的函數(shù)將自動(dòng)從函數(shù)列表中刪除。
—————- 使用變量 ————————————-
Q: 我怎樣編程實(shí)現(xiàn)填充變量列表(在數(shù)據(jù)詞典中)?
A: 數(shù)據(jù)詞典中的所有變量及分類都被存儲(chǔ)在 TfrReport.Dictionary.Variables 中.
with frReport1.Dictionary do
begin
// 創(chuàng)建分類(名稱用空白)
Variables[' New category'] := ‘ ‘;
// 創(chuàng)建變量
Variables['New Variable'] := ‘CustomerData.Customers.”CustNo”‘;
Variables['Another Variable'] := ‘Page#’;
end;
Q: 我定義了字符串變量:
with frReport1.Dictionary do
Variables['Month'] := ‘March’;
但是當(dāng)我運(yùn)行報(bào)表是,出現(xiàn)了錯(cuò)誤,為什么?
A: 因?yàn)?FastReport?假定數(shù)據(jù)詞典中的字符串變量值是一個(gè)表達(dá)式,它需要分析、計(jì)算它。
可以使用其它的方法:
with frReport1.Dictionary do
Variables['Month'] := ”” +’March’ + ””;
或者, 使用 frVariables 來(lái)傳輸固定數(shù)據(jù)到報(bào)表。
Q: 我不想在數(shù)據(jù)詞典中顯示某些數(shù)據(jù)集?
A: 使用 TfrReport.Dictionary.DisabledDatasets:
with frReport1.Dictionary do
begin
// 關(guān)閉該數(shù)據(jù)集
DisabledDatasets.Add(’CustomerData.Bio’);
// 或者, 關(guān)閉整個(gè)數(shù)據(jù)模塊/窗體
DisabledDatasets.Add(’CustomerData*’);
end;
Q: 我怎樣將數(shù)據(jù)傳送到報(bào)表?
A: 有幾個(gè)方法可以實(shí)現(xiàn)它. 第一是使用全局對(duì)象 frVariables (在 FR_Class 單元中被定義):
frVariables['My variable'] := 10;
這段代碼創(chuàng)建了一個(gè)名稱為“My variable”,值為 10 的變量。這是最好的傳輸固定數(shù)據(jù)的報(bào)表
的方法。
第二種方法是使用 TfrReport.OnGetValue 事件. 這可以使用這個(gè)方法來(lái)傳送動(dòng)態(tài)數(shù)據(jù)、記錄等
。
procedure TForm1.frReport1GetValue(ParName: String; var ParValue: Variant);
begin
if ParName = ‘MyField’ then
ParValue := Table1MyField.Value;
end;
最后, 第三種方法是通過(guò)編程在數(shù)據(jù)詞典中定義變量(可以參考以前的問(wèn)題):
with frReport1.Dictionary do
begin
Variables['MyVariable'] := ‘CustomerData.Customers.”CustNo”‘;
Variables['Another Variable'] := ’10’;
end;
Q: 我能在報(bào)表和程序間傳送數(shù)據(jù)嗎?
A: 使用 frVariables 對(duì)象. 如果你在報(bào)表的任何對(duì)象的腳本中寫(xiě)入以下代碼:
MyVariable := 10
那么,在你的程序中,你可以使用以下代碼來(lái)獲取 MyVariable 的值:
v := frVariables['MyVariable'];
—————- 腳本 (FastReport?Pascal) ———————————
Q: Band 中是否可以使用腳本?
A: 當(dāng)然. 選擇 band ,然后按 Ctrl+Enter 或在對(duì)象瀏覽器中選擇 “OnBeforePrint” 屬性。
Q: 報(bào)表頁(yè)中是否可以使用腳本?
A: 當(dāng)然. 選擇頁(yè) (在空白處單擊) ,然后在對(duì)象瀏覽器中選擇 “OnBeforePrint” 屬性。如果該
頁(yè)是一個(gè)對(duì)話框窗體,那么這個(gè)屬性就是 “OnActivate”.
Q: 我有兩個(gè)對(duì)象: Memo1 和 Memo2. 我能否在 Memo1 的腳本中調(diào)用 Memo2 的屬性和方法?
A: 當(dāng)然, 例如,你可以這樣做: 對(duì)象名.屬性名.
Q: 在腳本中,我可以使用對(duì)象的哪些屬性?
A: 幾乎所有你能在對(duì)象瀏覽器中看到的屬性。例如,可以使用 Font.Name, Font.Size等來(lái)存取
字體屬性。
—————- 其它問(wèn)題 ——————————————–
Q: 怎樣改變多頁(yè)報(bào)表中某一頁(yè)的順序?
A: 拖動(dòng)頁(yè)標(biāo)簽到目的位置。
Q: 我想查看所有的字段及變量,我想在報(bào)表中使用列表來(lái)實(shí)現(xiàn)它?
A: 設(shè)置 TfrReport.MixVariablesAndDBFields := True.現(xiàn)在,所有的數(shù)據(jù)字段及變量可在“插
入數(shù)據(jù)字段”對(duì)話框中可存取了。
Q: 我不想顯示導(dǎo)入選項(xiàng)對(duì)話框?
A: 在導(dǎo)入組件(比如,TfrTextExport)中設(shè)置所有必需的選項(xiàng),然后通過(guò)設(shè)置ShowDialog屬性為
False來(lái)關(guān)閉此對(duì)話框。
Q: 為什么 TotalPages 變量不起作用? 它總是返回 0.
A: 在你的報(bào)表中設(shè)置 Two-pass 選項(xiàng). 要設(shè)置它,你需要在報(bào)表設(shè)計(jì)器的“文件”菜單中,打開(kāi)
“報(bào)表選項(xiàng)”對(duì)話框。
Q: 我用BLOB字段來(lái)存儲(chǔ)我的報(bào)表。當(dāng)我運(yùn)行報(bào)表設(shè)計(jì)器時(shí),它顯示我的報(bào)表未命名?
A: 在運(yùn)行報(bào)表設(shè)計(jì)器前,這樣做:
frReport1.FileName := ‘Name of my report’;
Q: 我想在重新定義報(bào)表設(shè)計(jì)器中的“打開(kāi)”及“保存”按鈕的功能?
A: 查看 TfrDesigner 組件. 它有幾個(gè)必需的事件: OnLoadReport 和
OnSaveReport. 這里有一小段代碼例子:
procedure TForm1.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;
procedure TForm1.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 中, 我可以寫(xiě)這樣的代碼: QRLabel1.Caption := ’Some text’. 我可以用FR這樣做
嗎?
A: FR 對(duì)象并不是一個(gè)組件 (這并不像 QR, RB). 但使用 TfrReport.FindObject 方法可以通過(guò)
對(duì)象名稱找到該對(duì)象。
var
t: TfrMemoView;
begin
t := TfrMemoView(frReport1.FindObject(’Memo1’));
if t <> nil then
t.Memo.Text := ’FastReport’;
end;
Q: 我想在用戶預(yù)覽(TfrPreview組件)中自定義熱鍵?
A: 這個(gè)組件有個(gè)窗口: Tform 屬性. 將自定義句柄指定到 Window.OnKeyDown 屬性.
Q: Fast Report 2.4 不能裝載 FreeReport 2.21 文件?
A: 這僅需要使用16進(jìn)制數(shù)改變報(bào)表文件的第一字節(jié),然后在源代碼中修改下面的部分。在這些修
改之后, 裝載報(bào)表并保存它. 最后,返回到源代碼處.
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: 怎樣不在打印預(yù)覽中打印報(bào)表?
A: 這里有一段代碼:
frReport1.PrepareReport;
frReport1.PrintPreparedReport(”, 1, True, frAll);
或
frReport1.PrintPreparedReportDlg;
Q: 我想在報(bào)表中旋轉(zhuǎn)圖片。問(wèn)題是這張圖片是由我的應(yīng)用程序生成的。是否有方法可以在打印前
將這幅圖片裝載到報(bào)表中?
A: 使用 TfrReport.OnBeforePrint 事件:
if View.Name = ‘Picture1′ then
TfrPictureView(View).Picture.LoadFromFile(…) 或
.Assign 或
.你所想要做的任何事情
FastReport?套打全攻略
//以設(shè)計(jì)套打行為6行為例進(jìn)行說(shuō)明
一、定義變量
TaoDa?? 0 是套打 1 不套打
cPage?? 系統(tǒng)變量? 頁(yè)#
caPage? 系統(tǒng)變量? 總頁(yè)數(shù)
二、TfrPage.OnBeforePrint事件中寫(xiě)
{
if TaoDa = ‘0′ then
begin
title.visible:=false;?? //不用打印的設(shè)置Visible為False;
danweiv.frametyp := 0;? //只打印數(shù)據(jù)的不需要打印邊框的設(shè)置 frametyp 為 0;
…
end;
i := 0 ;?? //定義一個(gè)變量并進(jìn)行初始化。
}
二、主項(xiàng)數(shù)據(jù).OnBeforePrint事件中寫(xiě)
{
if TaoDa = ‘0′ then
begin
i := i + 1;
bm.memo := i;
if (i > 5 ) then
if ((i-1) mod 6 ) = 0 then newpage;
end;
}
三、主項(xiàng)腳.OnBeforePrint事件中寫(xiě)
{
j := i mod 6;
if j <> 0 then
begin
for k := j to 5 do
begin
ShowBand(Child1);?? //Child1是子的名稱?顯示空白行
end;
end;
}
四、欄目腳.OnBeforePrint事件中寫(xiě)
{
if cpage <> capage then
begin
shi.memo := ”;? //十
bai.memo := ”;? //百
qian.memo := ”; //千
wan.memeo := ”; //萬(wàn)
end
else begin
shi.memo := v1;
bai.memo := v2;
qian.memo := v3;
wan.memo := v4;
end;
}
這段代碼是用來(lái)控制在有多頁(yè)情況下,在最后一頁(yè)上顯示總金額。
其中:v1,v2,v3,v4 是自定義變量。
報(bào)表結(jié)構(gòu)組成:
欄目頭?????????? //畫(huà)報(bào)表的標(biāo)頭
主項(xiàng)數(shù)據(jù)???????? //顯示的數(shù)據(jù),會(huì)與數(shù)據(jù)源進(jìn)行綁定
主項(xiàng)腳????? //什么也不用放,只用來(lái)控制? visible := false;
子?????????????? //畫(huà)出空白行顯示的組件
欄目腳?????????? //顯示總的金額、數(shù)量
頁(yè)腳???????????? //顯示頁(yè)數(shù)
調(diào)用方法:
frReportA.LoadFromFile(s);?? s 是文件
frReportA.Dictionary.Variables['taoda']:=’1′;
進(jìn)行查詢
打印:
frReportA.PrepareReport;
frreportA.PrintPreparedReport(”,1,true,frall);
預(yù)覽:
frReportA.ShowReport;
FastReport打印CxGrid數(shù)據(jù)
用慣了FastReport,就不愿意再使用其他的Print Component。用FastReport打印CxGrid Filter后的數(shù)據(jù),網(wǎng)上一直沒(méi)有很好的辦法和例程。看到有將CxGrid的Fileter Text取出后再賦給DataSet的說(shuō)明,沒(méi)有具體去試驗(yàn),太麻煩。如此著名的Component肯定有解決此問(wèn)題的方法。于是今天到Dev Express英文站點(diǎn)去瀏覽了一番,在該站上搜索了一下,居然出來(lái)N多此問(wèn)題的提問(wèn)者,看了幾個(gè)這類的問(wèn)題后,終于解決了。
解決此問(wèn)題可以使用以下方法:
1、將View的datacontroller.filter.autodatasetfilter屬性設(shè)為True。
此方法需要DataSet支持才能設(shè)置。
2、是在FastReport的frDBDataSet的CheckEof Event里寫(xiě)如下代碼:
EOF := frUserDataset1.RecNo >= Grid.ViewData.RecordCount;
在frReport的GetValue Event里寫(xiě)代碼:
if ParName=’Field1′ then
ParValue := Grid.ViewData.Records[frDataset1.RecNo].Values[2]);
此代碼也可這樣寫(xiě):
ParValue :=Grid.ViewData.Records[frDataset1.RecNo].Values[View.GetColumnByFieldName(ParName).Index]);
ReportMachine
1.如何使用代碼指定打印機(jī)?
RMReport1.LoadFromFile(’Untitled.rmf’);
rmreport1.PrinterName:=’/192.168.10.1HP LaserJet 1022′;
轉(zhuǎn)自:http://kennyluo.iteye.com/blog/1557123
轉(zhuǎn)載于:https://www.cnblogs.com/ITGirl00/p/3591561.html
總結(jié)
以上是生活随笔為你收集整理的FastReport问题整理(转)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 网络设备的注册与初始化
- 下一篇: UIImageView 圆角