在fastreport腳本可以寫函數,當有許多windows自動api不能用,試着利用fastreport的AddFunction,OnUserFunction實現。
(網上搜)Fastreport可以自己加入需要的函數,來實現特定的功能。過程就是:
1)添加函數到報表中。
frxreport1.AddFunction('完整的函數聲明');
如有一個自定義函數,為GetName(Old:String):String;這個函數通過數據集的一個字段,得到另一個返回值。
則語句為:frxreport1.AddFunction('Function GetName(Old:String):String;');
2)腳本中使用函數。
在腳本中或報表中使用自定義函數,就像使用其它Fastreport內置函數一樣。
3)程序中處理函數。
使用函數是通過frxreport1的OnUserFunction函數來實現的。
OnUserFunction的聲明如下:Function(constMet
我:
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])))。
實例代碼:
unit Unit3; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Data.DB, Datasnap.DBClient, frxClass, frxDBSet, frxDesgn; type TForm3 = class(TForm) Button1: TButton; Button2: TButton; frxDesigner1: TfrxDesigner; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } dt1: TClientDataSet; ds1: TDataSource; frxDBDataset1: TfrxDBDataset; dt2: TClientDataSet; ds2: TDataSource; frxDBDataset2: TfrxDBDataset; frxReport: TfrxReport; Function UserFunction(const MethodName: String;var Params: Variant): Variant; public { Public declarations } end; var Form3: TForm3; implementation {$R *.dfm} //簡繁體裝換函數 function Cn2Big(CnStr: string): string; var Len: Integer; begin Len := Length(CnStr); SetLength(Result, Len); LCMapString(GetUserDefaultLCID, LCMAP_TRADITIONAL_CHINESE, PChar(CnStr), Len, PChar(Result), Len); end; function BIG2cn(bigStr: string): string; var Len: Integer; begin Len := Length(bigStr); SetLength(Result, Len); LCMapString(GetUserDefaultLCID, LCMAP_SIMPLIFIED_CHINESE, PChar(bigStr), Len, PChar(Result), Len); end; Function TForm3.UserFunction(const MethodName: String;var Params: Variant): Variant; begin if CompareText(MethodName,'Cn2Big')=0 then Result:=Cn2Big(VarToStr(Params[0])) else if CompareText(MethodName,'BIG2cn')=0 then Result:=BIG2cn(VarToStr(Params[0])); end; procedure TForm3.Button1Click(Sender: TObject); begin frxReport.DesignReport(); end; procedure TForm3.Button2Click(Sender: TObject); var OpenTemplate : TOpenDialog; begin try OpenTemplate := TOpenDialog.Create(nil); OpenTemplate.DefaultExt := 'fr3'; OpenTemplate.Title := '預覽模板'; if not OpenTemplate.Execute then exit; if not fileexists(OpenTemplate.FileName) then exit; self.frxReport.LoadFromFile(OpenTemplate.FileName); if assigned(OpenTemplate) then freeandnil(OpenTemplate); frxreport.PrepareReport(true); frxreport.ShowReport; except on e : exception do showmessage(e.Message); end; end; procedure TForm3.FormCreate(Sender: TObject); var i, j : integer; begin dt1 := TClientDataSet.Create(nil); ds1 := TDataSource.Create(nil); frxDBDataset1 := TfrxDBDataset.Create(nil); frxDBDataset1.UserName := '學生表'; dt2 := TClientDataSet.Create(nil); ds2 := TDataSource.Create(nil); frxDBDataset2 := TfrxDBDataset.Create(nil); frxDBDataset2.UserName := '課程表'; dt1.FieldDefs.Add('sid',ftInteger); dt1.FieldDefs.Add('sname',ftString,1000); dt2.FieldDefs.Add('sid',ftInteger); dt2.FieldDefs.Add('cid',ftInteger); dt2.FieldDefs.Add('cname',ftString,1000); ds1.DataSet := dt1; frxDBDataset1.DataSource := ds1; ds2.DataSet := dt2; frxDBDataset2.DataSource := ds2; dt2.MasterSource := ds1; dt2.MasterFields := 'sid'; dt2.IndexFieldNames := 'sid'; frxReport := TfrxReport.Create(nil); frxReport.DataSets.Add(frxDBDataset1); frxReport.DataSets.Add(frxDBDataset2); frxReport.AddFunction('function Cn2Big(CnStr: string): string;','用戶自定義函數','簡體裝換繁體'); frxReport.AddFunction('function BIG2cn(bigStr: string): string;','用戶自定義函數','繁體裝換簡體'); frxReport.OnUserFunction := UserFunction; dt1.CreateDataSet; dt2.CreateDataSet; for i := 1 to 3 do begin dt1.Append; dt1.FieldByName('sid').AsInteger := i; dt1.FieldByName('sname').AsString := '學生' + inttostr(i); dt1.Post; for j := 1 to 3 do begin dt2.Append; dt2.FieldByName('sid').AsInteger := i; dt2.FieldByName('sid').AsInteger := i; dt2.FieldByName('cname').AsString := '學生' + inttostr(i) + '課程' + inttostr(j); dt2.Post; end; end; end; procedure TForm3.FormDestroy(Sender: TObject); begin frxReport.Destroy; frxDBDataset1.Destroy; frxDBDataset2.Destroy; ds2.Destroy; ds1.Destroy; dt2.Destroy; dt1.Destroy; end; end.


