Visual FoxPro 9.0 报表书写器的新增功能

Visual FoxPro 9.0 报表书写器的新增功能

<!--NONSCROLLING BANNER END-->

作者:Cathy Pountney,Visual FoxPro MVP,www.frontier2000.com

翻译:张洪举,Visual FoxPro MVP,www.vfptop.com

应用于:Visual FoxPro 9.0

概述: 学习Visual FoxPro 9.0报表书写器的新增功能包括新增的可重用数据环境、报表保护和用户界面增强。你可以从中学习到对布局对象的增强、对国际用户的改进、对打印和对数据分组的增强。此外,也可以学习到报表书写器的两个最大改进:多细节带区和报表的可扩展功能。最后,你将学习到Visual FoxPro报表文件(FRX)的详细结构。

目录

前言
可扩展功能
数据环境
保护
用户界面增强
布局对象增强
国际化功能
打印增强
数据分组增强
多细节带区
FRX
结论
 

前言

微软在当前基于FRX结构的报表上投入了众多的开发者,在很大程度上改进了VFP 9.0的报表书写器。VFP 9.0的报表书写器与先前的VFP版本兼容,它是一个对新版本和老版本的成功融合。

可扩展功能

在VFP 9.0之前,报表引擎处理的事情包括:处理数据、对象位置、绘制、打印和预览,并没有挂钩到报表引擎和定制报表的方法,但是这在VFP别的应用领域中却可以。对于VFP 9.0报表书写器的最大改进就是新增的可扩展功能,报表设计器、报表引擎和预览容器都公开给了开发者。

报表生成器

VFP 9.0报表书写器包含了一个新增的设计时功能,叫做Builder Hooks(生成器挂钩)。公开了几个报表设计器事件和一个叫做Report Builder(报表生成器)的独立Xbase组件,这个组件可以被调用后处理这些报表设计器事件。这个组件也可以被用来调用你自己的对话框,扩展本地报表设计器的行为或者覆盖本地行为。

VFP为设计报表包含了一个可扩展的报表生成器应用程序,其包含有各种新增功能,并提供了一个很友好的用户界面。报表生成器由一个新增的系统变量_REPORTBUILDER控制。如果该变量为空,则显示原来版本的对话框。要调用生成器挂钩,可以设置该变量为一个适当的应用程序。例如,要使用VFP 9.0附送的报表生成器,可以执行下列命令:

_REPORTBUILDER = HOME() + "REPORTBUILDER.APP"

该文章中的某些部分假定使用原来版本的对话框,并且_REPORTBUILDER系统变量为空,其他某些地方则假定使用新对话框,并且_REPORTBUILDER系统变量设置为REPORTBUILDER.APP。如果你没有经历过我们描述的这种行为或没有看见过这个对话框,可以改变_REPORTBUILDER的值来体验一下。

报表引擎

在新的输出系统中(Object-Assisted Output),报表引擎用于处理数据中心的事务,如移动整个范围和表达式求值。但是,当建立输出时,它延迟对叫做ReportListener的新增基类的工作,该新增基类使用GDI+以一种更加高级的方法来绘制报表内容,并且它也给Xbase用户一个与输出过程相互作用的机会。图1显示了这些部分如何搭配在一起工作的。

Click here for larger image

图1 使用新增的ReportListener类来操纵报表

要使用ReportListener类,可以使用REPORT FORM命令的新增子句,如下所示:

oListener = CREATEOBJECT("ReportListener")
oListener.ListenerType = 1 && 预览,或设置为0进行打印
REPORT FORM <name> <clauses> OBJECT oListener

VFP 9.0也提供了第二种使用ReportListener类的方式,你可以设置新增系统变量_REPORTOUTPUT的值为一个基于ReportListener类的应用程序名称。

当使用Object-Assisted Output时,报表会根据它的ListenerType属性值设置,使用两种方式中的某个方式进行处理。你可以认为这两种方式是print-appropriatepreview-appropriate,或者是page-at-a-timeall-pages-at-once。在第一种方式中,在准备每页时,Listener触发一个OutputPage事件,例如在发送每页到打印机或打印队列时。

在第二种方式中,Listener为绘制和高速缓存报表准备所有的页面,在完成时,可以调用OutputPage方法来询问是按页号输出所有的页面还是输出其中的任意一个页面。

预览容器

在VFP 9.0中,另一个可扩展功能难题是预览容器。对于此挂钩,你可以使用由VFP 9.0附送的新预览容器,或者书写自己的预览容器。在不使用新增的object-assiste输出时,旧的预览容器仍旧可用。

新增的系统变量_REPORTPREVIEW可以用来包含预览容器的应用程序名称。缺省情况下,该变量指向ReportPreview.app。该应用程序比旧的预览程序包含了大量的改进,包括更多的缩放级别、工具栏控制、标题控制、多页预览和使用GDI+而带来的更加优良的显示品质。图2和图3显示了旧预览界面和新预览界面的差异。

图2 在旧预览容器中输出很不柔和

图3 新的预览容器含有更多优良性能和更多完善选项

注意旧预览容器和新预览容器之间在品质方面的差异。新容器比旧容器具有更加柔和的字体,这要归功于使用GDI+来输出信息;同时也要注意所停靠工具栏的差别,在新预览容器上的工具栏具有更多选项,包含多页布局按钮等。

传统输出

新增的SET REPORTBEHAVIOR命令可以用于打开或关闭Object-Assisted Output,新的输出绘制引擎和预览界面与旧类型的输出有相当大的差异,对齐、字母紧排和间距在GDI和GDI+之间是不同的,这会在很大程度上改变现存报表的查看结果。因此,REPORTBEHAVIOR默认设置值为80,即关闭Object-Assisted Output输出,报表处理按照VFP 9.0之前的方式进行。

如果你要全局性的打开Object-Assisted Output,可以在Options对话框中改变这个设置值(如图4所示),或者执行下面的命令:

