建立自己的报表预览程序

来源:互联网 发布:dysin python 编辑:程序博客网 时间:2024/05/13 08:58

建立自己的报表预览程序

作者:张洪举 Microsoft Visual FoxPro MVP (http://www.vfptop.com)

日期:2005年10月

应用于:Microsoft Visual FoxPro 9.0

目录

概述

Visual FoxPro 9.0 的报表预览应用程序接口

建立自己的报表预览程序

使用建立的报表预览程序预览报表

 

概述

可以通过 ReportListener 的 PreviewContainer 属性指定一个自定义报表预览程序,来代替 Visual FoxPro 默认的 ReportPreview.app 程序。

在 Visual FoxPro 的辅助对象模式下预览一个报表或标签时,ReportListener 需要一个附加的组件来提供预览界面,这个组件被称为预览容器。预览容器是用 Visual FoxPro 代码编写的,因此用户可以自己建立预览容器。

ReportListener 可以通过 ReportListener 的 PreviewContainer 属性指定一个预览容器对象,也可以通过 _REPORTPREVIEW 系统变量指向一个预览容器对象。_REPORTPREVIEW 的默认值为 ReportPreview.App,ReportPreview.App 是 Visual FoxPro 的默认报表预览程序。

Visual FoxPro 9.0 的报表预览应用程序接口

建立自定义报表预览程序一个很重要的问题,是如何获得对 ReportListener 对象的引用,从而控制 ReportListener 的行为。为了实现这个目的,在你建立的报表预览程序中必须包含一个名为 SetReport 的方法,ReportListener将通过该方法将自身引用传递给你的预览程序。该方法的语法格式如下:

PROCEDURE SetReport

LPARAMETER oListenerRef

oListenerRef 参数便是对 ReportListener 对象的引用,你可以通过该参数,将对 ReportListener 对象的引用保存到一个属性或变量中。

同时,在你建立的报表预览程序中还必须包含一个名为 Show 的方法,ReportListener 在报表绘制完毕后将调用该方法进行报表显示。假设已经建立了一个 ControlPreview 类作为我们的预览容器,下面是调用该类时的代码。

lcReport=HOME(2)+"Solution/Europa/EmployeesMD.frx"
oListener = CREATEOBJECT('ReportListener')  &&建立ReportListener对象,并保存到oListener变量中
olistener.ListenerType = 1  &&设置输出模式
oListener.OutputType = 1
 
*!* 下面的代码用于指定预览容器 
olistener.PreviewContainer=NEWOBJECT("ControlPreview","AdditionSamples.vcx")  
 
*!* 下面的 REPORT FORM 命令将开始执行报表,同时将执行 ControlPreview 的 SetReport 方法,
*!* 传递 ReportListener 对象引用给 ControlPreview,但是由于此时报表还未绘制完毕,所以并不
*!* 能获得报表的总页数、页面高度等信息。在绘制完毕后,ReportListener 将调用 ControlPreview
*!* 的 Show 方法,进行预览输出,由于此时报表已经准备完毕,所以你可以在 Show 方法中获得
*!* 报表的页面高度等信息
REPORT FORM (lcreport) OBJECT oListener NOWAIT

建立自己的报表预览程序

我们将通过下面的示例来说明建立自己报表预览程序的方法,任何报表都可以使用该程序进行预览输出。为了更好地说明这个预览程序的功能,首先来看一下设计完成后的执行效果,如图1 所示。通过这个预览程序,可以设置报表的显示百分比、通过导航或直接定位要预览的页,以及指定报表的打印范围。

图1 报表预览程序界面

1)建立基于 Form 的类

在 Visual FoxPro 的 Command 窗口中执行 CREATE CLASS 命令,打开如图2 所示的 New Class(新建类)对话框。设置新建类的名称为 ControlPreview,基于 Form 类,存储在 AdditionSamples.vcx 类库中。

设置完成后单击 OK 按钮,将打开 Class Designer (类设计器)对话框,最终设计结果如图3 所示

  

图2 New Class 对话框

