Fastreport使用经验
[FORMATDATETIME('mm-dd', [IBqryShipDate."CLOSEDATE"])]
[FORMATDATETIME('mm/dd/yy', [IbqryOrderForm."ORDERDATE"])]
金额总计:[FORMATFLOAT('>####0.00', [TotalAmount])]
[FORMATFLOAT('#,##0.00',[qryDetail."JinE"])]
订单数量:[COUNT(band1)]
数量合计:[SUM([IBqryShipDate."QUANTITY"])]
婚否:[IF([IbqryPersonal."ISMARRIAGED"]=1, '是', '否')]
[IF([qryData."CLOSEDATE"]=0,'',[FORMATDATETIME('yyyy-mm-dd', [qryData."CLOSEDATE"])])]
[IF([qryCustoms."EXPORTDATE"]=0,'',[DateEngStyle([qryCustoms."EXPORTDATE"])])]
[IF([qryPrints."TOTAL1"]=0,'',[qryPrints."TOTAL1"])]
[IF([qryPrint."CURDATE"]=0,'',[FORMATDATETIME('mm-dd',[qryPrint."CURDATE"])])]
[IF([qryPrint."STYPE"]='0', [Ban], [Huo])]
[Copy([qryData."WASHMETHOD"],1,8)]
while iCount < 4 do
  begin
    ShowBand(Child1);
    iCount := iCount + 1;
  end; 
 
  begin
  if FreeSpace < SubBand1.Height then
    NewPage
  else
  begin   
    iTotal10 := iTotal10 + 1;
    if iTotal10 > 10 then
    NewPage; 
  end;
end
在Delphi程序中访问报表对象
最基本的方法就是frxReport1.FindObject。然后把返回的对象强制转换成它的类型,当然,在报表中必须真的有这么个东东。如改变一个Tfrxmemoview的内容,可以这样写TfrxMemoView(frxReport1.FindObject('memo1')).Text:='jade';
还可以用TfrxReportPage的FindBand方法,这个方法的参数是Band类,如报表抬头就可以直接使用这个方法,因为抬头一个页中只有一个,如果有多个同样的类。则不能使用这种方法。如果要使用TfrxreportPage,一般可以用这样的代码
TfrxReportPage(frxReport1.Pages[0])。当然,如果你的这个页是对话框型的,则不行了。但一般都是报表型的。
******使用上下标
在Fastreport中使用上下标是很简单的,只要用一个Tfrxmemoview,把AllowHTMLTags属性设为真,就可以使用网页标签来实现上下标了,如
12<sup>2</sup>与24<sub>3</sub>。就分别是2为上标,3为下标。
******打印页码
打印页码是很简单的,只要加入一些常量即可,如打印第几页共几页就可以使用
第[Page#]页  共[TotalPages#]页
这里要注意的一点是如果想正确显示总页数,必须选中二次报表。
******动态建立变量及变量组
建立变量组名
delphi trunc函数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,初始值)
******共用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一样使用共用的报表组件了。
******加入自定义函数
Fastreport可以自己加入需要的函数,来实现特定的功能。过程就是:
1)添加函数到报表中。
frxreport1.AddFunction('完整的函数声明');
如有一个自定义函数,为GetName(Old:String):String;这个函数通过数据集的一个字段,得到另一个返回值。
则语句为:frxreport1.AddFunction('Function GetName(Old:String):String;');
2)脚本中使用函数。
在脚本中或报表中使用自定义函数,就像使用其它Fastreport内置函数一样。
3)程序中处理函数。
使用函数是通过frxreport1的OnUserFunction函数来实现的。
OnUserFunction的声明如下:Function(const MethodName: String;var Params: Variant): Variant;
比如上面的函数,首先要有一个函数,这个函数是GetName的实现部分。如有一个在程序中实现的函数。
function RealGetName(Old:String):String;这个函数名是无所谓的,也可以是GetName。
在OnUserFunction的事件处理中有如下代码即可完成自定义函数在报表中的使用。
if CompareText(MethodName,'GetName')=0 then Result:=RealGetName(VarToStr(Params[0]));
我一般都是使用CompareText来比较函数名,因为我发现二个版本的Fastreport,一个是MethodName全部自动变成了小写,一个是全部自动变成了大写,所以干脆用CompareText来比较,肯定不会出错。
如果有多个参数,则依次传递Params[0],Params[1]即可,要保持顺序一致。
这里要注意一点,如果参数为指针,则不能直接使用Pointer(Integer(Params[0]))。因为实际传递过来的是指针的整数值,可以使用Pointer(StrToInt(VarToStr(Params[0])))。
******使用脚本,脚本中使用变量
很多时候,我们希望把对报表的控制放到报表的脚本中,通常我这样做有二个原因:
1)能够根据字段内容的变化而使用不同的设置,因为如果想在程序中实现这样功能,就不得
不用自定义函数,函数的实现要放到程序中,函数
可能需要传递很多参数,效率低下。
2)把不同报表的控制放到脚本中,可以实现报表的模块化,程序只是简单的设置数据集的关系,并加载硬盘上的报表文件,不同报表的不同实
现方式,显示方式,均放到报表文件中,程序简洁,易维护,易升级。
当然,这样的缺点就是程序中加载报表时的数据集别名必须与设计报表时的别名一致。
脚本的使用与通常程序的使用并没有太多的区别,就是像正常的程序那样引用控件的名称即可。但注意对变量的使用,需要把变量名或表达式用<>括起来。
******在脚本中根据字段名改变Tfrxmemoview的内容
假设有数据表“用户”,字段ID为用户标识,Name为用户名,打印时要求,如果用户名为空,则打印“无用户名”,否则打印出“用户名:实际的用户”,则可以在ID的Tfrxmemoview控件的OnAfterData事件中写如下脚本。
if <frxDBDataSet1."Name">='' then
Memo2.Text:='无用户名'
else
Memo2.Text:='用户名:[frxDBDataSet1."Name"]'
Memo2是放置用户名称数据的Tfrxmemoview控件。
这里注意,要在脚本中访问变量需要把变量用<>包括起来。
******实现连续打印
很多人认为Fr不能实现连续打印,以为只能通过自己写函数调用打印函数来实现连续打印,实际上,Fr可以轻易的实现连续打印,同时,实现时又是非常简单,你甚至可以在你的程序的打印设置中简单的让客户选择是否连续打印,其它都可以保持不变。
function PelsTomm(Pels:Extended):Extended;
begin     

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。

发表评论