SET REPORTBEHAVIOR 90

图4 使用Options对话框中的Run-time behavior(运行时行为)选项改变SET REPORTBEHAVIOR设置

REPORTBEHAVIOR设置90时, REPORT FORM命令会与使用OBJECT子句一样来执行,而不需要改变代码,VFP使用_REPORTOUTPUT系统变量为每个REPORT FORM命令指定基于ReportListener类的应用程序。

通过VFP 9.0报表书写器中的新增扩展功能,你可以使用报表生成器、报表引擎和预览界面,你既可以全局地打开这些新增功能,也可以为各个报表逐个单独打开。也可以关闭这些新增功能,就象在先前VFP版本中运行一样。

数据环境

VFP 9.0报表书写器现在可以与其他报表共享数据环境,数据环境也可以被作为一个类进行保存,然后加载到所需要的报表中,这为定义公共报表需求提供了一个很好的数据重用解决方案。

另存为类

要将一个数据环境存储为类,可以在报表中定义数据环境时进行。当数据环境窗口处于活动状态时,从File菜单中选择新增的Save As Class...选项(参考图5)。

图5 当数据环境为活动窗口时,新增的Save As Class...选项会出现在File菜单上

在选择Save As Class...选项后,出现如图6所示的Save As Class 对话框。在保存一个报表的数据环境时,Save选项组DataEnvironment是惟一可用的选项按钮。

图6 为存储报表的数据环境,使用Save As Class对话框来声明新建类和类库的名称

在Name文本框中为类输入一个名称,接下来在File文本框中输入要保存的新建类的类库名称。如果所输入的类库名称不存在,则创建新类库文件,也可以使用省略(...)按钮来定位到一个已存在的类库。最后,你还可以输入对新建类的说明。

加载一个数据环境

除了手动为一个新建报表定义数据环境外,VFP 9.0也提供了从已有报表或已存储的DataEnvironment类中加载数据环境的选项。Report菜单上的Load Data Environment(加载数据环境)...选项(如图7所示)允许选择一个数据环境加载到当前报表中。

图7 使用Load Data Environment...选项从已有报表或DataEnvironment类中加载数据环境

注意:Load Data Environment功能仅在新增的ReportBuilder对话框中可用,你应当通过设置_REPORTBUILDER = HOME() + "ReportBuilder.app"来使用此功能

从报表加载数据环境

要从其他报表加载数据环境时,所有原数据环境的代码和成员会被复制到新报表中,这里的含义是:在复制后,再对原报表的数据环境的改变不会再影响到所建立的报表中。

可以从Report菜单中选择Load Data Environment...后打开如图8所示的Report Properties对话框,选择所要复制数据环境的报表到当前报表中。

图8 使用Report Properties对话框的Data Environment选项卡来选择你要复制数据环境的的报表

选择Copy from another report file(从其他报表文件复制)选项按钮后并选择Select...按钮,这会打开Open对话框,可以从中选择要复制的报表,一旦选择一个报表后,将出现一个确认对话框(如图9所示)。

图9 使用此对话框来确认要复制一个数据环境到当前报表中

VFP 9.0要从其他报表复制数据环境到当前报表,会通知你会覆盖当前数据环境,并且要单击Yes才可以继续执行,这说明你在当前报表数据环境中定义的任何内容都将被覆盖掉。如果单击No,报表不会发生变化并终止此过程,单击Yes时,数据环境被复制并出现如图10所示的提示对话框。

图10 该对话框确认数据环境已被成功复制到当前报表中

现在完成了复制数据环境,就可以按照程序需求来操作数据环境了。但是,需要注意的是,在这之后再对原来报表数据环境做的改变,并不会影响当前报表的数据环境。

DataEnvironment类加载数据环境

当从一个类中加载数据环境时,一些代码会被添加到新建报表的数据环境中,用于绑定到指定的DataEnvironment类,并在运行时实例化这个类。这里的含义是:以后再对DataEnvironment类所做的改变会影响到所有使用这个类的报表。

使用如图8所示的Report Properties 对话框,单击Link to a visual DE class(连接到可视数据环境类)按钮,接下来单击Select...按钮来打开Open对话框,可以从中选择类库和要使用的类。在选择了一个类后,将会出现与图9同样的确认对话框,确认后,数据环境被更新,并且显示如图10所示的对话框,通知加载数据环境成功。

在此时,一些代码会被添加到数据环境的某些方法中,在一些方法中只具有十分简单的代码,如只有一个DODEFAULT()命令,其原因是在方法中只少要包含一行代码,否则BindEvents()函数不能运转。

数据环境代码

从一个类加载数据环境后,会自动添加一些代码到下面描述的几个方法中。

Init方法

Init方法中的下列代码用于保证BindEvents()能按预定目标工作。

*-----------------------------------------------------*
* 此方法代码由报表生成器插入 *
*-----------------------------------------------------*
    DODEFAULT()
BeforeOpenTables方法

下列代码在数据环境上建立了几个新属性,来支持被加载的DataEnvironment类的对象引用。接下来将该数据环境中的事件绑定到在DataEnvironment类中的相对应事件,但是,InitDestroy事件不绑定。最后,DataEnvironment类的BeforeOpenTables事件被触发。

