Rave报表介绍之二: 可视报表设计器
可视报表设计器
Rave有自己的可视报表设计器,以自己的文件格式保存报表。这有一些优势,你可以把报表
独立于应用程序之外,可独立进行升级,甚至可以通过网络进行更新,或者使用Nevrona的
Rave Report Server。当然,你也可以把报表保存为标准的DFM文件格式。
为了启动可视报表设计器,防止一个TRvProject部件在form上,这个TRvProject部件将是你
的应用程序和你即将要创建的报表的联系。 如果需要,可加一个TRvSystem部件到窗体上,
通过设定RvProject的Engine属性与它挂接。RvSystem部件是作为一个通用的报告系统配置
部件:可通过它设置将要使用的打印机,边界,页数等等。为了开始一个新的报表项目,双
击RvProject部件,或者通过敏感菜单选择"Rave Visual Designer..." 。
一个Rave项目文件将可能由多个报表组成。通过全局页面(Global Pages)可以保存一些报表
间共享的品项。
如果一个属性从缺省值改变为特定值,在属性编辑器中会显示成粗体。
当在可视报表设计器设计好报表后,返回到delphi的IDE中,改变RvProject部件的
ProjectFile属性为你刚才完成并保存的报表文件名。为了运行报表,加一个调用RvProject
对象的Execute方法的过程即可。
如果我们设计的报表项目中只有一个报表,我们仅仅调用RvProject.Execute即可。如果我
们的报表项目中有多个报表,我们不得不在调用Execute前,调用SelectReport来选择特定
的报表,或者调用直接调用ExecuteReport方法。
与报表项目进行交互
参数(Parameters)
参数可以存在于报表项目,报表,报表页面这三个地方,可通过对应对象的parameters属性
进行设定。
你仅能通过报表项目的对象树来选择报表项目和特定的报表。对于报表页面可以通过报表项
目的对象树或页面设计的标题来选择。
参数可通过DataText部件来输出。在页面上加一个DataText组件,打开属性编辑器的
DataField属性。你能在此选择项目变量、参数、后初始化变量。
procedure TFormMain.btnExecuteClick(Sender: TObject);
begin
RvProject.Open; //打开报表项目
RvProject.SelectReport('ParametrizedReport',False); //通过报表名称选择特定的报表
RvProject.SetParam('Name','Leonel'); //给特定参数设定值
RvProject.Execute; //执行报表
RvProject.Close; //关闭报表项目
end;
后初始化变量
后初始化变量是只有在报表已经被打印了才知道值的变量。比如页的总数(TotalPages)就是
后初始化变量,其使用方式类同于一般变量,也是通过DataTexts来打印的。
全局页面
如果有些报表的部分在两个或更多报表中是相同的公用的,你能把这些放置到全局页面中。
比如公司名称、日期和时间、当前页号和总页数等。我们需要每个报表都有这些东西,我们
应该怎么做?
首先,加一个全局页面到报表项目中。在这个页面中,加一个section组件。Sections组件
用于组件的逻辑分组。
在section组件中加入我们想要共享的东西。
在特定报表的特定页,增加另一个section组件。设定该组件的Mirror属性为前面那个全局
页面中的Section组件。你能看见全局页面中的Section组件及其包含的对象均被映射进来
了。对于其它特定的页面,同法炮制,现在多个页面就可以共享一些组件了。
条件打印
有时我们会根据特定的条件打印报表的特定部分。Rave对此提供了强劲的支持。我们可以根
据字段值和参数的条件映射一些sections 。
在新的一个页面中创建一个参数HeaderKind。 它可能的值为H0 (无页头), H1(第一种页
头), H2 (第二种页头)。在全局页面中增加一个新的section组件,它具有第二种页头风格。
返回到ConditionalReport报告Page1的页面,加一个DataMirrorSection部件,设定它的
DataField字段为Param.HeaderKind。打开它的DataMirrors属性编辑器,增加两个Data
Mirrors: 如果值是H1,将打印第一种页头;值是H2, 将打印第二种页头;因为值为H0并不匹
配任何mirrors,将不打印页头。
procedure TFormMain.btnExecuteClick(Sender: TObject);
begin
RvProject.Open; //打开报表项目
RvProject.SelectReport(cmbReports.Text,False); //通过报表名称选择特定的报表
case cmbReports.ItemIndex of
1: RvProject.SetParam('Name',edName.Text); //给特定参数设定值
2: RvProject.SetParam('HeaderKind',Format('H%d',[cmbHeaderKind.ItemIndex])); //
给特定参数设定值
end;
RvProject.Execute; //执行报表
RvProject.Close; //关闭报表项目
end;
镶嵌报表项目文件到应用EXE文件中
通常,当你发布应用程序时,你必须同时包括你的报表项目文件。如果你让报表项目文件成
为一个独立文件,你就可以采用简单方式对其更新而不需要重新编译你的应用程序。如果你
想把报表项目文件包含在你的应用程序的EXE中,也是很简单的,你需要:设定RvProject组
件的StoreRAV属性。你通过Load一个报表项目文件把它包含在DFM中,通过Save可以提取出先
前的一个报表项目文件,通过Clear可以删除镶嵌的报表项目文件。当报表项目文件被装载
进应用程序的EXE中后,你就不再需要同时把报表项目文件打包进发布的应用程序了!
结论
我们学习了如何使用可视报表设计器,以及相应的一些提示。
2004-3-24 8:15
SCYANGYU
等级: 论坛版主
贴子:301
积分:0
园币:1000
注册:2004-1-23
第 2 楼
Introduction to Rave Reports - Part II: Visual Designer
In the Part I of this document. you have seen how the Code Based engine of Rave
Reports works. Now we are going to explore the Visual Designer.
The Visual Designer
If you are used to work with Quick Reports, the default reporting engine
included in the previous versions of Delphi, you created your reports using
Delphi's own form designer, and they were save in the DFM, included as resources
in your executable. Rave works a bit diferently in this aspect: it has it's own
report designer, and saves the report using it's own file format. This has some
advantages, including the fact that your reports can be made "standalone", and
be used or updated independently of your application, or even made available in
a Intranet or in the Internet, using Nevrona's Rave Report Server. Of course,
you can still have it saved in a form's DFM.
To get started with the Rave Visual Designer, drop a TRvProject in a form. This
will be the link from your application to the reports you are developing. If you
want, you can add a TRvSystem and link your RvProject to it, through it's Engine
property. The RvSystem is the object responsible for the general configuration
of the reports: the printer that is going to be used, the margins, the number of
pages, and so on. To start a new project, double click the RvProject you added
to the form, or select "Rave Visual Designer..." from its context menu. This is
the interface that you will be working on:
The interface is simple, and you might be familiar with some parts of it from
Delphi's IDE. On the top there's the menu, the toolbar, and the component
pallete that contain the components that will be used in the reports. In the
left there's the Object Inpector, which will be used to adjust the properties of
the components of the report. In the middle there's the Page Designer or the
Event Editor, and in the left there's the very usefull Project Treeview. For a
quick overview of the components in the pallete, you can go to Nevrona's Visual
Designer page.
A Rave Project File can have one or more reports. That way you can keep common
items between them in a single location, called Global Pages. If you expand the
Report Library node of the Project Treeview, you can see that right now you are
working on Report1. Clicking on it, its properties will show on the Inspector.
Let's change it's name and call it SimpleReport. Next, go to the Standard tab on
the Component Pallete, and pick a Text component and add it to the page. Change
its text property, and adjust its size and position. Here's how mine looked
like:
As you can see, the properties that were changed from the default values are
shown in bold. In this case, I changed the Font, Text and Truncate properties.
By default it does not highlight Name, Pos and Size changes. If you'd like to
see them, right click the Inspector and uncheck "Exclude Name, Size and Pos
changes" in the context menu.
You might have also noticed that Rave does not have an auto size property. You
can use the Truncate property to have that effect: if truncate is false, the
design time size will have no effect.
You can see the result of this simple report right on the designer: Press F9 or
use File/Execute Report to run it. Now let's do it in our application. Save your
project and return to Delphi. Change to ProjectFile property of RvProject to
point to the file you just saved. To run the report, add a call to the Execute
method of the RvProject object in a button click, for example.
RvProject.Execute will only work for now because we only have one report in this
project. If we had multiple reports, we'd have to call SelectReport to choose
one before calling Execute, or calling ExecuteReport directly.
Here's the output:
Tip: If you Close and Open your project before executing, you won't need to to
recompile your application or restart it to see the changes you just made in the
designer.
Interacting with the Project
If you worked with Quick Reports, you might be used to manipulating the objects
in runtime, changing their Position, Text and Visibility. After all, they were
just TObjects! While this is possible with Rave, and I'll cover it in a later
article, it's a little harder than it was with QR. But don't worry, Rave
provides a different answer to this kind of problems.
Parameters
If you can use parameters in your reports. They can be defined using the
parameters property of either the Project, a Report or a Page. Parameters can be
defined in either of these places, they are just in multiple places for easier
access.
You can only select the Project and a Report through the Project Treeview. A
page, however, can be selected using the Project Treeview or clicking on it's
title above the page designer.
Among other uses, you can print parameters. So, for instance, if the title of
your report can be user-defined, you could pass it from your application into
the report as a parameter.
Let's add a new report to this project to see how parameters work. To do that,
click the fourth button on the toolbar or choose File/New Report. Call it
ParametrizedReport, changing its name through the object inspector. This report
is going to be very similar to the first one, except the text is going to be
user-defined.
Now we need to define the parameter that is going to be printed. To do that,
still having the report as the selected object, open the property editor the the
parameters property. There should be listed all parameters of this report, each
on a separate line. Add a parameter called Name, like this:
Parameters can be printed using a DataText component, available in the Report
tab of the component pallete. Add a DataText to the page, and open the property
editor of the DataField property. There you can choose which field is going to
be printed, when working with DataAware reports (which will be covered on Part
III of these series). You can also choose Project Variables, Parameters and
Post-Initialize Variables from there.
So choose the parameter added previously from the Parameters drop-down combo and
press the Insert Parameter button. The data text expression is now Param.Name
(we are going to change that a little later). Press OK and try to execute the
report, as before. Nothing is printed, since the parameter has not been set.
We need to set this parameter before printing. Don't forget to save your
changes, and return to Delphi, adding a call to SelectReport before Execute, so
we can see the right report. Before executing, though, we need to set the
parameter we added. That is made using RvProject's SetParam method. This is how
my code looks like right now:
procedure TFormMain.btnExecuteClick(Sender: TObject);
begin
RvProject.Open;
RvProject.SelectReport('ParametrizedReport',False);
RvProject.SetParam('Name','Leonel');
RvProject.Execute;
RvProject.Close;
end;
Now, when we execute the report, we are going to see the string we set as a
parameter printed.
Tip: You can use RvProject.GetReportList to get a list of avaible projects, and
add them to a ComboBox, or a RadioGroup, for example. That makes selecting the
report easier.
But this is too simple. Let's change the expression that is going to be printed.
Return to Rave Designer and open the property editor for the DataText we added.
You can add any text you want, combining text, fields, parameters and variables.
I changed it to this:
Here's the result:
Post-Initialize Variables
Post-Initialize Variables, or simply PI Vars, are variables whose value is only
known after the report has already been printed. It may sound strange, at first,
but think about the number of pages of a report, for example. We can only know
it's value after the report is ready. Actually TotalPages is a report variable
that acts like a PI var, and can easily be printed using DataTexts as we did
with Parameters.
Global Pages
When you have parts of reports that are common to two or more reports, you can
put these in a global page. Let's supose we have a header with our company name,
the date and time that report is being printed, the current page and the number
of pages of that report. We want that header to be in every report. How can we
do it?
First, add a global page to the project, using File/New Global Page, or the
Toolbar shortcut. In that page, add a section component, available in the
standard tab of the component pallete.
Sections are logical groupings of components. they can be used to group
component so they can be easily moved around the report, or as containers for
Mirrors, as we are doing right now.
Inside that section we add what we want to be printed. In this case, a few
DataTexts. My header looks like this:
Hint: Instead of changing the font property of several components to the same
font, link them to a FontMaster component, available in the standard tab, and
set the font on it. That way is easier to change the font in the future, in case
it's needed.
Now add another section to the Page1 of SimpleReport. Set its Mirror property to
GlobalPage1.Section1. You will see a copy of the header you created in the
global page. Do the same thing to ParametrizedReport. Now both reports share the
same header. Here how it looks like for me:
Conditional Printing
Sometimes we need to print certain parts of a reporting depending of some
conditions. Rave has a very powerful way of dealing with this. We can
conditionally mirror sections depending on field values or parameters. Let's
create a new Report, calling it a ConditionalReport.
Let's pretend that this new report is a trick one. The user can choose the
header that is going to be printed, from two different kinds of headers. He can
also choose for the report to be printed without a header. We are going to use a
parameter to tell the report what kind of header is going to be printed, and a
DataMirrorSection to select the proper header at runtime.
First, add a parameter to this new report called HeaderKind. Let's assume that
it will have the values H0 (for no header), H1 (for the first header), H2 (for
the second kind of header). Now add a new section to the global page (you can
reach it through the Project Treeview), with the second kind of header layout. I
created a header similar to the first one, changing the font title and adding a
border around the values. It looks like this:
Now return to the Page1 of ConditionalReport, and add a DataMirrorSection,
available at the Report tab of the component pallete. Go to its DataField
property editor, and set Param.HeaderKind as the expression. Now go to the
DataMirrors property editor, and add two Data Mirrors: if the value is H1, it
should point to the first header, H2, to the second. Since H0 does not match any
mirrors, nothing will be printed. It should look like this:
Notice that I gave more meaningful names to each of the sections earlier.
Hint: You can use the OnMirrorvalue event of the DataMirrorSection to work on
ranges of values.
Now return to Delphi and add the code to set the parameter according to the
user's choice. I added a ComboBox with the options and my code looks like this:
procedure TFormMain.btnExecuteClick(Sender: TObject);
begin
RvProject.Open;
RvProject.SelectReport(cmbReports.Text,False);
case cmbReports.ItemIndex of
1: RvProject.SetParam('Name',edName.Text);
2: RvProject.SetParam('HeaderKind',Format('H%d',[cmbHeaderKind.ItemIndex]));
end;
RvProject.Execute;
RvProject.Close;
end;
Now the proper header will be printed according to the user's choice.
Embedding the Project in the Executable
When you deploy your application, you must include you project file. You can
have it as a separated file, so you can update it in a easier way, only shipping
a new one, without recompiling your application, or include it in your
executable. It's easy to do that: open the property editor for the StoreRAV
property of RvProject. There you can press Load to include the file in the DFM,
Save to extract a previously saved file, and Clear to remove an embedded file.
When there's a file loaded in this property, you don't need to ship the project
file separately.
Conclusions
We've learned how to work on the Visual Designer, and seen a few tricks that
allow some flexible reports. You can find a project containing the sample
reports developed here on CodeCentral. On Part III we are going to learn how to
create DataAware reports, and operate with bands.
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, RpBase, RpSystem, RpDefine, RpRave, StdCtrls, ExtCtrls;
type
TFormMain = class(TForm)
RvProject: TRvProject;
RvSystem: TRvSystem;
btnExecute: TButton;
cmbReports: TComboBox;
cmbHeaderKind: TComboBox;
edName: TLabeledEdit;
procedure btnExecuteClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure cmbReportsChange(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
FormMain: TFormMain;
implementation
{$R *.dfm}
procedure TFormMain.btnExecuteClick(Sender: TObject);
begin
RvProject.Open;
RvProject.SelectReport(cmbReports.Text,False);
case cmbReports.ItemIndex of
1: RvProject.SetParam('Name',edName.Text);
2: RvProject.SetParam('HeaderKind',Format('H%d',[cmbHeaderKind.ItemIndex]));
end;
RvProject.Execute;
RvProject.Close;
end;
procedure TFormMain.FormCreate(Sender: TObject);
begin
cmbReports.Items.Clear;
RvProject.Open;
RvProject.GetReportList(cmbReports.Items, False);
cmbReports.ItemIndex := 0;
end;
procedure TFormMain.cmbReportsChange(Sender: TObject);
begin
edName.Enabled := cmbReports.ItemIndex = 1;
cmbHeaderKind.Enabled := cmbReports.ItemIndex = 2;
end;
end.