图3 ControlPreview 类最终设计结果

2)表单的关键属性设置

表单的关键属性设置如表1所示。

1

对象

属性

说明

ControlPreview

(表单)

AllowOutput

.F.

不允许将“?”等命令显示输出到该表单中

nCurrentPage

1

自定义属性。储存当前正在显示的报表页号

nPageHeight

100

自定义属性。存储当前报表页面的高度

nPageWidth

100

自定义属性。存储当前报表页面的宽度

oListener

.NULL.

自定义属性。存储通过 SetReport 方法传递给该程序的对 ReportListener 对象的引用

ScrollBars

3

设置表单根据需要显示水平和垂直滚动条

cboPer

RowSourceType

1

RowSourceType 和 RowSource 用于设置组合框中可用的报表显示百分比

RowSource

25,50,100,150,200,500

 

cmdTop

Caption

|<

该按钮用于导航到报表的第一页

cmdPrev

Caption

该按钮用于导航到报表的上一页

cmdNext

Caption

该按钮用于导航到报表的下一页

cmdBott

Caption

>|

该按钮用于导航到报表的最后一页

cmdPage

Caption

指定页

该按钮用于显示 txtPage 文本框中指定的报表页

txtPage

Value

1

该文本框用于显示当前预览页面的页号,也可以在其中输入一个页号,然后单击 cmdPage 按钮定位到该页

optPrint

ButtonCount

2

该对象是表单中的选项按钮组,具有2个按钮

BorderStyle

0

不具备边框

Value

1

默认选定第一个按钮

Option1.Caption

打印所有页

选定该按钮后,表单中的 txtFrom 和 txtTo 文本框将变为禁止状态

Option2.Caption

打印指定页

选定该按钮后,表单中的 txtFrom 和 txtTo 文本框将变为可用状态

txtFrom

Value

1

默认值为1

Enabled

.F.

在表单启动时,默认为禁止状态

txtTo

Value

1

默认值为1

Enabled

.F.

在表单启动时,默认为禁止状态

cmdPrint

Caption

打印(/<P)

该按钮根据打印选择输出报表到打印机中

cmdClose

Caption

关闭

该按钮用于关闭表单

shpPreview

 

 

用于显示报表的形状对象

3)预览程序的初始化设置

在预览程序的初始化部分,需要获得对 ReportListener 对象的引用,然后通过这个引用,获得报表的页面尺寸,进而设置表单中 shpPreview 对象的大小。

预览程序的初始化设置不能在表单的 Init 事件进行,因为在该类实例化的时候,有可能 ReportListener 对象还未建立,或者 ReportListener 还未进行报表处理,所以此时你无法获得报表的任何信息。根据前面的介绍,ReportListener 是通过预览程序的 SetReport 方法将 ReportListener 传递给预览程序的。因此,在表单中需要新建一个 SetReport 方法,代码如下:

LPARAMETERS oListenerRef

This.oListener = oListenerRef   &&将对ReportListener对象的引用保存到表单的oListener属性中

ReportListener 在报表绘制完成后,将调用预览程序的 Show 方法显示表单。由于此时报表已经绘制完成,所以可以在此方法中获得报表页面的高度、宽度值,进而设置 shpPreview 对象的大小。由于表单对象默认地具有 Show 方法,因此,只需要在该方法中填入下列代码即可。

LPARAMETERS nStyle

WITH This

    IF VARTYPE(.oListener) = "O"

        .nPageHeight = .oListener.GetPageHeight() / 10   &&获得页面的像素高度(每英寸96DPI

        .nPageWidth = .oListener.GetPageWidth() / 10    &&获得页面的像素宽度

        .shpPreview.Height = INT(.nPageHeight)        &&设置形状的高度

        .shpPreview.Width = INT(.nPageWidth)         &&设置形状的宽度

        .Caption = "报表预览程序-" + .oListener.CommandClauses.File  &&标题中包含有报表的文件名称,见图13-68

        .Refresh

    ENDIF

ENDWITH

 

DODEFAULT(nStyle)  &&执行默认的Show方法行为

4)报表显示比例设置

