[转载]使用FastReport 3.0及以上版本创建动态报表的几个技巧

1.已经生成的报表保存到流中,再从流中取出
   TfrxReport.PreviewPages.SaveToStream(TStream);
   TfrxReport.PreviewPages.LoadFromStream(TStream);

2.把变量添加到报表中
   with frxReport1 do
   begin
     with Variables do
     begin
       Category:=Add;
       Category.Name := ' ' + '自定义变量1';       //注意!!第一个' '内是一个空格!!如果没有空格,不能正确添加分类
       with Add do Name := ' ' + '自定义变量2';    //更简化的格式
       AddVariable('自定义变量1', '变量11', QuotedStr('大写金额'));
       AddVariable('自定义变量1', '变量12', QuotedStr('大写金额'));
       AddVariable('自定义变量1', '变量13', QuotedStr('大写金额'));
       AddVariable('自定义变量2', '变量21', 1880);
       AddVariable('自定义变量2', '变量22', QuotedStr('大写金额'));
       AddVariable('自定义变量2', '变量23', QuotedStr('大写金额'));
     end;
   end;

3.动态添加数据集,要注意!!!!!
在取报表格式之前,应该先把数据集对象放好,这样才能保证在报表控件在取格式文件后,
安置报表对象时,可以拿到数据对象,如果操作顺序搞反了,则报表对象就无法
拿到数据对象,在预览数据时,就会产生“没有数据集”的错误了!!
var
   tmpDataSet: T数据集;
   DataSource: TDataSource;
   frxDBDataSet: TfrxDBDataset;
begin
   tmpDataSet:=T数据集.Create(Self);
   DataSource:=TDataSource.Create(Self);
   frxDBDataSet:=TfrxDBDataset.Create(Self);

   DataSource.DataSet:=tmpDataSet;
   frxDBDataSet.DataSource:=DataSource;
   //frxDBDataSet.DataSet:=tmpDataSet;     //这条语句与上一条都可用,我也不知道区别在哪
   frxDBDataSet.UserName:='数据项名称';     //好用在于可以用中文名
   frxReport1.DataSets.Add(frxDBDataSet);
-------------注意:在把报表格式LoadFromFile或LoadFromStream之前,必须完成上面这几条语句的程序!!!!

4.将报表设置数据保存到流中,只要设置TfrxDesigner.OnSaveReport就可以了,但不知道这东西怎么和Report联接起来的,只需要在界面上放一个控件就OK了,怪怪的,不过挺爽
  
5.自定义预览窗口
   通过引用frxPreview来建立继承类TfrxPreview,然后在继承的类中加入自己的特性,这样是最省事的了

6.处理顺序的信条(真理):假设报表模板是保存在数据库中的
a.必须在把报表模板提取出来前,把表对象注入数据中,否则在预览时就知错
b.必须在在把报表模板提取出来后,再把动态变量加到报表中,否则看不到变量存在
这两个顺序必须当信条来理解,至于什么原因,偶还没空看FastReport的源程序咧,嘿嘿~~,这两个处理机制可是偶经过了N多失败之后才发现的哦

7.添加自定义函数
a.建立自己的函数,可以是类的成员函数(要注意实例化类哟),也可以是全局函数
b.用TfrxReport.AddFunction把函数加到注册项中,注意,必须是函数的完整定义,比如,你的函数是:
    function MyFunction(Para0: Float): string;
 那么AddFunction格式应该这样:
    frxReport1.AddFunction('function MyFunction(Para0: Float): string','自定义函数','');
c.必须在TfrxReport.OnUserFunction中对函数的返回值进行处理,否则在报表中即使写的格式正确,也没有返回值,这是必须注意的

8.在自定义函数中使用报表中的对象
a.建立自定义函数

function TForm1.GetCrossObject(CrossObj: TfrxCustomCrossView): string;
begin
   // 取数据对象
   Result:='行数:'+IntToStr(CrossObj.Matrix.RowCount);
end;

b.注册函数,可以在Form1.Create时注册哦

   with frxReport1 do
   begin
     AddFunction('function GetCrossObject(CrossObj: TfrxCustomCrossView): String',
       '扩展函数', '');
   end;

c.必须在TfrxReport.OnUserFunction中对函数的返回值进行处理

function TForm1.frxReport1UserFunction(const MethodName: String;
   var Params: Variant): Variant;
begin
   if UpperCase(MethodName)=UpperCase('GetCrossObject') then
     Result:=GetCrossObject(TfrxCustomCrossView(Integer(Params[0])));   //类型转换才能编译通过哦  
end;

原文地址:https://www.cnblogs.com/eastson/p/1656726.html