三思同志 发表于2005-04-23 7:56 AM IP: 218.15.22.*
强大的报表设计器
Visual FoxPro 9.0 的报表设计器(1)
Micorsoft公司对新推出的Visual Foxpro 9报表设计器作了显著地改进,同时又与老版本的Visual Foxpro保持了向后兼容性,新版本的报表设计器是一个新旧版本的混合体。
在本文中,你将了解报表设计器对新的数据环境、报表保护、用户界面、对象布局与数据分组功能的增强。最后,你将了解Visual FoxPro 9报表设计器的一个最有用的增强功能:多条明细区带(multiple detail bands)。
报表设计被一个新增的“Xbase报表设计器”的工具代替。它提供了一些新的对话框,并且比以前的版本更方便使用。它还提供了一些旧版本报表设计中所没有的新特色。你可以通过改变一个名为“_REPORTBUILDER”的系统属性来决定使用哪种报表设计器,如下所示:
*--如果要使用新版本的报表设计器
_REPORTBUILDER = HOME() + 'ReportBuilder.app'
*--如果要使用旧版本的报表设计器_REPORTBUILDER = ''
报表输出引擎:与报表设计器一样,你可以控制是否选用新版本的报表输出引擎。但与报表设计器不同的是Visual FoxPro 9默认报表输出引擎为旧版本方式。主要是因为在新版本的输出引擎中使用了GDI+库,而老版本的输出引擎使用的是GDI库,使用老版本的输出引擎就可以让应用程序可以在不用版本的windows上显示出同样的输出效果。你可以用如下命令来切换你的输出引擎:
*--使用新版本的输出引擎
SET REPORTBEHAVIOR 90
*--使用旧版本的输出引擎
SET REPORTBEHAVIOR 80
在下文中我们假定使用的是新版本的报表设计器和输出引擎。
数据环境(DE)
Visual FoxPro 9的报表设计器能与让多个报表共享同一个数据环境。数据环境能够以类的方式保存,并在需要的时候被报表载入。这为那些需要制定通用报表数据环境的应用程序提供了方便。
要将数据环境保存为一个类,首先你要为报表定义一个数据环境,然后激活数据环境窗口,并在“File”主菜单中单击“Save As Class...”选项。
这样系统会弹出一个新的对话框(参见图1)。在这种情况下,Save单选按钮组中只有“DataEnvironment”处于允许状态。
图1. 使用“Save As Class”对话框指定要保存的类名以及所在的类库,并将指定报表的数据环境保存在这个类中。
Visual FoxPro 9.0 的报表设计器(2)
载入数据环境
除了能为报表定义数据环境以外,Visual FoxPro 9还能让你将某个报表的数据环境类载入到报表中去。“Report”菜单中的“Load Data Environment...”选项可以让你选择到底载入哪个数据环境。
通过报表设计器载入数据环境
如果要为一个新报表载入数据环境,那源数据环境的所有代码和成员变量都会复制到新报表中。这表明当你改变原来报表的数据环境后,并不会对新报表的数据环境产生任何影响。
图2显示了当你从“Report”主菜单中单击了“Load Data Environment...”选项后弹出的属性对话框。你可以在里面选择从哪个报表中复制源数据环境。
图2. 单击”Data Environment“选项卡,从中选择你要从哪个报表中复制数据环境
在上图中,单击“Copy from another report file”单选按钮,然后单击“Select...”按钮,这样会弹出一个打开对话框,你可以从中选择从哪个报表中复制。如果你选中了一个报表,那系统弹出一个确认框。
假如我们要将某个报表的数据环境复制到当前报表中去,Visual FoxPro 9会警告你将覆盖当前报表的数据环境,你必须选择“是”才能继续进行复制。这个提示功能可以防止由于你的误操作而将当前报表的数据环境覆盖掉。如果你选择“否”的话,那复制就会取消,如果选择的是“是”,那就会真正进行复制操作,并且当操作完成后,系统会出现另一个对话框,提示你操作完成。
现在数据环境已经复制成功了,你可以操控新的数据环境。但你要始终记得原报表数据环境的改变并不会对新的数据环境有任何影响。
从一个类中载入数据环境
当要从一个类中载入数据环境时,你必须要为新报表的数据环境写一些额外的代码,使得它能够动态地绑定源数据环境,并且初始化它的一个实例。这意味着如果从类中载入数据环境时,对源数据环境做的所有改动会影响到所有使用它的报表。
你同样可以用图2所示的报表属性对话框来完成这个效果,先单击“Link to a visual DE class”单选按钮,然后从系统弹出的打开对话框中选择你要载入的类库以及类名,当你点击确定按钮后,当前报表的数据环境将得到更新,并且系统会给出相应提示信息。
其实Visual FoxPro自动为数据环境的如下5个方法中加入了一些代码:Init()、BeforeOpentables()、AfterCloseTables()、Destroy()和Error()。有些方法中加入的代码非常简单,仅仅是一个DODEFAULT()命令,这个命令不执行任何操作。其原因是BindEvents()方法必须保证数据环境的这5个方法中的代码行数超过一行才能执行。你可以手动查看这些自动生成的代码,但我强烈建议你别去动这些代码。
Visual FoxPro 9.0 的报表设计器(3)
保护
如果要在Visual FoxPro 9使用报表设计器或者标签设计器,你可以为一个或多个的布局对象设置保护。这种特性可以让你的用户只能对报表进行有限的修改。
你可以为布局对象设置5种保护模式,域对象有着另外的保护选项。带区(Band)有两种保护模式可供你选择。并且你也可对报表本身设置不同的保护方式。
保护一个对象
要在报表设计器中为一个布局对象设置保护,通过激活此对象的属性对话框即可操作,你可通过用右键点击此对象,并在弹出的快捷菜单中选择相应的菜单项,或者直接双击此对象。图3显示了一个布局对象属性对话框的保护页,你可以为布局对象设置如下5种保护方式: • 对象不能被移动或改变大小。它使得用户不能在设计器中移动此布局对象,并且用户不能改变此对象的大小。
• 对象不能被修改。它使得用户不能修改此布局对象的属性。
• 对象不能被删除。 它使得用户不能删除此对象。
• 对象不能被选中。用户不可以选择此对象,当对象处于这种保护方式下时,用户不能移动它或改变它的大小,同样也不能修改或删除它。
• 对象在设计器中不可见。它使得此对象在报表设计中不可见,当对象处于这种保护方式下时,用户不能移动它或改变它的大小,同样也不能修改或删除它。
图3. 布局对象属性对话框中的保护页
这个对话框还有一个名为“Design-time caption”的输入项,它只对域对象有效。你可以在其中输入域对象的名称,这样在报表设计器中就不会显示域的表达示名称,而是显示你输入的名称。当域的表达式非常冗长时,这种显示方式可以使得报表设计器的用户界面更加友好。
保护一个带区(Band)
在报表设计器中要保护一个带区的话,请先激活此带区的属性对话框。你可以通过选择“Report”菜单中的“Edit Bands...”菜单项来打开这个属性对话框,也可以直接双击带区的灰色条。图4显示了一个带区属性对话框的保护页,你可以选择以下两种保护模式:
• 带区不可修改。这可以防止用户修改带区的属性。
• 带区不可改变大小。这可以防止用户改变带区的大小。
图4. 带区属性对话框中的保护页
保护报表本身
要为一个报表设定保护方式,要先激活此报表的属性对话框。你可以通过选择“Report”菜单中的“Properties”菜单项来打开这个属性框,也可以右键单击此报表来弹出这样一个菜单。图5显示了一个报表属性对话框的保护页
图5. 报表属性对话框中的保护页
这个对话框的上半部分可让你禁止用户使用属性对话框中的某些属性页。当你选择了相应的检查框后,报表属性对话框中的某些属性页会变得不可用。但“Protection”检查框总是保持选择状态而且不允许你对它进行改动。另外由于“Ruler/Grid”属性页无法保护,因此“Ruler/Grid”检查框也总处于禁止状态,这两个检查框之所以显示是为了保持属性页与检查框的一致性。
属性对话框的下半部分可以禁止用户使用某些菜单项。当你选择了相应的检查框后,相应的菜单会变得不可用。
在命令中设置保护标志
如果要通过命令方式来调用报表设计器或标签设计器中的保护方式,则应该使用PROTECTED关键字,如下所示:
CREATE REPORT MyReport PROTECTED
MODIFY REPORT MyReport PROTECTED
CREATE LABEL MyLabel PROTECTED
MODIFY LABEL MyLabel PROTECTED
如果没有指定PROTECTED关键字,报表设计器不会为任何布局对象加上保护
Visual FoxPro 9.0 的报表设计器(4)
增强的用户界面(UI)
报表设计的用户界面作了很多改进,使得用户能更方便、更直观地设计出报表。菜单项也作了很大的调整,上下文菜单做了改进,报表设计器的工具栏中增加了一些新选项。表达式构造对话框(Expression Builder )和表达式构造选项对话框(Express Builder Options)都有了新的特性,此外报表设计器对其它一些用户界面作了细微的改进。
菜单
菜单加入了一些新项目,一些原有的菜单项被更名使得它们表达的意思更清晰,此外一些常用的菜单项被重复以便用户更方便地访问到它,具体如下:
• “File”菜单下增加了“Save As Class...”菜单项。
• 报表设计器的工具栏加入了一个名为“水平线(horizontal lines)”的控件,它用来把Grid Lines和Show Position这两个控件与其它的控件分割开来。
• “Report”菜单增加了“重贴标签(relabled)”、“新建(new)”以及“打印预览(Print Preview)”等菜单项。
快捷菜单
对现有的快捷菜单添加了一些新条目,使得菜单条目与相应的对话框能保持更好一致性。 • “全局(Global)”快捷菜单增加了一个名为“重贴标签(relabled)”的菜单项。
• 通过右键单击任意带区(band)的灰色栏可以弹出名为“带区(Band)”的快捷菜单。
• 通过右键单击任意布局对象可以弹出名为“布局对象(Layout Object)”的快捷菜单。
工具栏
如图6所示,报表设计器的工具栏增加了两个新的控件:页面设置控件和字体控件:
图6. 报表设计器增加的两个新控件
表达式构造对话框
表达式构造对话框为“表达式域(Expression for Field)”输入框提供了一个更大的输入空间,允许用户输入更多的报表表达式。
如果你将_REPORTBUILDER这个系统属性设为空的话,那表达式构造对话框会指定本地行为,只有在数据环境中定义的数据表才能够显示在对话框中的列表中。那些没有在数据环境中定义的数据表则不会在列表中显示。
如果将_REPORTBUILDER系统属性为ReportBuilder.app的话,那表达式构造对话框则会呈现另外一种行为。首先,_GETEXPR中定义的表达式构造器会取代本地的表达式构造器。
表达式构造对话框还有一个下拉组合列表框,你可以从中选择要操作的数据表。只有当前已使用的数据表才会出现在这个列表框中。需要强调的是报表设计器是不会自动打开数据环境中定义的数据表的,因此如果数据表没有被打开的话,那它便不会出现在这个列表框中。
采用这种设计方式事,当用户使用你定义的报表时,你可以很好地控制用户能访问哪些数据表,不能访问哪些数据表。你可能在数据环境中定义了若干个数据表,但你不希望用户能访问所有的数据表,这时你可以打开一些允许用户访问的数据表,而其他未打开的数据表则对用户不可见。
鼠标指针的改进
当报表中对象处于大小可变状态时,鼠标指针会发生相应的改变(参见图7)。
图7. 当一个对象处于大小可变状态时,鼠标指针发生的改变。
多项选择对话框
VIsual FoxPro 9提供了一个多项选择对话框,你可以通过它一次性地设置多个布局对象的Portection和Print属性。它也允许你对单个布局对象的其它属性进行修改。要使用这种功能,先要选定多个布局对象,然后在任意一个对象上面单击右键来弹出这个对话框,如图8所示:
图8. 多项选择对话框
所有被选定的对象出现在对话框的“Selection”属性页的列表中。如果你要选取报表中所有的布局对象的话,用CTRL+A组合键可以对它们进行全选,然后再单击右键即可。
图8中的“Sort by”选项组允许你将布局对象按类型或出现在报表中的位置排序。“Remove from list”按钮可以删除列表中的布局对象。如果你双击列表中的某个对象,那么“Properties”属性页就会激活,并且显示出这些布局对象在报表中的某些属性。如图9所示,你可以一次性更改所有出现在“Selection”属性页中的布局对象的某些属性。
图9. 通过“Properties”属性页来修改布局对象的保护属性以及打印属性。
如果你选中了“Apply these protection settings to the selected objects”检查框,那可以对列表中的布局对象设置保护方式。如果你选中了“Apply this condition to the selected objects upon saving”检查框,那么可以允许打印。你可以根据自已的需要对保护及打印做更进一步的设置,设置完毕后,单击“OK”按钮便可同时改变所选的布局对象的这些属性。
更大的缩放级别
预览窗口有了更大的缩放级别,可以从10%缩放到500%。
布局对象的增强
布局对象也做了一些改进,包含一个操控模板字符的可选项,字符表达式的裁剪模式,以及能指定布局对象的相对位置和绝对位置。
模板字符
域属性对话框增加了对模板字符的一些新支持,它们分别是覆盖(Overlay)和交错(Interleave)。用来支持字符的一些特殊格式。
当你使用覆盖方式时,特殊字符会被当做数据的一部分,并且会覆盖其它的字符。举个例子来说,当你使用一个格式化字符串“999-999”时,而用户实际输入的数据是“123456”,那报表的最终结果将会显示为“123-56”,注意数字“4”被格式化字符中的“-”覆盖了。
当你使用交错方式时,特殊字符会插入到当前数据中。举个例子来说,当你使用一个格式化字符串“999-999”时,而用户实际输入的数据是“123456”,那报表的最终结果将会显示为“123-456”,注意“-”插入到了数字“3”和数字“4”的中间。
Visual FoxPro 9.0 的报表设计器(5)
字符表达式的裁剪模式
在Visual FoxPro 9以前,当域对象中的文本过长时一般都会被自动裁剪。在Visual FoxPro 9中,你可以指定域对象的如下几种裁剪方式:
• 缺省裁剪方式。这种方式类似于以前版本的Visual FoxPro的处理方式。
• 裁剪最近的字符。它将多余的字符全部裁掉,直至刚好满足输入域的长度。
• 裁剪最近的单词。它将多余的单词全部裁掉,直至刚好满足输入域的长度。
• 文件裁剪方式。如果输入域中的内容中一个非常长的文件路径,那么中间的路径将会以省略号代替,只保留头尾路径。
大小及位置
现在可以更方便地控制布局对象的大小以及所处的位置。与原版本不同,当在新版本报表中加入一个对象时,此对象的“From page top”、“From left”、“Height”和“Width”属性都会自动设置。在报表设计器中,“From page top”属性是指对象相对于页面顶端的相对位置。此对象上的所有灰色栏的高度也都被计算在内。改变对象的“From page top”属性有可能将对象移到到另一个区带中去。
相对位置:“From page top”属性和“Height”属性共同确定了当前对象是处于绝对位置还是相对位置。当对象的“From page top”属性的取值范围在报表的区域内,并且“Height”属性小于或等于所在区带的高度时对象就处于相对位置。一般来说,只有区带内的对象才需要使用相对位置,而像Page Header和Page Footer这样的对象则不需要使用相对位置。
绝对位置:当对象的“From page top”属性的取值范围在报表的区域以外,并且“Height”属性大于所在区带的高度时对象就处于绝对位置。绝对位置意味着对象在每页报表中都有着一个精确的位置,不会发生偏移。
我们可以利用绝对位置来为报表增加水印效果。将一幅水印图像放在Page Header区带中,并且将它设为“缩放内容,保持形状”模式。将水印图像的“From page top”属性和“From left”属性设为某组值,这组值相当于你的水印图像在报表中的左上角坐标。然后通过改变“Height”和“Width”属性来指出水印的大小,但注意的是不要将图像的尺寸设得过大,以免超过了打印区域的边界。
增强的数据分组功能
Visual FoxPro 9报表设计器对数据分组功能做了一些改进,增大了数据分组的最大数量限制以及对水平栏的改进。
最大数据分组数
最大数据分组数从原来的20个增加到了现在的74个。实际原来的版本也支持最大74个数据分组数,但由于原来的界面只支持20个数据分组的输入,从而导致了这种限制。
水平分栏
在以前的版本中,如果要为一个数据组定义多个水平分栏的话将会浪费很多报表空间。并且第一行第一列与报表的顶端之间有一些空白,数据还会从行1列2开始显示。并且在每个数据组中都会有一个多余的区带,如图10所示。即使数据组的页头区带的高度为0,Visual FoxPro 仍然将保留这些空白,如图11所示。
图10. 当为数据组定义多个水平分栏时,原来版本的Visual FoxPro浪费的报表空间
图11. 即使数据组的页头区带高度为0,原来版本的Visual FoxPro仍将保留这些空白
在Visual FoxPro 9中数据组分栏得到了改进。当报表设计器发现一个新数据组时,它将从第一列开始显示,直至満行。如果不满一行,那剩下的部分将以空格填充。如果还有未打印完的明细记录的话,那这些记录会从下一行开始输出,如图12所示。如果数据组的页头区带的高度为0,则Visual FoxPro 将不会保留任何空白,如图13所示。
图12. 将数据组进行水平分栏时,Visual Foxpro 9将节省更多的空间
图13. 如果数据组的页头区带高度为0时,Visual Foxpro 9不会保留任何空白
Visual FoxPro 9.0 的报表设计器(6)
多条明细区带
这个新增功能其实早在以前就很需要,它是对老版本的一个很大的改进。它能让你在一个父表中为每一条记录处理相对应的子表,这种报表格式的一个典型实例如图14所示。
图14. 这个报表为每个客户报告了其购买保险的详细信息
数据表与关联
要想熟练地使用这一新特色,你必须明白父表是怎样与子表一起协同工作的。我们以图15所展示的报表为例,它使用的数据库环境如下:
• 客户表(Customer)是父表,它包含了所有购买保险的客户。
• 家庭成员表(Members)是客户表的子表,它包含了客户的所有家庭成员。
• 交通险表(Vehicles)也是客户表的一个子表,它包含了客户所购买的交通险。
• 家庭险表(Homes)也是客户表的一个子表,它包含了客户所购买的家庭险。
主表
必须有一个表来做为报表的主表,在本例中,客户表正是这样的一个数据表。如果你用数据环境来定义数据表的话,那必须将它的InitialSelectedAlias属性定义为这个数据表。 如果你用代码的方式来定义数据表的话,那要保证当此报表运行时,客户表必须处于当前打开的工作区。
目标别名(Target Alias)
所谓目标别名,是指在报表某个特定的区带中做为主表的那个数据表。在本例中,家庭成员表是明细区带1的主表,交通险表是明细区带2的主表,而家庭险表则是明细区带3的主表。
如果没有为某个明细区带定义主表,那它就会呈现出与老版本的Visual FoxPro一样的行为(每个父表只会处理一个明细区带)。但如果你定义每个父表都为主表的话,那结果会全然不同。Visual FoxPro 将依次处理父表中所有记录,并在每个明细区带中依次将它们输出。
关联
关联在如何控制多条明细区带的输出中起到的重要的角色。Visual FoxPro通过父表与子表之间的关联来进行记录的导向。你可以通过SET RELATION或者SET SKIP来定义这些关联。如果你在数据环境中打开了这些数据表,并且数据库中已经定义了它们之间的关联关系的话,那父表与子表之间将会自动生成关联。
如果你采用代码方式打开数据表的话,那列表1将告诉你如何将图15所示的数据环境建立起来。
列表1.建立图15的数据环境
如下代码展示了如何将父表与子表建立报表关联的例子。
*--打开子表
USE Members IN 0 ORDER CustomerFK
USE Vehicles IN 0 ORDER CustomerFK
USE Homes IN 0 ORDER CustomerFK
*--打开父表
SELECT 0
USE customer ORDER CustomerPK
*--为父表和子表建立报表关联
SET RELATION TO CustomerPK INTO Members
SET RELATION TO CustomerPK INTO Vehicles ADDITIVE
SET RELATION TO CustomerPK INTO Homes ADDITIVE
定义多条明细区带
如果你新建一个报表,那它缺省地为这个报表只设置一个明细区带。通过可选区带对话框可增加额外的明细区带。从“Report”菜单中选择“Optional Bands...”菜单项就可以打开这个对话框。它其实就是原来版本中的“标题/小结(Title/Summary)”对话框。
单击“Add”按钮便可以增加一个新的明细区带,你可以为一个报表定义最多20个明细区带。
定义主表
通过明细对话框你可以为每一个明细区带定义其主表。从“Report”菜单中选择“Edit Bands...”就可以打开这个对话框,或者双击明细区带的灰色栏也可达到同样效果。
主表实际上是一个表达式,你必须将相应的数据表名用引号引起来。如果你定义了某个主表,则相应的明细区带的灰色栏将显示它的名字。
如果你要建立一个多条明细区带形式的报表,请别忘了在字段前面加入数据表名的前缀,格式为“数据表名.字段名”,这样可以防止不同的数据表之间的同名字段冲突。
页头和页尾
多条明细区带的另一个改进就是能为每一个明细区带增加独立的页头和页尾。这与页头和页尾分组有些类似,但仍然有一些不同。当每个父表记录的处理流程如下:
• 明细区带1的页头被处理。
• 处理明细区带1中主表相应的所有子表记录。
• 明细区带1的页尾被处理。
• 明细区带2的页头被处理。
• 处理明细区带2中主表相应的所有子表记录。
• 明细区带2的页尾被处理。
• 明细区带3的页头被处理。
• 处理明细区带3中主表相应的所有子表记录。
• 明细区带3的页尾被处理。
• 以此类推......
要为每一个明细区带增加独立的页头和页尾,你必须在详细信息对话框中的“Detail Header/Footer”的检查框中选中相应的明细区带。也可通过点击明细区带上方的标题栏来对明细区带进行排序。
学海无涯
Visual FoxPro 9报表设计器增加了如此多的特色来帮你建立更好的报表,以至于你不得不花更多的精力来学习它的新功能,但我认为这些学习是非常值得的。新的数据环境允许你在不同的报表中共享它。对报表的各个部分提供了强有力的保护方式,用户界面也做了一番改头换面,让你得到更舒适的开发体验。布局对象与数据分组的增强给你提供了更多的报表操控能力。最后,新推出的多条明细区带的特色能挖掘出报表设计器的更多功能。所有的这些改进可让你创建出非常复杂、功能非常强大的报表。
Visual FoxPro 9.0 的报表设计器(1)
Micorsoft公司对新推出的Visual Foxpro 9报表设计器作了显著地改进,同时又与老版本的Visual Foxpro保持了向后兼容性,新版本的报表设计器是一个新旧版本的混合体。
在本文中,你将了解报表设计器对新的数据环境、报表保护、用户界面、对象布局与数据分组功能的增强。最后,你将了解Visual FoxPro 9报表设计器的一个最有用的增强功能:多条明细区带(multiple detail bands)。
报表设计被一个新增的“Xbase报表设计器”的工具代替。它提供了一些新的对话框,并且比以前的版本更方便使用。它还提供了一些旧版本报表设计中所没有的新特色。你可以通过改变一个名为“_REPORTBUILDER”的系统属性来决定使用哪种报表设计器,如下所示:
*--如果要使用新版本的报表设计器
_REPORTBUILDER = HOME() + 'ReportBuilder.app'
*--如果要使用旧版本的报表设计器_REPORTBUILDER = ''
报表输出引擎:与报表设计器一样,你可以控制是否选用新版本的报表输出引擎。但与报表设计器不同的是Visual FoxPro 9默认报表输出引擎为旧版本方式。主要是因为在新版本的输出引擎中使用了GDI+库,而老版本的输出引擎使用的是GDI库,使用老版本的输出引擎就可以让应用程序可以在不用版本的windows上显示出同样的输出效果。你可以用如下命令来切换你的输出引擎:
*--使用新版本的输出引擎
SET REPORTBEHAVIOR 90
*--使用旧版本的输出引擎
SET REPORTBEHAVIOR 80
在下文中我们假定使用的是新版本的报表设计器和输出引擎。
数据环境(DE)
Visual FoxPro 9的报表设计器能与让多个报表共享同一个数据环境。数据环境能够以类的方式保存,并在需要的时候被报表载入。这为那些需要制定通用报表数据环境的应用程序提供了方便。
要将数据环境保存为一个类,首先你要为报表定义一个数据环境,然后激活数据环境窗口,并在“File”主菜单中单击“Save As Class...”选项。
这样系统会弹出一个新的对话框(参见图1)。在这种情况下,Save单选按钮组中只有“DataEnvironment”处于允许状态。
图1. 使用“Save As Class”对话框指定要保存的类名以及所在的类库,并将指定报表的数据环境保存在这个类中。
Visual FoxPro 9.0 的报表设计器(2)
载入数据环境
除了能为报表定义数据环境以外,Visual FoxPro 9还能让你将某个报表的数据环境类载入到报表中去。“Report”菜单中的“Load Data Environment...”选项可以让你选择到底载入哪个数据环境。
通过报表设计器载入数据环境
如果要为一个新报表载入数据环境,那源数据环境的所有代码和成员变量都会复制到新报表中。这表明当你改变原来报表的数据环境后,并不会对新报表的数据环境产生任何影响。
图2显示了当你从“Report”主菜单中单击了“Load Data Environment...”选项后弹出的属性对话框。你可以在里面选择从哪个报表中复制源数据环境。
图2. 单击”Data Environment“选项卡,从中选择你要从哪个报表中复制数据环境
在上图中,单击“Copy from another report file”单选按钮,然后单击“Select...”按钮,这样会弹出一个打开对话框,你可以从中选择从哪个报表中复制。如果你选中了一个报表,那系统弹出一个确认框。
假如我们要将某个报表的数据环境复制到当前报表中去,Visual FoxPro 9会警告你将覆盖当前报表的数据环境,你必须选择“是”才能继续进行复制。这个提示功能可以防止由于你的误操作而将当前报表的数据环境覆盖掉。如果你选择“否”的话,那复制就会取消,如果选择的是“是”,那就会真正进行复制操作,并且当操作完成后,系统会出现另一个对话框,提示你操作完成。
现在数据环境已经复制成功了,你可以操控新的数据环境。但你要始终记得原报表数据环境的改变并不会对新的数据环境有任何影响。
从一个类中载入数据环境
当要从一个类中载入数据环境时,你必须要为新报表的数据环境写一些额外的代码,使得它能够动态地绑定源数据环境,并且初始化它的一个实例。这意味着如果从类中载入数据环境时,对源数据环境做的所有改动会影响到所有使用它的报表。
你同样可以用图2所示的报表属性对话框来完成这个效果,先单击“Link to a visual DE class”单选按钮,然后从系统弹出的打开对话框中选择你要载入的类库以及类名,当你点击确定按钮后,当前报表的数据环境将得到更新,并且系统会给出相应提示信息。
其实Visual FoxPro自动为数据环境的如下5个方法中加入了一些代码:Init()、BeforeOpentables()、AfterCloseTables()、Destroy()和Error()。有些方法中加入的代码非常简单,仅仅是一个DODEFAULT()命令,这个命令不执行任何操作。其原因是BindEvents()方法必须保证数据环境的这5个方法中的代码行数超过一行才能执行。你可以手动查看这些自动生成的代码,但我强烈建议你别去动这些代码。
Visual FoxPro 9.0 的报表设计器(3)
保护
如果要在Visual FoxPro 9使用报表设计器或者标签设计器,你可以为一个或多个的布局对象设置保护。这种特性可以让你的用户只能对报表进行有限的修改。
你可以为布局对象设置5种保护模式,域对象有着另外的保护选项。带区(Band)有两种保护模式可供你选择。并且你也可对报表本身设置不同的保护方式。
保护一个对象
要在报表设计器中为一个布局对象设置保护,通过激活此对象的属性对话框即可操作,你可通过用右键点击此对象,并在弹出的快捷菜单中选择相应的菜单项,或者直接双击此对象。图3显示了一个布局对象属性对话框的保护页,你可以为布局对象设置如下5种保护方式: • 对象不能被移动或改变大小。它使得用户不能在设计器中移动此布局对象,并且用户不能改变此对象的大小。
• 对象不能被修改。它使得用户不能修改此布局对象的属性。
• 对象不能被删除。 它使得用户不能删除此对象。
• 对象不能被选中。用户不可以选择此对象,当对象处于这种保护方式下时,用户不能移动它或改变它的大小,同样也不能修改或删除它。
• 对象在设计器中不可见。它使得此对象在报表设计中不可见,当对象处于这种保护方式下时,用户不能移动它或改变它的大小,同样也不能修改或删除它。
图3. 布局对象属性对话框中的保护页
这个对话框还有一个名为“Design-time caption”的输入项,它只对域对象有效。你可以在其中输入域对象的名称,这样在报表设计器中就不会显示域的表达示名称,而是显示你输入的名称。当域的表达式非常冗长时,这种显示方式可以使得报表设计器的用户界面更加友好。
保护一个带区(Band)
在报表设计器中要保护一个带区的话,请先激活此带区的属性对话框。你可以通过选择“Report”菜单中的“Edit Bands...”菜单项来打开这个属性对话框,也可以直接双击带区的灰色条。图4显示了一个带区属性对话框的保护页,你可以选择以下两种保护模式:
• 带区不可修改。这可以防止用户修改带区的属性。
• 带区不可改变大小。这可以防止用户改变带区的大小。
图4. 带区属性对话框中的保护页
保护报表本身
要为一个报表设定保护方式,要先激活此报表的属性对话框。你可以通过选择“Report”菜单中的“Properties”菜单项来打开这个属性框,也可以右键单击此报表来弹出这样一个菜单。图5显示了一个报表属性对话框的保护页
图5. 报表属性对话框中的保护页
这个对话框的上半部分可让你禁止用户使用属性对话框中的某些属性页。当你选择了相应的检查框后,报表属性对话框中的某些属性页会变得不可用。但“Protection”检查框总是保持选择状态而且不允许你对它进行改动。另外由于“Ruler/Grid”属性页无法保护,因此“Ruler/Grid”检查框也总处于禁止状态,这两个检查框之所以显示是为了保持属性页与检查框的一致性。
属性对话框的下半部分可以禁止用户使用某些菜单项。当你选择了相应的检查框后,相应的菜单会变得不可用。
在命令中设置保护标志
如果要通过命令方式来调用报表设计器或标签设计器中的保护方式,则应该使用PROTECTED关键字,如下所示:
CREATE REPORT MyReport PROTECTED
MODIFY REPORT MyReport PROTECTED
CREATE LABEL MyLabel PROTECTED
MODIFY LABEL MyLabel PROTECTED
如果没有指定PROTECTED关键字,报表设计器不会为任何布局对象加上保护
Visual FoxPro 9.0 的报表设计器(4)
增强的用户界面(UI)
报表设计的用户界面作了很多改进,使得用户能更方便、更直观地设计出报表。菜单项也作了很大的调整,上下文菜单做了改进,报表设计器的工具栏中增加了一些新选项。表达式构造对话框(Expression Builder )和表达式构造选项对话框(Express Builder Options)都有了新的特性,此外报表设计器对其它一些用户界面作了细微的改进。
菜单
菜单加入了一些新项目,一些原有的菜单项被更名使得它们表达的意思更清晰,此外一些常用的菜单项被重复以便用户更方便地访问到它,具体如下:
• “File”菜单下增加了“Save As Class...”菜单项。
• 报表设计器的工具栏加入了一个名为“水平线(horizontal lines)”的控件,它用来把Grid Lines和Show Position这两个控件与其它的控件分割开来。
• “Report”菜单增加了“重贴标签(relabled)”、“新建(new)”以及“打印预览(Print Preview)”等菜单项。
快捷菜单
对现有的快捷菜单添加了一些新条目,使得菜单条目与相应的对话框能保持更好一致性。 • “全局(Global)”快捷菜单增加了一个名为“重贴标签(relabled)”的菜单项。
• 通过右键单击任意带区(band)的灰色栏可以弹出名为“带区(Band)”的快捷菜单。
• 通过右键单击任意布局对象可以弹出名为“布局对象(Layout Object)”的快捷菜单。
工具栏
如图6所示,报表设计器的工具栏增加了两个新的控件:页面设置控件和字体控件:
图6. 报表设计器增加的两个新控件
表达式构造对话框
表达式构造对话框为“表达式域(Expression for Field)”输入框提供了一个更大的输入空间,允许用户输入更多的报表表达式。
如果你将_REPORTBUILDER这个系统属性设为空的话,那表达式构造对话框会指定本地行为,只有在数据环境中定义的数据表才能够显示在对话框中的列表中。那些没有在数据环境中定义的数据表则不会在列表中显示。
如果将_REPORTBUILDER系统属性为ReportBuilder.app的话,那表达式构造对话框则会呈现另外一种行为。首先,_GETEXPR中定义的表达式构造器会取代本地的表达式构造器。
表达式构造对话框还有一个下拉组合列表框,你可以从中选择要操作的数据表。只有当前已使用的数据表才会出现在这个列表框中。需要强调的是报表设计器是不会自动打开数据环境中定义的数据表的,因此如果数据表没有被打开的话,那它便不会出现在这个列表框中。
采用这种设计方式事,当用户使用你定义的报表时,你可以很好地控制用户能访问哪些数据表,不能访问哪些数据表。你可能在数据环境中定义了若干个数据表,但你不希望用户能访问所有的数据表,这时你可以打开一些允许用户访问的数据表,而其他未打开的数据表则对用户不可见。
鼠标指针的改进
当报表中对象处于大小可变状态时,鼠标指针会发生相应的改变(参见图7)。
图7. 当一个对象处于大小可变状态时,鼠标指针发生的改变。
多项选择对话框
VIsual FoxPro 9提供了一个多项选择对话框,你可以通过它一次性地设置多个布局对象的Portection和Print属性。它也允许你对单个布局对象的其它属性进行修改。要使用这种功能,先要选定多个布局对象,然后在任意一个对象上面单击右键来弹出这个对话框,如图8所示:
图8. 多项选择对话框
所有被选定的对象出现在对话框的“Selection”属性页的列表中。如果你要选取报表中所有的布局对象的话,用CTRL+A组合键可以对它们进行全选,然后再单击右键即可。
图8中的“Sort by”选项组允许你将布局对象按类型或出现在报表中的位置排序。“Remove from list”按钮可以删除列表中的布局对象。如果你双击列表中的某个对象,那么“Properties”属性页就会激活,并且显示出这些布局对象在报表中的某些属性。如图9所示,你可以一次性更改所有出现在“Selection”属性页中的布局对象的某些属性。
图9. 通过“Properties”属性页来修改布局对象的保护属性以及打印属性。
如果你选中了“Apply these protection settings to the selected objects”检查框,那可以对列表中的布局对象设置保护方式。如果你选中了“Apply this condition to the selected objects upon saving”检查框,那么可以允许打印。你可以根据自已的需要对保护及打印做更进一步的设置,设置完毕后,单击“OK”按钮便可同时改变所选的布局对象的这些属性。
更大的缩放级别
预览窗口有了更大的缩放级别,可以从10%缩放到500%。
布局对象的增强
布局对象也做了一些改进,包含一个操控模板字符的可选项,字符表达式的裁剪模式,以及能指定布局对象的相对位置和绝对位置。
模板字符
域属性对话框增加了对模板字符的一些新支持,它们分别是覆盖(Overlay)和交错(Interleave)。用来支持字符的一些特殊格式。
当你使用覆盖方式时,特殊字符会被当做数据的一部分,并且会覆盖其它的字符。举个例子来说,当你使用一个格式化字符串“999-999”时,而用户实际输入的数据是“123456”,那报表的最终结果将会显示为“123-56”,注意数字“4”被格式化字符中的“-”覆盖了。
当你使用交错方式时,特殊字符会插入到当前数据中。举个例子来说,当你使用一个格式化字符串“999-999”时,而用户实际输入的数据是“123456”,那报表的最终结果将会显示为“123-456”,注意“-”插入到了数字“3”和数字“4”的中间。
Visual FoxPro 9.0 的报表设计器(5)
字符表达式的裁剪模式
在Visual FoxPro 9以前,当域对象中的文本过长时一般都会被自动裁剪。在Visual FoxPro 9中,你可以指定域对象的如下几种裁剪方式:
• 缺省裁剪方式。这种方式类似于以前版本的Visual FoxPro的处理方式。
• 裁剪最近的字符。它将多余的字符全部裁掉,直至刚好满足输入域的长度。
• 裁剪最近的单词。它将多余的单词全部裁掉,直至刚好满足输入域的长度。
• 文件裁剪方式。如果输入域中的内容中一个非常长的文件路径,那么中间的路径将会以省略号代替,只保留头尾路径。
大小及位置
现在可以更方便地控制布局对象的大小以及所处的位置。与原版本不同,当在新版本报表中加入一个对象时,此对象的“From page top”、“From left”、“Height”和“Width”属性都会自动设置。在报表设计器中,“From page top”属性是指对象相对于页面顶端的相对位置。此对象上的所有灰色栏的高度也都被计算在内。改变对象的“From page top”属性有可能将对象移到到另一个区带中去。
相对位置:“From page top”属性和“Height”属性共同确定了当前对象是处于绝对位置还是相对位置。当对象的“From page top”属性的取值范围在报表的区域内,并且“Height”属性小于或等于所在区带的高度时对象就处于相对位置。一般来说,只有区带内的对象才需要使用相对位置,而像Page Header和Page Footer这样的对象则不需要使用相对位置。
绝对位置:当对象的“From page top”属性的取值范围在报表的区域以外,并且“Height”属性大于所在区带的高度时对象就处于绝对位置。绝对位置意味着对象在每页报表中都有着一个精确的位置,不会发生偏移。
我们可以利用绝对位置来为报表增加水印效果。将一幅水印图像放在Page Header区带中,并且将它设为“缩放内容,保持形状”模式。将水印图像的“From page top”属性和“From left”属性设为某组值,这组值相当于你的水印图像在报表中的左上角坐标。然后通过改变“Height”和“Width”属性来指出水印的大小,但注意的是不要将图像的尺寸设得过大,以免超过了打印区域的边界。
增强的数据分组功能
Visual FoxPro 9报表设计器对数据分组功能做了一些改进,增大了数据分组的最大数量限制以及对水平栏的改进。
最大数据分组数
最大数据分组数从原来的20个增加到了现在的74个。实际原来的版本也支持最大74个数据分组数,但由于原来的界面只支持20个数据分组的输入,从而导致了这种限制。
水平分栏
在以前的版本中,如果要为一个数据组定义多个水平分栏的话将会浪费很多报表空间。并且第一行第一列与报表的顶端之间有一些空白,数据还会从行1列2开始显示。并且在每个数据组中都会有一个多余的区带,如图10所示。即使数据组的页头区带的高度为0,Visual FoxPro 仍然将保留这些空白,如图11所示。
图10. 当为数据组定义多个水平分栏时,原来版本的Visual FoxPro浪费的报表空间
图11. 即使数据组的页头区带高度为0,原来版本的Visual FoxPro仍将保留这些空白
在Visual FoxPro 9中数据组分栏得到了改进。当报表设计器发现一个新数据组时,它将从第一列开始显示,直至満行。如果不满一行,那剩下的部分将以空格填充。如果还有未打印完的明细记录的话,那这些记录会从下一行开始输出,如图12所示。如果数据组的页头区带的高度为0,则Visual FoxPro 将不会保留任何空白,如图13所示。
图12. 将数据组进行水平分栏时,Visual Foxpro 9将节省更多的空间
图13. 如果数据组的页头区带高度为0时,Visual Foxpro 9不会保留任何空白
Visual FoxPro 9.0 的报表设计器(6)
多条明细区带
这个新增功能其实早在以前就很需要,它是对老版本的一个很大的改进。它能让你在一个父表中为每一条记录处理相对应的子表,这种报表格式的一个典型实例如图14所示。
图14. 这个报表为每个客户报告了其购买保险的详细信息
数据表与关联
要想熟练地使用这一新特色,你必须明白父表是怎样与子表一起协同工作的。我们以图15所展示的报表为例,它使用的数据库环境如下:
• 客户表(Customer)是父表,它包含了所有购买保险的客户。
• 家庭成员表(Members)是客户表的子表,它包含了客户的所有家庭成员。
• 交通险表(Vehicles)也是客户表的一个子表,它包含了客户所购买的交通险。
• 家庭险表(Homes)也是客户表的一个子表,它包含了客户所购买的家庭险。
主表
必须有一个表来做为报表的主表,在本例中,客户表正是这样的一个数据表。如果你用数据环境来定义数据表的话,那必须将它的InitialSelectedAlias属性定义为这个数据表。 如果你用代码的方式来定义数据表的话,那要保证当此报表运行时,客户表必须处于当前打开的工作区。
目标别名(Target Alias)
所谓目标别名,是指在报表某个特定的区带中做为主表的那个数据表。在本例中,家庭成员表是明细区带1的主表,交通险表是明细区带2的主表,而家庭险表则是明细区带3的主表。
如果没有为某个明细区带定义主表,那它就会呈现出与老版本的Visual FoxPro一样的行为(每个父表只会处理一个明细区带)。但如果你定义每个父表都为主表的话,那结果会全然不同。Visual FoxPro 将依次处理父表中所有记录,并在每个明细区带中依次将它们输出。
关联
关联在如何控制多条明细区带的输出中起到的重要的角色。Visual FoxPro通过父表与子表之间的关联来进行记录的导向。你可以通过SET RELATION或者SET SKIP来定义这些关联。如果你在数据环境中打开了这些数据表,并且数据库中已经定义了它们之间的关联关系的话,那父表与子表之间将会自动生成关联。
如果你采用代码方式打开数据表的话,那列表1将告诉你如何将图15所示的数据环境建立起来。
列表1.建立图15的数据环境
如下代码展示了如何将父表与子表建立报表关联的例子。
*--打开子表
USE Members IN 0 ORDER CustomerFK
USE Vehicles IN 0 ORDER CustomerFK
USE Homes IN 0 ORDER CustomerFK
*--打开父表
SELECT 0
USE customer ORDER CustomerPK
*--为父表和子表建立报表关联
SET RELATION TO CustomerPK INTO Members
SET RELATION TO CustomerPK INTO Vehicles ADDITIVE
SET RELATION TO CustomerPK INTO Homes ADDITIVE
定义多条明细区带
如果你新建一个报表,那它缺省地为这个报表只设置一个明细区带。通过可选区带对话框可增加额外的明细区带。从“Report”菜单中选择“Optional Bands...”菜单项就可以打开这个对话框。它其实就是原来版本中的“标题/小结(Title/Summary)”对话框。
单击“Add”按钮便可以增加一个新的明细区带,你可以为一个报表定义最多20个明细区带。
定义主表
通过明细对话框你可以为每一个明细区带定义其主表。从“Report”菜单中选择“Edit Bands...”就可以打开这个对话框,或者双击明细区带的灰色栏也可达到同样效果。
主表实际上是一个表达式,你必须将相应的数据表名用引号引起来。如果你定义了某个主表,则相应的明细区带的灰色栏将显示它的名字。
如果你要建立一个多条明细区带形式的报表,请别忘了在字段前面加入数据表名的前缀,格式为“数据表名.字段名”,这样可以防止不同的数据表之间的同名字段冲突。
页头和页尾
多条明细区带的另一个改进就是能为每一个明细区带增加独立的页头和页尾。这与页头和页尾分组有些类似,但仍然有一些不同。当每个父表记录的处理流程如下:
• 明细区带1的页头被处理。
• 处理明细区带1中主表相应的所有子表记录。
• 明细区带1的页尾被处理。
• 明细区带2的页头被处理。
• 处理明细区带2中主表相应的所有子表记录。
• 明细区带2的页尾被处理。
• 明细区带3的页头被处理。
• 处理明细区带3中主表相应的所有子表记录。
• 明细区带3的页尾被处理。
• 以此类推......
要为每一个明细区带增加独立的页头和页尾,你必须在详细信息对话框中的“Detail Header/Footer”的检查框中选中相应的明细区带。也可通过点击明细区带上方的标题栏来对明细区带进行排序。
学海无涯
Visual FoxPro 9报表设计器增加了如此多的特色来帮你建立更好的报表,以至于你不得不花更多的精力来学习它的新功能,但我认为这些学习是非常值得的。新的数据环境允许你在不同的报表中共享它。对报表的各个部分提供了强有力的保护方式,用户界面也做了一番改头换面,让你得到更舒适的开发体验。布局对象与数据分组的增强给你提供了更多的报表操控能力。最后,新推出的多条明细区带的特色能挖掘出报表设计器的更多功能。所有的这些改进可让你创建出非常复杂、功能非常强大的报表。