在表单的 cboPer 组合框的 InteractiveChange 事件中包含有下列代码,用于根据选择的显示比例设置 shpPreview 形状的大小,然后重新输出报表。

WITH Thisform

    IF VARTYPE(.oListener) = "O"

        .shpPreview.Height = INT(.nPageHeight * VAL(.cboPer.Value) /100)

        .shpPreview.Width = INT(.nPageWidth * VAL(.cboPer.Value) /100)

        .oListener.OutputPage(.nCurrentPage, .shpPreview, 2) 

    ENDIF

ENDWITH

5)报表导航设置

“|<”按钮用于导航到报表的第一页,其 Click 事件代码如下:

WITH Thisform

    .nCurrentPage = 1

    .oListener.OutputPage(1, .shpPreview, 2)  &&显示第一页

    .CmdRefresh()                &&设置按钮的可用状态

    .txtPage.Value = 1

ENDWITH

“<” 按钮用于导航到当前报表的上一页,其 Click 事件代码如下:

WITH Thisform

    .nCurrentPage = .nCurrentPage - 1  &&当前报表页号减1

    .oListener.OutputPage(.nCurrentPage, .shpPreview, 2)  &&显示指定页

    .CmdRefresh()      &&设置按钮的可用状态

    .txtPage.Value = .nCurrentPage

ENDWITH

“>”按钮用于导航到当前报表的下一页,其 Click 事件代码如下:

WITH Thisform

    .nCurrentPage = .nCurrentPage + 1  &&当前报表页号减1

    .oListener.OutputPage(.nCurrentPage, .shpPreview, 2)  &&显示指定页

    .CmdRefresh()      &&设置按钮的可用状态

    .txtPage.Value = .nCurrentPage

ENDWITH

“>|”按钮用于导航到报表的最后一页,其 Click 事件代码如下:

WITH Thisform

    .nCurrentPage = .oListener.OutputPageCount

    .oListener.OutputPage(.nCurrentPage, .shpPreview, 2)  &&显示最后一页

    .CmdRefresh()                &&设置按钮的可用状态

    .txtPage.Value = .nCurrentPage

ENDWITH

指定页”按钮用于导航到在txtPage文本框中指定的页号,其 Click 事件代码如下:

WITH Thisform

    IF .txtPage.Value >= 1 AND .txtPage.Value <= .oListener.OutputPageCount

        .nCurrentPage = .txtPage.Value

        .oListener.OutputPage(.nCurrentPage, .shpPreview, 2)

        Thisform.CMDRefresh

    ELSE

        =MESSAGEBOX("页号无效或已经超出了总页数",0+48,"提示")

    ENDIF

ENDWITH

上面5个按钮的Click事件中都使用了表单的自定义方法 CMDRefresh 来控制“|<”、“<”、“>”和“>|”按钮的可用性,该方法的代码如下:

WITH This

    .cmdPrev.Enabled = VARTYPE(.oListener) = 'O' and .nCurrentPage > 1

    .cmdNext.Enabled = VARTYPE(.oListener) = 'O' and ;

        .nCurrentPage < .oListener.OutputPageCount

    .cmdTop.Enabled = VARTYPE(.oListener) = 'O' and .nCurrentPage > 1

    .cmdBott.Enabled = VARTYPE(.oListener) = 'O' and ;

        .nCurrentPage < .oListener.OutputPageCount

ENDWITH

6)打印设置

选项按钮组 optPrint InteractiveChange 事件中包含有下列代码,用于控制 txtFrom txtTo 文本框的可用性。

IF This.Value = 1

    Thisform.txtFrom.Enabled = .F.

    Thisform.txtTo.Enabled = .F.

ELSE

    Thisform.txtFrom.Enabled = .T.

    Thisform.txtTo.Enabled = .T.

ENDIF

