zoukankan      html  css  js  c++  java
  • FastReport中如何加入自定义函数

    在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.
    

    效果:
    213102_qmub_2862751
    213146_qds9_2862751

  • 相关阅读:
    BP神经网络的数学原理及其算法实现
    机器学习必知的10大算法
    支持向量机通俗导论(理解SVM的三层境界)
    svm算法 最通俗易懂讲解
    read/write/fsync与fread/fwrite/fflush的关系和区别
    ubuntu16.04编译QT5.6所依赖的库
    Linux下的tar压缩解压缩命令详解
    Ubuntu16下编译linux内核,报"mkimage" command not found错的解决
    Git之(一)Git是什么[转]
    mac上完整卸载删除:android studio方案
  • 原文地址:https://www.cnblogs.com/iyulang/p/6831304.html
Copyright © 2011-2022 走看看