*-----------------------------------------------------*
* 此方法代码由报表生成器插入 *
*-----------------------------------------------------*
    LOCAL loMember, laDEEvents[1], liMember, liMembers, loBoundMember
    THIS.AddProperty( "BoundDE", NEWOBJECT( "de_insurance", "c:\vfp9\rwde.vcx" ))
    IF VARTYPE( THIS.BoundDE ) = "O" AND UPPER( THIS.BoundDE.BaseClass ) = "DATAENVIRONMENT"

        * 在这里绑定事件,跳过Init和Destroy事件
        * FRX DE和它的成员只能具有基本事件,所以许多PEMSTATUS不是必需的
        liMembers = AMEMBERS( laDEEvents, THIS, 3 )       
        FOR liMember = 1 TO liMembers
            IF INLIST( UPPER( laDEEvents[ liMember, 1] ), "INIT", "DESTROY" )
                LOOP
            ENDIF
            IF INLIST( UPPER( laDEEvents[ liMember, 2] ), "EVENT", "METHOD" )
                BINDEVENT( THIS, ;
                           laDEEvents[ liMember, 1], ;
                           THIS.BoundDE, ;
                           laDEEvents[ liMember, 1] )
            ENDIF
        ENDFOR

        * 现在做私有成员的检查,再次跳过Init和Destroy事件
        FOR EACH loMember IN THIS.Objects
            IF PEMSTATUS( THIS.BoundDE, loMember.Name, 5 ) AND ;
                UPPER( PEMSTATUS( THIS.BoundDE, loMember.Name, 3 ) = "OBJECT"
                loBoundMember = EVAL( "THIS.BoundDE." + loMember.Name )
                IF ( loBoundMember.BaseClass == loMember.BaseClass )
                    liMembers = AMEMBERS( laDEEvents, loMember, 3 )
                    FOR liMember = 1 to liMembers
                        IF INLIST( UPPER( laDEEvents[ liMember, 1] ), "INIT", "DESTROY" )
                            LOOP
                        ENDIF
                        IF INLIST( UPPER( laDEEvents[ liMember, 2] ), "EVENT", "METHOD" )
                            BINDEVENT( THIS, ;
                                       laDEEvents[ liMember, 1], ;
                                       loBoundMember, ;
                                       laDEEvents[ liMember, 1] )
                        ENDIF
                    ENDFOR
                ENDIF
            ENDIF            
        ENDFOR
        THIS.BoundDE.BeforeOpenTables()
    ENDIF
AfterCloseTables方法

AfterCloseTables方法中的下列代码用于保证BindEvents()按预定目标工作。

*-----------------------------------------------------*
* 此方法代码由报表生成器插入 *
*-----------------------------------------------------*
    DODEFAULT()
Destroy方法

添加到Destroy方法中的下列代码,用来解除报表数据环境方法与DataEnvironment类之间的绑定,该代码也移除对DataEnvironment类的对象引用。

*-----------------------------------------------------*
* 此方法代码由报表生成器插入 *
*-----------------------------------------------------*
    LOCAL loMember
    UNBIND( THIS )
    FOR EACH loMember in THIS.Objects
        UNBIND( loMember )
    ENDFOR
    IF PEMSTATUS( THIS, "BoundDE", 5 ) AND UPPER( PEMSTATUS( THIS, "BoundDE", 3 )) = "PROPERTY"
        THIS.BoundDE = NULL
    ENDIF
Error方法

Error方法中的下列代码用于保证BindEvents()按预期目标工作。

*-----------------------------------------------------*
* 此方法代码由报表生成器插入 *
*-----------------------------------------------------*
    LPARAMETERS nError, cMethod, nLine
    DODEFAULT( nError, cMethod, nLine )

保护

在VFP 9.0中使用报表设计器或标签设计器时,可以为一个或多个布局对象建立保护。这就允许用户来修改一个报表,但是却可以保持某些对象不被改变。

设置保护标记

布局对象有5种可以设置的不同保护模式,Field(字段)对象具有一个额外的保护选项,Bands(带区)具有2个可以设置的保护模式,报表自身还具有多种可以设置的保护模式。

注意:新增的保护功能只能通过新增的ReportBuilder对话框进行设置,可以设置_REPORTBUILDER = HOME() + "ReportBuilder.app"来使用这些保护功能。

保护对象

要在报表设计器中保护一个布局对象,应当打开对象的Properties对话框进行设置。在选定对象后,可以从Report菜单中选择Properties打开Properties对话框。也可以单击右键后从对象的上下文菜单中选择,或者双击对象自动打开Properties对话框。图11展示了一个字段对象的Properties对话框的Protection(保护)选项卡。

图11 可以使用Properties对话框的Protection选项卡来设置布局对象的保护模式

可以为布局对象设置如下5种保护模式:

  • Object cannot be moved or resized加上复选标记,可以防止用户在设计界面中移动布局对象到其他位置和防止用户调整对象的大小。
  • Object cannot be edited加上复选标记,可以防止用户对对象的属性做任何改变。
  • Object cannot be deleted加上复选标记,可以防止用户删除此对象。
  • Object cannot be selected加上复选标记,可以防止用户选择此对象,在选择了此选项时,Object cannot be moved or sizedObject cannot be editedObject cannot be deleted保护模式会被同时选定。
  • Object is not visible in Designer加上复选标记,可以防止在保护模式的报表设计器中出现此对象,在选定该选项时,则其他4个选项的保护模式也会被同时选定。

该对话框的Design-time caption(设计时标题)部分仅用于Field对象,在该文本框中输入的字符串将在报表设计器中代替Field的Expression显示,这样做的好处是可以显示一些友好易用的信息,从而替代某些复杂的表达式显示。

保护带区

要在报表设计器中保护带区,可以选择带区的Properties对话框。可以从Report菜单中选择Edit Bands...菜单项打开Properties对话框,也可以从带区的上下文菜单中选择,或者双击带区中的灰色带区条来打开。图12显示了一个带区的Properties对话框的Protection选项卡。

图12 可以使用带区的Properties对话框的Protection选项卡来设置带区的保护模式

可以为带区设置如下两种保护模式:

  • Band cannot be edited加上复选标记,可以防止用户见到Band Properties对话框。
  • Band cannot be resized加上复选标记,可以防止用户调整带区大小。
保护报表

要设置整体的报表保护,可以打开Report Properties对话框进行设置。可以从Report菜单中选择Properties菜单项,或者从报表的上下文菜单中打开Report Properties对话框。图13显示了Report Properties对话框的Protection选项卡。

图13 可以使用Report Properties对话框的Protection选项卡来设置报表的整体保护模式

在对话框的上部,可以允许定义Report Properties对话框的哪个选项卡对于用户不可用。对于在该区域中的每个选择,Report Properties对话框的相应选项卡会禁止使用。Protection选项总是处于选定状态,并且不可用。Ruler/Grid选项不可用是因为该选项卡不能被保护,该选项之所以出现在这里,是为了和Report Properties对话框上的选项卡保持一致。

该对话框的下部允许哪个菜单选项对于用户不可用,对于在该区域中的每个选择,相应的菜单项会禁止使用。

使用保护标识

要在与报表设计器或标签设计器会话期间调用保护功能,必须在命令中使用如下所示的PROTECTED关键字:

CREATE REPORT MyReport PROTECTED
MODIFY REPORT MyReport PROTECTED
CREATE LABEL MyLabel PROTECTED
MODIFY LABEL MyLabel PROTECTED

如果没有使用PROTECTED关键字,则报表设计器不启用对于布局对象的保护功能。

用户界面增强

对于用户界面做的许多修改,可以使设计报表更加容易和直观。VFP 9.0彻底更新了菜单、上下文菜单,并在报表设计器工具栏上增加了许多新选项。Expression Builder对话框和Expression Builder Options对话框也增加了新功能,以及一些其他用户界面增强也被添加到VFP 9.0报表书写器中。

菜单

VFP 9.0中的菜单已被彻底更新,以适应新增的选项。此外,为了更加明确,一些原有菜单选项被重新标注,并且为了更加容易访问,一些选项被重复放置在几个菜单中。图14至图16展示了新菜单的变化。

图14 在File菜单上新增的“Save As Class...(另存为类)”选项

图15 为报表设计器工具栏新增的Report Designer Toolbar选项,并把Grid Lines、Show Position选项与其他选项进行分割开

图16 Report菜单上的更多变化,包括重新标注选项、新增选项和新增的Print Preview重复选项

上下文菜单

现在的上下文菜单也增加了一些菜单项,这样可以与所调用的对话框更加一致。在报表设计器中的一些项目,先前并不具有上下文菜单,但是现在可以了。图17至图19展示了这些新变化。

图17 全局上下文菜单所具有的新增选项和一个重新标注选项

图18 通过右键单击任何带区的灰色带区条可以打开新增的带区上下文菜单

图19 通过右键单击任何布局对象可以打开布局对象上下文菜单

工具栏

报表设计器工具栏也有一些新增的按钮,如图20所示。

图20 为页面设置和字体属性新增的按钮

Expression Builder(表达式生成器)对话框

Report Expression对话框具有了一些小改变,图21展示了这种变化,现在的对话框为输入报表表达式提供了更大的区域。

图21 在当前更高的Expression for Field on Report文本框中可以输入较长的表达式

_REPORTBUILDER系统变量为空时,Expression Builder对话框原来的行为如下:仅在数据环境中定义的表的字段显示在Fields列表框中,但是在数据环境外打开的表在列表框中并不可用。

_REPORTBUILDER系统变量设置为ReportBuilder.app时,Expression Builder的行为却大不相同。首先,在_GETEXPR中定义的Expression Builder会替代原来的Expression Builder。图22显示了默认的Expression Builder对话框。

图22 使用"From table"组合框从打开的表中选择字段

Expression Builder对话框现在具有了一个为Fields列表框中的字段选择数据表的组合框,但是,只有当前使用的数据表在组合框中才会列出。记住这一点是至关重要的,因为在数据环境中定义的表不会被报表设计器自动打开,因此,它们不会自动出现在组合框中。

之所以这样做,是因为当在应用程序中允许用户修改报表时,你可以控制哪些表对最终用户可用。如:你可能在数据环境中定义了一些你所需要的数据表,但是却不希望用户可以访问它们,所以,你可以明确地打开想让用户访问的表,而忽略掉那些要保护的表。

Expression Builder Options(表达式生成器选项)对话框

Expression Builder Options对话框中的Field aliases选项组现在可用了,如图23所示。该选项组用于指定在从Expression Builder对话框中选择字段时是否添加表的别名到报表表达式中。

图23 使用Field aliases选项组可以指定在从Expression Builder对话框中选择字段时是否添加表的别名到报表表达式中

Always add alias(总是添加别名)Never add alias(不添加别名)选项按钮指定VFP 9.0是否为所有字段自动添加表的别名,Add non-selected alias only(仅添加未选定的别名)选项按钮的行为受_REPORTBUILDER系统变量的值影响。如果_REPORTBUILDER系统变量为空,任何不是从数据环境InitialSelectedAlias属性所指定表中选择的字段将使用表别名作为前缀,从InitialSelectedAlias指定表中选择的字段则不使用表别名前缀。

如果_REPORTBUILDER系统变量设置为ReportBuilder.appAdd non-selected alias only选项的使用略有不同,在确定是否以表别名作为字段的前缀时,将以当前所选择的表别名代替InitialSelectedAlias指定的表别名。

除了从Expression Builder对话框选择字段之外,也可以从数据环境中拖放字段到报表设计器中,这会使用Field aliases选项组中的设置。与此相同,在Options对话框的Report选项卡中也新增了一个选项,如图24所示。该选项决定了为所有新建立的报表使用什么样的Field aliases默认设置。

图24 使用Options对话框的Report选项卡上的Expression Builder选项来设置默认Expression Builder行为

其他用户界面增强

几个对于用户界面的其他增强也改进了报表设计方式,详述如下。

鼠标形状

现在当对象可以被调整大小时,鼠标形状会进行相应变化,给予提示。如图25所示。

图25 使用新增的鼠标形状变化可以知道对象在什么时候可调整大小

Multiple Selection(多重选择)对话框

VFP 9.0现在具有了一个Multiple Selection对话框,可以一次为多个布局对象设置ProtectionPrint when属性,自然也可以改变其中任何单个布局对象的其他属性。要使用这个新增功能,可以在选择多个布局对象后,双击其中的任何一个对象来打开Multiple Selection对话框,如图26所示。

图26 使用Multiple Selection对话框的Selection选项卡选择要操作的布局对象

所选择的布局对象会在对话框打开时显示在对话框的第一个选项卡中,要对报表中的所有对象进行操作,可以在打开该对话框之前按CTRL+A来选择所有布局对象。

Sort by(排序)选项允许对布局对象列表按在报表中的Type(类型)或Location(位置)进行排序,Remove from list(从列表中删除)按纽从列表中删除选定的布局对象,双击列表中的任何项目,则打开与该对象对应的Properties对话框。Multiple Selection对话框的Properties选项卡,用于改变在Selection选项卡中所列出全部项目的属性,如图27所示。

图27 使用Multiple Selection对话框的Properties选项卡一次改变所有选定对象的Protection属性和Print when逻辑条件

选择Apply these protection settings to the selected objects(应用保护设置到选定对象)复选框来打开Protection选项;选择Apply this condition to the selected objects upon saving(应用下面的条件到选定对象)复选框来打开Print when选项,在改变了ProtectionPrint when的设置后,可以单击OK按钮关闭对话框并保存这些改变到所有Selection选项卡中列出的布局对象中。

更多缩放级别

Preview窗口具有了更多的缩放级别,如图28所示。

图28 为了更好的可视性,可以使用在VFP 9.0预览新增的缩放级别

VFP 9.0对用户界面进行了许多改进,包括菜单、上下文菜单和工具栏。对Expression Builder对话框和Expression Builder Options对话框也增加了一些有效的选项,其他改进包括鼠标形状、Multiple Selection对话框以及更多报表预览的缩放级别。

布局对象增强

在布局对象中增加了一些小改进,包括控制模板字符的选项、对于字符表达式的剪裁模式,以及相对和绝对位置。

注意:要使用增强的剪裁模式,应当使用新增的Object Assisted Output,或者直接通过ReportListener对象,或者通过间接的SET REPORTBEHAVIOR 90命令。

模板字符

Field Properties对话框现在具有了一个新增部分-Template characters,如图29所示,两个可用选项是Overlay(覆盖)Interleave(插入)。这决定了如何使用在Format expression文本框中指定的字符串。

图29 Template characters决定了如何将格式化字符用于字段数据

在使用Overlay选项时,指定的格式化字符作为数据的一部分来对待,并且覆盖在格式化字符给定位置上的任何字符。例如,在Format expression为“999-999”时,并且字段数据包含“123456”,则报表显示为“123-56”,请注意其中的“4”是如何被Format expression表达式中的破折号给替换掉的。

在使用Interleave选项时,指定的格式化字符将插入到当前数据中。例如,在Format expression为“999-999”时,并且字段数据中包含“123456”,则报表显示“123-456”,请注意Format expression表达式中的破折号如何插入到了“3”和“4”之间。

为Character表达式指定剪裁方式

在VFP 9.0之前,在文本过长时,字段对象总是被剪裁到最近的单词。在VFP 9.0中,在Field Properties对话框上的一个新增选项可以指定剪裁文本的方式,如图30所示。

图30 使用Trim mode for character expressions来指定剪裁超长文本的方式

对6个剪裁选项说明如下:

  • 选择Default trimming,将使用默认行为,与Trim to nearest word, append ellipsis选项是相同的,该行为类似VFP的先前版本,但是在字符后添加省略号。
  • 选择Trim to nearest character,文本将被剪裁到恰好填充指定空间的最后完整字符。
  • 选择Trim to nearest word,文本被剪裁到恰好填充指定空间的最后完整单词。
  • 选择Trim to nearest character, append ellipsis,文本被剪裁到恰好填充指定空间的最后完整字符,并在打印文本的后面添加一个省略号(...)。
  • 选择Trim to nearest word, append ellipsis,文本被剪裁到恰好填充指定空间的最后完整单词,并在打印文本的后面添加一个省略号(...) 。
  • 选择Filespec: Show inner path as ellipsis,在全部文本不能被填充进指定空间时,长路径和文件名内的目录名会替换为省略号(...)。

大小和位置

布局对象的另一个新增功能是可以更好地控制对象的大小和位置,如图31所示。

图31 使用在Properties对话框上的Size and position in layout(大小和布局位置)选项来控制相对和绝对位置

在对象被添加到报表上时,From page topFrom leftHeightWidth的值是自动设置的,注意From page top属性值是相对于报表设计器中页顶部的位置,对象上方的所有灰色带区条的高度也会被考虑在内,改变From page top属性可能会不经意地移动对象到其他带区。

相对位置

From page top属性值和Height属性值将共同来确定是使用绝对位置还是相对位置。当From page top属性是一个报表设计器页面大小范围内的一个值时,并且Height的属性值小于或等于对象其所在带区的高度,则使用相对位置。相对位置需要对象在带区中,但是页标头和页脚注带区除外。

绝对位置

From page top属性设置成了一个报表设计器页面范围大小之外的一个值,或者Height属性的值超过了对象所在带区的高度,则使用绝对位置,绝对位置的含义是对象将在每页中相同的精确位置进行打印。

绝对位置可以用于在报表上建立水印,例如,在页标头带区中放置一个图像,并设置为Scale contents, retain shape(缩放图片,保留形状)。改变From page topFrom left属性来指定水印开始的左上角位置,改变HeightWidth属性来指定水印的大小,并确认水印没有超出打印机的可打印区域。

国际化功能

在VFP 9.0中,报表在国际化支持方面有着更好的表现,特别是可以为字体设置字符集或语言脚本。网格单位具有了更多选项,并且STRCONV()函数也具有了更多选项。

FontCharSet

字体的字符集或语言脚本可以在Font对话框中设置,如图32所示。这可以为报表上的一个特定对象或整个报表设置默认字体。

图32 可以使用Script组合框选择一个字符集或语言脚本

网格单位

Set Grid Scale对话框现在增加了3个Ruler Scale(标尺刻度)选项来允许设置刻度为inches(英寸)或metric/centimeters(米/厘米),或者关闭标尺。这为具有不同系统默认设置的客户给予了更好的控制需求,图33显示了在Set Grid Scale对话框中的新增选项。

图33 为更好地控制标尺刻度,可以在Set Grid Scale对话框中使用新增的下拉组合框

Set Grid Scale对话框相同的功能增强也被添加到Options对话框的Report选项卡中。

STRCONV()

VFP 9.0另一个对国际化报表的改进是修改了STRCONV()函数,现在可以使用该函数变化Locale ID的代码页和fontcharset(字符集)的值,下面的帮助文档解释了STRCONV()的新增功能。

STRCONV(cExpression, nConversionSetting [,nRegionalIdentifier[,nRegionalIDType]])

nRegionalIDType: 
0 - 默认值, nRegionalIdentifier为Locale ID.
1 - nRegionalIdentifier为代码页
2 - nRegionalIdentifier为字符集

对于nConversion的设置值1、2、3、4、7和8,只有在nRegionalIdentifier=0时支持。

对于设计非英文报表,FontCharSet、网格单位和STRCONV()函数的改进在报表设计时更具灵活性。

打印增强

为了实现更好的打印功能,一些命令和对话框都被进行了增强和改进。SYS(1037)函数现在新增了一个参数,并且具有了返回值;GetFont()函数的对话框使用了新样式;APrinters()函数生成的数组现在具有3列元素。

SYS(1037)函数用于打开Print Setup对话框,以及用于改变VFP的默认打印机。在VFP 9.0的以前版本中,SYS(1037)函数没有实际意义的返回值,不管用户如何操作,总是返回一个空串。即使用户按下了Cancel按钮,你也无法捕获这个操作的信息。

在VFP 9.0中,一个新参数被添加到SYS(1037)中,并且函数具有了返回值,如表1所示。

表1 SYS(1037)的新增参数和返回值

参数描述返回值
SYS(1037)除了可以返回一个具有实际意义的值,其行为与先前版本一样。 0 = 用户取消了操作

1 = 用户选择了OK按钮

SYS(1037,1)如果当前工作区包含一个与FRX匹配的结构,并且没有打印机信息存储在当前工作区中,则打开页面设置对话框。如果用户在对话框中选择了OK按钮,VFP会在临时表的第一条记录的EXPRTAGTAG2字段中写入打印机信息,然后恢复临时表到先前的RECNO()记录位置。

如果当前工作区没有包含相应的结构,则没有对话框被激活,并且返回0。

0 = 用户取消了操作或表结构无效。

1 = 用户选择了OK按钮,对FRX进行了相应的更新。

SYS(1037,2)如果当前工作区包含一个与FRX匹配的结构,VFP的默认打印机信息被写入到第一条记录的EXPRTAGTAG2字段中,然后恢复临时表到先前的RECNO()记录位置。

如果当前工作区不包含与FRX匹配的结构,则没有信息被写入到临时表中,并返回0。

0 = 表结构无效,无动作发生。

1 = VFP的默认打印机信息成功写入到FRX中。

SYS(1037,3)如果当前工作区包含一个与FRX匹配的结构,FRX中的打印环境信息被作为VFP的默认打印机,此外,并将打印环境信息重新写入到FRX中,这就可以防止无效信息的发生。

如果当前工作区不包含与FRX匹配的结构,则没有信息被写入到临时表中,并返回0。

0 = 无动作发生。

1 = VFP从FRX中读取并设置默认打印机信息。

GetFont()

GetFont()函数有如下的一些小改动。

只显示可打印字体

GetFont()的第三个参数现在新增了一个可选值,可以传递P给函数,通知VFP只显示对于默认打印机的可打印字体,如下所示:

=GetFont(' ', 0, 'P')
FontCharSet(字符集)

在以前的VFP版本中,GetFont()的第4个参数用于识别FontCharSet。但是,现在传递01给第4个参数的含义有了一些变化。

  • 传递0,允许使用字符集组合框,明确设置组合框的值为“西方,并返回FontCharSet和其他数据。
  • 传递1,允许使用字符集组合框,设置组合框的值为用户的地区设置值,并返回FontCharSet和其他数据。

在以前的版本中,会忽略第4个参数,并禁止字符集组合框,并且返回值中不包含FontCharSet部分。

APrinters()

APrinters()新增了一个参数,用来搜集打印机的信息。使用可选的第2个参数,会使生成的数组比以前多出3个附加列,如下所示:

lnPrinters = APrinters(laPrinters, 1)

前面的两列与以前版本相同,是打印机名称打印机端口。新增的3列分别是驱动程序注释位置

调用APrinters(),如果不包含可选的第2个参数,则提供与先前版本相同的行为,即:只返回两列。

更具现代化的对话框

Print Setup对话框现在已经被更名为Page Setup,并且更具现代化。Print对话框在Windows 2000和以后的操作系统中也更具现代化。

Page Setup对话框

Page Setup对话框如图34所示,可以使用如下方法打开:

  • 当报表设计器不是WONTOP()时,从File菜单选择Page Setup
  • 当报表设计器是WONTOP()时,从Report Page Setup对话框选择Page Setup按钮。
  • 使用SYS(1037)命令。

图34 新Page Setup对话框代替了旧Print Setup对话框

Print对话框

Print对话框如图35所示,可以使用如下方法打开:

  • File菜单选择Print
  • 在命令中使用TO PRINTER PROMPT子句,如REPORT FORM。

图35 在Windows 2000或更后期的系统中,新的Print对话框更具现代化

数据分组增强

VFP 9.0报表书写器在数据分组方面有一些小的增强。

数据分组最大值

数据分组的最大值已经从20增加到74。

水平列

在以前,报表中超过一列的位置被定义为一个数据分组水平面,浪费了许多空间。第一个位置(第1行,第1列)留下了许多空白,并且数据在第1行的第2列开始。同样的,在每个数据分组之间浪费了一个空白带,如图36所示。即使组标头带区的高度为0,VFP仍旧保留这个空间,如图37所示。带区条

Click here for larger image

图36 以前版本的VFP,在使用数据分组和水平列时浪费了许多的空间

Click here for larger image

图37 VFP的以前版本为组标头保留了空间,即使没有定义任何对象,也是这样

在VFP 9.0中,数据分组和水平列的行为发生了改变。当遇到一个数据分组时,将在下一个整行的第1列打印分组表达式的内容,该行的剩余部分作为遗留空白,并且不再用于打印细节内容。属于该数据分组的细节内容在分组打印行的后面的第1列开始打印,如图38所示。同样的,如果组标头的高度为0,则不再保留任何额外空间,如图39所示。

Click here for larger image

图38 在使用水平列和数据分组时,VFP 9.0不再象以前版本那样浪费空间

Click here for larger image

图39 在组标头带区设置为0高度时,VFP 9.0不再保留额外的空间

这种新行为,虽然避免了先前描述的浪费空间情况,但是可能会损坏一些已存在报表。不过,新行为的一个额外好处是:数据分组带区可以伸展为所有列的宽度,如图40所示。

Click here for larger image

图40 在VFP 9.0中,可以伸展组标头带区为多个列的宽度

多细节带区

除了在VFP 9.0报表书写器中的这些扩展性增强,新增的多细节带区功能是最大的改变,并且在报表中经常需要使用到这样的功能。该新增功能允许为父表的每条记录处理多个子表,一个这种类型报表的示例如图41所示。

Click here for larger image

图41 这个多细节带区示例报表的每个客户具有3个独立的细节带区

表和关系

作为多细节带区,理解父表和子表如何一起工作是理解如何使用这些新增功能的关键。假设要写一个如图41所示的报表,对于这种情况的数据库如图42所示。

图42 一个保险公司的Customer(客户)、Members(成员)、Vehicles(车辆)和Homes(住址)数据库

Customer表是父表,并且为保险公司的每个客户包含一条记录,Members、Vehicles和Homes表是Customer的子表。Members表为每个客户的家庭成员保留一条记录,Vehicles表为每个客户投保的车辆保留一条记录,Homes表为每个客户的住址保留一条记录。

驱动报表

将其中的一个报表用于驱动报表是必需的,在这个示例中,Customer表是驱动表,如果要使用报表的数据环境来定义表,可以设置InitialSelectedAlias属性为该表,如果要使用代码来定义表,要确认在报表运行时Customer表在当前工作区中。

Target Alias(目标别名)

目标别名是用于为一个特定细节带区描述哪个表是驱动表的术语,在这个示例中,Members表是细节带区1的目标别名,Vehicles表是细节带区2的目标别名,Homes表是细节带区3的目标别名。

如果没有为细节带定义目标别名,将使用VFP以前版本的行为,换句话说,细节带区将处理每个父表的记录。但是,如果输入了父表的名称作为目标别名,却会得到非常不同的结果。对于父表中的每条记录,VFP处理父表中的所有记录,即在细节带区打印父表的每个记录。因此,如果有一个具有10条记录的父表,并设置细节带区的目标别名为这个父表,则最终报表会打印10遍这10条记录,总共100条记录。

关系

了解关系在一个多细节带区中如何运作是相当重要的,VFP使用父表和子表之间的关系来定位所有记录,可以使用SET RELATIONSET SKIP来定义这些关系。如果在数据环境中打开了表,并且关系已经被定义在数据库中,则会自动使用这些关系。

如果使用代码打开表,下面的代码演示了如何为Insurance Customer Listing(保险客户列表)来设置表,如图41所示。

*-- 打开子表
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 FORM Insurance PREVIEW

定义多细节带区

缺省情况下,新建立的报表只具有一个细节带区。

添加附加细节带区

附加细节带区可通过如图43所示的Optional Bands对话框添加,要调用这个对话框,可以从Report菜单中选择Optional Bands...。这是与以前Title/Summary相同的对话框,现在被重命名为Optional Bands,该名称更加符合添加附加选项。

图43 使用Optional Bands对话框上的Details微调控制来调节细节带区的总数

可以使用Details微调控制来添加报表所需要的细节带区数量,最多可以为每个报表定义20个细节带区。图44显示了选择3个细节带区后的报表设计器效果。

图44 该示例报表具有3个细节带区

定义Target Alias(目标别名)

目标别名通过Detail对话框赋值给一个细节带区(如图45所示)。该对话框可以从Report菜单中选择Edit Bands...,然后选择适当的细节带区来调用。也可以通过双击细节带区的灰色带区条来打开这个对话框。

图45 在Detail对话框上为每个细节带区定义Target alias

Target alias是一个表达式,因此,应当将表的名称放置在引号中,一旦定义了目标别名,表示细节带区的灰色带区条将显示目标别名,如图46所示。

图46 报表设计器把每个细节带区和一个数值以及与其关联的目标别名结合在一起,所以可以很容易地识别不同细节带区

在建立多细节带区报表时,在字段名称前面加上相应的别名是十分重要的,这可以防止产生字段是来自于哪个表的混乱情况。

标头和脚注

多细节带区的另一个增强功能是可以为每个细节带区增加标头和脚注,这在某些方面类似于组标头和组脚注。对于每个被处理的父记录,发生如下事件:

  • 细节1的标头带区被处理。
  • 细节1带区为与相关联目标别名中的每个子记录处理一次。
  • 细节1的脚注带区被处理。
  • 细节2的标头带区被处理。
  • 细节2带区为与相关联目标别名中的每个子记录处理一次。
  • 细节2的脚注带区被处理。
  • 细节3的标头带区被处理。
  • 细节3带区为与相关联目标别名中的每个子记录处理一次。
  • 细节3的脚注带区被处理。

要打开细节标头和细节脚注带区,可以在每个细节带区的Detail对话框中复选Detail Header/Footer,如图45所示。为了帮助从其他带区中分辨出细节带区,细节带区前面的三角是实心的,其他三角则是空心的,如图47所示。

Click here for larger image

图47 细节带区标以实心三角,其他带区标以空心三角

除了在报表设计器中标识每个细节带区外,Edit Bands对话框也使用带区的连续数字来标明每个细节标头带区、细节脚注带区和细节带区。Edit Bands对话框可以从Report菜单中选择Edit Bands...进行调用,如图48所示。

图48 Edit Bands对话框使用每个细节带区的连续数字来帮助识别每个细节带区、细节标头带区和细节脚注带区

需要注意的是:对于一个特定的细节带区,即使没有细节带区记录存在,相应的细节标头和细节脚注带区仍旧打印,如果不希望细节标头和细节脚注出现这种情况,可以对带区中的每个布局对象使用下面的Print when逻辑条件来屏蔽这种打印操作,并要确认为这些布局对象复选 Remove line if blank选择框。

NOT EOF(<target alias>)

与组标头和组脚注类似,细节标头和细节脚注具有一些相同的选项,如图45所示。Detail对话框具有一些新增选项:

  • Start on a new column(从新列开始): 使用此选项使细节带集从报表的新列开始,注意此选项不允许显式地分配一个细节带集到一个指定列,如果一个细节带集的信息溢出了当前列,它将在下列中继续打印。
  • Start on a new page(从新页开始): 使用此选项使细节带集从一个新页开始打印。
  • Reset page number to 1 for each detail set(每个细节带集重置页号为1):使用此选项和Start
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Visual FoxPro 9.0是一种以数据为中心的编程语言和集成开发环境。它是微软公司开发的一种结构化查询语言(SQL)编程工具,可用于创建和管理数据驱动的应用程序。 Visual FoxPro 9.0具有强大的数据库管理功能,可以通过创建表、索引、视图和查询来管理和操作数据。它支持多种数据类型,如字符、数字、逻辑和日期,并提供了丰富的数据操作功能,例如增删改查等。同时,它还支持通过SQL语句进行复杂的数据查询和操作。 Visual FoxPro 9.0还具有良好的用户界面设计功能,可以创建各种窗体和控件,使用户能够直观地操作应用程序。程序员可以使用Visual FoxPro的集成开发环境进行可视化的界面设计,并通过其丰富的事件模型为控件添加各种行为。 Visual FoxPro 9.0还支持运行时自动更新和部署,使得程序的维护和分发变得更加方便。此外,它还具有强大的报表生成功能,可以生成各种格式的报表,如PDF、Excel等。 Visual FoxPro 9.0的开源社区CSDN提供了丰富的学习资源和技术支持,使用户能够快速入门和解决问题。通过CSDN,用户可以获取与Visual FoxPro相关的教程、博客、论坛和代码示例等信息,与其他开发者交流经验,共同学习和成长。 总之,Visual FoxPro 9.0是一个功能强大的编程工具,可用于创建和管理数据驱动的应用程序。通过CSDN等开源社区的支持,我们可以更好地学习和使用Visual FoxPro,提高开发效率并解决问题。 ### 回答2: Visual FoxPro 9.0是一种集成开发环境,是由微软公司开发的一种数据库管理系统。它是一种基于面向对象的编程语言,用于开发Windows平台下的数据库应用程序。 在Visual FoxPro 9.0中,我们可以使用其强大的编程功能来创建和管理数据库的表、索引和关系。它提供了丰富的数据类型,包括字符型、数字型、日期型等,使得我们可以更加灵活地存储和处理数据。 Visual FoxPro 9.0还拥有强大的查询语言,可以通过编写SQL语句来对数据库进行高效的数据检索和筛选。同时,它还支持嵌套查询、联合查询等高级查询操作,满足了复杂业务场景的需求。 除了数据库操作,Visual FoxPro 9.0还具备图形用户界面的设计和开发能力。我们可以使用其自带的表单设计器来创建用户界面,并通过编写代码来实现界面与数据库之间的交互。这使得我们能够轻松地开发出功能强大、操作友好的数据库应用程序。 此外,Visual FoxPro 9.0还支持网络编程,可以使用TCP/IP协议进行网络通信,实现多用户同时访问数据库的需求。 总之,Visual FoxPro 9.0是一种强大的集成开发环境,具备丰富的数据库管理和编程功能。它成为了许多开发者首选的工具,用于开发Windows平台下的数据库应用程序。 ### 回答3: Visual FoxPro是一种面向对象的数据库编程语言和集成开发环境,是由微软开发并于2007年停止更新的。Visual FoxPro 9.0是其最后一个版本,它引入了许多新的功能和改进。 Visual FoxPro 9.0具有强大的数据库处理能力,可以连接多种类型的数据库,并通过集成的数据库引擎进行高效的数据操作。它支持SQL查询和索引,可以实现复杂的数据处理和分析。 Visual FoxPro 9.0还拥有丰富的开发工具和组件,使开发者能够快速建立视觉化的用户界面,并且可以定制界面风格和功能。它提供了大量的用户界面控件和命令,可以轻松地实现图形化的应用程序。 此外,Visual FoxPro 9.0还具有强大的报表生成功能,可以根据数据生成各种类型的报表,并支持自定义报表样式和格式。 Visual FoxPro 9.0的开发也非常方便,它内置了丰富的开发工具和调试器,可以帮助开发者快速编写和调试代码。它还支持面向对象的编程模式,可以提高代码的可重用性和扩展性。 综上所述,Visual FoxPro 9.0是一种功能强大的数据库编程语言和开发环境,适用于各种类型的应用程序开发。它具有丰富的数据库处理能力、强大的报表功能和方便的开发工具,能够帮助开发者快速开发出高质量的应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值