“打印”按钮的 Click 事件代码如下所示。在执行打印后,将关闭表单。请注意其中的 .oListener.PreviewContainer = .NULL. 代码,在执行 RELEASE Thisform 命令前,必须首先使用该代码释放对预览程序对象的引用,否则是无法关闭表单的。对于打印页范围的选择,是通过 CommandClauses 属性的 PrintRangeFrom PrintRangeTo 成员来实现的,有关这方面的信息请参考 Visual FoxPro 帮助。

WITH Thisform

    DO CASE

        CASE .optPrint.Value = 1  &&打印所有页

             .oListener.CommandClauses.PrintRangeFrom = 1

             .oListener.CommandClauses.PrintRangeTo = .oListener.OutputPageCount

             .oListener.PreviewContainer = .NULL.   &&取消对预览程序对象的引用

             .oListener.OnPreviewClose(.T.)    &&输出到打印机

             .oListener = .NULL.

         

        CASE .optPrint.Value = 2

             IF .txtFrom.Value < 1 OR ;

                 .txtFrom.Value > .oListener.OutputPageCount

                 =MESSAGEBOX("开始页号设置无效!", 48, "提示")

                 RETURN

             ENDIF

             IF .txtTo.Value < 1 OR ;

                 .txtTo.Value > .oListener.OutputPageCount

                 =MESSAGEBOX("终止页号设置无效!", 48, "提示")

                 RETURN

             ENDIF

             IF .txtFrom.Value <= .txtTo.Value

                 .oListener.CommandClauses.PrintRangeFrom = .txtFrom.Value

                 .oListener.CommandClauses.PrintRangeTo = .txtTo.Value

                 .oListener.PreviewContainer = .NULL.   &&取消对预览程序对象的引用

                 .oListener.OnPreviewClose(.T.)  &&输出到打印机

                 .oListener = .NULL.

             ELSE

                 =MESSAGEBOX("开始页号必须小于或等于终止页号!", 48, "提示")

             ENDIF

       

    ENDCASE

 

    RELEASE Thisform    &&关闭表单

ENDWITH

7)报表的重绘设置

在调整表单大小时,表单中的对象会被重新绘制,这时候需要重新输出报表到表单的形状对象 shpPreview 中,否则,重绘后的形状对象中将不再有报表显示。

在表单的Paint事件中加入下列代码,用于重绘时的报表输出。

WITH This

    IF VARTYPE(.oListener)="O"

        .oListener.OutputPage(.nCurrentPage,.shpPreview,2)

    ENDIF

ENDWITH

8)表单关闭设置

在表单关闭前,首先要释放 ReportListener 的 PreviewContainer 属性对报表预览程序对象的引用,否则,该表单无法关闭。在表单的 QueryUnload 事件中包含有下列代码,当单击表单标题栏的关闭框时,将执行该事件中的代码。

WITH This

    IF VARTYPE(This.oListener) = 'O'

        .oListener.PreviewContainer = .NULL.   &&释放对报表预览程序对象的引用

        .oListener.OnPreviewClose(.F.)  &&关闭预览

    ENDIF

    .oListener = .NULL.

ENDWITH

表单中“关闭”按钮的 Click 事件与表单的 QueryUnload 事件代码基本相同,如下所示。

IF VARTYPE(Thisform.oListener) = 'O'

    Thisform.oListener.PreviewContainer = .NULL.

    Thisform.oListener.OnPreviewClose(.F.)  

ENDIF

Thisform.oListener = .NULL.

 

RELEASE Thisform

使用建立的报表预览程序预览报表

至此,这个报表预览序就设计完毕了,使用这个报表预览程序进行输出的代码如下:

lcReport=HOME(2)+"Solution/Europa/EmployeesMD.frx"

oListener = CREATEOBJECT('ReportListener')  &&建立ReportListener对象,并保存到oListener变量中

olistener.ListenerType = 1  &&设置输出模式

oListener.OutputType = 1

olistener.PreviewContainer=NEWOBJECT("ControlPreview","AdditionSamples.vcx")  &&指定预览程序

REPORT FORM (lcreport) OBJECT oListener NOWAIT

原创粉丝点击