fastreport问题集 选自delphi园地 http://www.delphifans.com/infoview/article_401.html
---------------- 使用自定义函数 ----------------------------------------
q: 我怎样添加我的自定义函数?
a: 使用 tfrreport.onuserfunction 事件. 这里有一个简单的例子:
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;
然后,你就可以在报表(任何表达式或脚本)的任何地方使用 sumtostr 函数了。
q: 但是它仅仅能工作在一个tfrreport组件中。可我想在任何地方(在所有的tfrreport组件中)使用的我的自定义函数?
a: 使 onuserfunction event 句柄作为所有组件的公用句柄。如果你不能做到这一点,你需要创建函数库:
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;
要注册函数库,调用
frregisterfunctionlibrary(tmyfunctionlibrary);
要卸载函数库,调用
frunregisterfunctionlibrary(tmyfunctionlibrary);
q: 我怎样将我的函数添加到函数列表中 (用表达式生成器)?
a: 使用 fraddfunctiondesc 过程 (在fr_class 单元中):
fraddfunctiondesc(funclib, ‘sumtostr‘, ‘my functions‘,
‘sumtostr(<number>)/converts number to its verbal presentation.‘);
注意: "/" 符号是必须的! 它从它的描述中分隔函数语法。
funclib 被声明为你自己的函数库 (如果你不使用函数库可以将其设置为nil). 当函数库未注册时,所有它的函数将自动从函数列表中删除。
---------------- 使用变量 -------------------------------------
q: 我怎样编程实现填充变量列表(在数据词典中)?
a: 数据词典中的所有变量及分类都被存储在 tfrreport.dictionary.variables 中.
with frreport1.dictionary do
begin
// 创建分类(名称用空白)
variables[‘ new category‘] := ‘‘;
// 创建变量
variables[‘new variable‘] := ‘customerdata.customers."custno"‘;
variables[‘another variable‘] := ‘page#‘;
end;
q: 我定义了字符串变量:
with frreport1.dictionary do
variables[‘month‘] := ‘march‘;
但是当我运行报表是,出现了错误,为什么?
a: 因为 fastreport 假定数据词典中的字符串变量值是一个表达式,它需要分析、计算它。
可以使用其它的方法:
with frreport1.dictionary do
variables[‘month‘] := ‘‘‘‘ + ‘march‘ + ‘‘‘‘;
或者, 使用 frvariables 来传输固定数据到报表。
q: 我不想在数据词典中显示某些数据集?
a: 使用 tfrreport.dictionary.disableddatasets:
with frreport1.dictionary do
begin
// 关闭该数据集
disableddatasets.add(‘customerdata.bio‘);
// 或者, 关闭整个数据模块/窗体
disableddatasets.add(‘customerdata*‘);
end;
q: 我怎样将数据传送到报表?
a: 有几个方法可以实现它. 第一是使用全局对象 frvariables (在 fr_class 单元中被定义):
frvariables[‘my variable‘] := 10;
这段代码创建了一个名称为“my variable”,值为 10 的变量。这是最好的传输固定数据的报表的方法。
第二种方法是使用 tfrreport.ongetvalue 事件. 这可以使用这个方法来传送动态数据、记录等。
procedure tform1.frreport1getvalue(parname: string; var parvalue: variant);
begin
if parname = ‘myfield‘ then
parvalue := table1myfield.value;
end;
最后, 第三种方法是通过编程在数据词典中定义变量(可以参考以前的问题):
with frreport1.dictionary do
begin
variables[‘myvariable‘] := ‘customerdata.customers."custno"‘;
variables[‘another variable‘] := ‘10‘;
end;
q: 我能在报表和程序间传送数据吗?
a: 使用 frvariables 对象. 如果你在报表的任何对象的脚本中写入以下代码:
myvariable := 10
那么,在你的程序中,你可以使用以下代码来获取 myvariable 的值:
v := frvariables[‘myvariable‘];
---------------- 脚本 (fastreport pascal) ---------------------------------
q: band 中是否可以使用脚本?
a: 当然. 选择 band ,然后按 ctrl+enter 或在对象浏览器中选择 "onbeforeprint" 属性。
q: 报表页中是否可以使用脚本?
a: 当然. 选择页 (在空白处单击) ,然后在对象浏览器中选择 "onbeforeprint" 属性。如果该页是一个对话框窗体,那么这个属性就是 "onactivate".
q: 我有两个对象: memo1 和 memo2. 我能否在 memo1 的脚本中调用 memo2 的属性和方法?
a: 当然, 例如,你可以这样做: 对象名.属性名.
q: 在脚本中,我可以使用对象的哪些属性?
a: 几乎所有你能在对象浏览器中看到的属性。例如,可以使用 font.name, font.size等来存取字体属性。
---------------- 其它问题 --------------------------------------------
q: 怎样改变多页报表中某一页的顺序?
a: 拖动页标签到目的位置。
q: 我想查看所有的字段及变量,我想在报表中使用列表来实现它?
a: 设置 tfrreport.mixvariablesanddbfields := true.现在,所有的数据字段及变量可在“插入数据字段”对话框中可存取了。
q: 我不想显示导入选项对话框?
a: 在导入组件(比如,tfrtextexport)中设置所有必需的选项,然后通过设置showdialog属性为false来关闭此对话框。
q: 为什么 totalpages 变量不起作用? 它总是返回 0.