译者:​Fbilo

VFP 开发组在对运行时增强工作的时候有几个目标,其中包括:

  1. 处理更多的报表输出类型,而不仅仅是打印和预览;
  2. 为报表输出使用 GDI+。这提供了一些显著的增强,比如精确得多的报表绘制、图像和字体的平滑缩放、以及象文本旋转那样的额外能力。
  3. 提供一个更灵活的多得、可扩展得报表系统;
    在 VFP 9 以前,报表引擎是庞大的:它处理每一件事情-数据处理、对象定位、绘制、预览以及打印。此外,还有一些例外(字段中的UDF、组、变量表达式、带区的 OnEntry 和 OnExit 表达式等等),你不能在一个报表运行的过程中与它进行交互。

在 VFP 9 中新的报表引擎已经将责任拆分成了几块,报表引擎现在只负责数据处理和对象定位,一个新的对象 report listener 负责处理绘制和输出。由于 Report listener 是类,现在你可以以各种过去你只能梦想的方式来与报表输出过程进行交互。

VFP 9 同时包含了新旧两个报表引擎,因此你可以根据需要选择在哪个报表引擎下运行你的报表。不过,一旦你认识到了新报表引擎的好处,除非绝对必要,否则你是不会想再回头使用旧样式报表的。

新报表语法

VFP9支持使用就报表引擎运行报表;只要简单的使用跟过去一样的 REPORT 命令(尽管你可以使用一个新的命令来覆盖 REPORT 的行为,稍后你会看到)。为了获得新样式的报表行为,请给 REPORT 命令使用新的 OBJECT 子句。OBJECT 支持两种使用它的方式:通过指定一个 Report listener 或者指定一个报表类型。Microsoft 把它叫做“支持对象”的报表。

一个 Report listener 是一个提供新样式报表行为的对象。Report listener 基于的是 VFP 9 中一个新的基类 ReportListener。要告诉 VFP 去为一个报表使用一个指定的 listener,可以先建立这个 listener 类的实例,然后在 REPORT 命令的OBJECT子句中指定这个对象的名称。这里是一个例子:

loListener = createobject('MyReportListener')
report form MyReport object loListener

如果你不喜欢手动建立一个 listener 的实例,你可以通过指定一个 OBJECT TYPE 来让 VFP 自动为你生成一个:

report form MyReport object type 1

这些定义了的对象类型是:0 表示输出到一台打印机,1 为打印预览,4 为 XML 输出,5 为 HTML 输出。你还可以定义你自己的对象类型。

当你以这种方式运行一个报表的时候,在新的系统变量 _REPORTOUTPUT 中指定的那个应用程序(默认是 VFP 主目录下的 ReportOutput.APP)被调用,由这个应用程序来负责弄清楚应该为被指定的 OBJECT TYPE 建立哪个 listener 类的实例。

你可能就会想了:“可我的应用程序中有着成吨的报表。难道我得在整个应用程序中去搜索并修改每个 REPORT 命令吗?”。你走运了,有一个简单的办法可以避免这种麻烦:打开 SET REPORTBEHAVIOR 90 这个开关,可以将支持对象的报表设为默认。这就意味着当你使用 TO PRINT 子句的时候,REPORT 命令会表现得好像你指定了 OBJECT TYPE 0;当你使用了 PREVIEW 子句的时候,REPORT 命令会表现得好像你指定了 OBJECT TYPE 1。SET REPORTBEHAVIOR 80 则恢复到 VFP 8 以及更早版本的行为。如果在你应用程序中的大部分或者全部报表都能在支持对象模式下正常运行,那么可以选择在应用程序启动的时候 SET REPORTBEHAVIOR 90。由于新旧样式的报表在绘制方面的不同,你也许会需要对某些报表进行调整以使它们能在新样式报表系统下正常工作,因此或者对它们进行调整或者使用 SET REPORTHAVIOR 80 来运行这些报表。参见 VFP 帮助文件开头部分的“What’s New in Visual FoxPro”主题下的“Changes in Functionality for the Current Release”一节,以了解在向后兼容模式和支持对象模式两者在绘制上的区别。

ReportOutput.APP 主要是一个对象工厂(Object factory,一种设计模式);它为报表建立与其相配的 listener 的实例。它还包括一些提供 XML 和 HTML 输出的 listener。不过,由于它只是一个 VFP 应用程序,所以你可以通过设置 _REPORTOUTPUT 来把它替换成你自己的应用程序。请在发布你的应用程序给你的用户时确保带上了 ReportOutput.APP(或者你自己所做的对它的替代品),这样你的应用程序才能使用支持对象的报表。

  • 在第七章“在运行时扩展报表系统”中会讨论更多关于 ReportOutput.APP 和 report listener 的细节。

现在让我们来看一下运行时增强的某些特点。

新的预览窗口

匆匆一看,在图25中显示的 VFP 9 预览窗口看上去好像跟过去版本中的它并没多少不同。不过,请仔细看一下这里面的工具栏。

注意这个工具栏里面现在有一些新的按钮允许你去指定一次显示几页。图26展示了一次显示四页的情况(你必须把这个报表的缩放比例调整到25%以一次看到全部这四页)。

还有你要注意的是:现在你可以将报表放到到超过100%了:200、300和500%都支持。这在新旧样式的预览窗口中都有效。不过在缩放比例很高的时候,旧样式预览窗口显示的是有锯齿的文本、而新样式预览窗口显示的是平滑的文本;这里正好演示了 GDI+ 相对于 GDI 的优点。另一个新特色是一个快捷菜单,它的菜单项重复了工具栏上这些功能,加上允许你显示或者隐藏工具栏。

最后,试一下下面这个:

_screen.Forms[2].Caption = 'This is my report'

这是对的——预览窗口是一个 VFP 表单而不是一个纯粹的窗口。这就意味着你可以完全控制它的表现,而想在过去版本中这么做可是有点痛苦的。当你在支持对象模式下运行一个报表的时候,该预览窗口将被使用;否则,被用到的将是以前版本 VFP 中的同一个窗口。

VFP 9 有一个新的系统变量 _REPORTPREVIEW,用于为报表指定一个提供预览窗口的 VFP 应用程序。默认情况下,该变量指向的是在 VFP 主目录下的 ReportPreview.APP,但你如果需要的话可以把它替换成你自己的应用程序。你也可以用其它方式指定用于输出的这个表单;不过要讨论具体怎么做就超出本章的范围了。跟其它新的 VFP 模块一样,如果你的应用程序要使用新的报表预览窗口,请确保为了它而在发布的安装包中包含 ReportPreview.APP 或者你自己对它的替代品。

进程反馈

当一个报表运行时间很长的时候,你也许需要有一种途径告诉你的用户正在发生什么事情。这个任务ReportOutput.APP 中内建的 UpdateListener 类可以做到,当报表正在处理中的时候它能显示其进度,并提供 Cancel 的能力(见图27)。你可以根据需要禁用这个功能、或者使用一个 report listener 来提供你自己的(进度控制)。在第七章“在运行时扩展报表系统”中有它的一个示例。


图27、UpdateListener 类显示一个报表的进度,并给予用户 Cancel 的能力
HTML 和 XML 输出

尽管从过去几个版本开始你就可以使用 GenHTML.PRG 来将一个报表输出到 HTML,可坦白的说,结果不怎么样。幸运的是,在 VFP 9 中,你可以使用在 ReportOutput.APP 中内建的某些 listener 来建立高质量的 HTML 和 XML 输出了。

Listener type 5 指定 HTML 输出,而 type 4 用于 XML 输出,因此你可以使用下面的命令来输出到 HTML:

report form MyReport object type 5

不过,这里并没有给予你对要建立的文件名称或者其它设置的控制。(如果你要控制的

下面的代码(取自XMLOutput.PRG)用 EmployeesMD 报表的开头六页建立一个名为 MyReport.XML 的 XML 文件,只包含数据。在这个案例里使用了 ReportOutput.App 中的 XMLListener 类(type 4)。

loListener = .NULL.
do (_reportoutput) with 4, loListener
loListener.TargetFileName = 'MyReport.xml'
loListener.QuietMode = .T.
loListener.XMLMode = 0     && 0 = data only, 1 = layout only, 2 = both
report form EmployeesMD object loListener range 1, 6

图28、VFP 9 提供了来自报表的高质量 HTML 输出
图29、使用 XMLListener 类,你可以为一个报表建立只包含数据、只包含报表布局、或者同时包含前两者的 XML

HTML 输出其实是先使用 XML Listener 来生成 XML,然后使用 XSLT 来生成最终的 HTML 结果。

这两种 listener 类都有着一些你可以用来更多的控制输出的其它属性。参见 VFP 帮助文档以了解更多详情。

图形文件输出

有了一个 Report listener,你还可以输出到一个图形文件。VFP 9 支持 EMF、TIFF(单页和多页)、JPG、BMP、PNG以及GIF。第三方的 listener 也可以支持其它格式的文件。

这里是一些简单的代码,取自 GraphicOutput.PRG,它输出 EmployeesMD 报表中的一页到一个 GIF 文件。图30 展示了这个生成的 GIF 文件。

loListener = createobjet('ReportListener')
loListener.ListenerType = 3
report form EmployeesMD object loListener range 1,1
loListener.OutputPage(1, 'MyReport.gif',104) && 104=GIF

比如这个 GIF 图像
参见第七章“在运行时扩展报表系统”以了解关于这个主题的详情。

PDF怎么办?

当然了,你现在该问“PDF怎么办?”了。VFP 9 支持的输出中还没包括 PDF。不过,目前有几种你可以从 VFP(包括9.0以及以前的版本)获得PDF输出的途径:

  1. 使用 Adobe Acrobat 或者象 Print2PDF 这样的别的PDF编辑器;
  2. 使用一个支持 PDF 输出的 VFP 专用第三方工具,比如 Mind’s Eye 报表引擎、XFRX、或者 FRX2Any。大多数这些工具的开发人员正在、或者已经完成了他们的工具的 VFP 9 版本。
  3. 通过指定打印到一个适当的驱动来输出一个 PostScript 文件,然后使用免费软件 GhostScript 工具来将它转换成一个 PDF 文件。

其它打印增强

在 VFP 9 中有着大量的其它通用打印增强。
显示页设置对话框的 SYS(1037) 有了一些新的功能。首先,这个对话框看上去就跟过去的不一样了:

图31、在 VFP 9 中(右边的图)的 SYS(1037)跟它在 VFP8 中的对应物(左边的图)相比,有着更摩登的界面

其次,它现在有了一个返回值,可以指示用户在这个对话框里是按下了 OK(“1”)还是 Cancel(“0”)。

然而,最大的变化是,现在你可以传递一个参数给它来告诉它该干什么。传递给它0或者不传递参数给它将显示默认的页设置对话框。要为一个特定的报表显示、并可能会改动页面设置,请将该报表作为一个表来打开(就是 USE MyReport.FRX),然后调用 SYS(1037,1)。你可以使用SYS(1037,2)(该命令将默认的打印机设置写入到被作为一个表打开在当前工作区中的一个FRX 文件中)和 SYS(1037,3)(该命令将默认的打印机设置设置为那些在一个打开在当前工作区中的FRX文件中的信息)来保存或者恢复默认打印机信息;这两个命令都不会显示页面设置对话框。它们通常被用来推入和弹出打印机设置。

APRINTERS()现在可以接收一个新的可选参数1,在这种情况下结果数组有三个列,分别显示驱动器、注释、和位置。

象 SYS(1037)对话框一样,当你在 REPORT 命令中使用 PROMPT 关键词时被显示的打印对话框有了一个更摩登的表现(图32)。

图32、在 VFP 9 中随 REPORT 命令的 PROMPT 子句显示的对话框(右边的图像)比 VFP 8 中的(左边的图)有着更摩登的界面

总结

VFP 9 在报表引擎上改动的数量令人难以置信。这些改动使你可以更轻松的使用报表编辑器、使得建立你过去无法或者很难做到的类型的报表成为了可能,并提供了新类型的输出。此外,VFP 开发组还为在设计时和运行时扩展报表引擎的能力提供了至关重要的钩子;我们将在接下来的两章中讨论这方面的细节。你可以期待着发现 VFP 报表的大量新用法,并且将来还会发现更多。

更多资料:www.sn58.cn

〔连载〕VFP9增强报表-运行时能力的增强相关推荐

  1. Cocoa 框架 For iOS(一) 框架的介绍,Objectivie-C运行时能力的解析等 (转载)

    http://blog.csdn.net/totogo2010/article/details/8081253 Cocoa框架是iOS应用程序的基础,了解Cocoa框架,对开发iOS应用有很大的帮助. ...

  2. java 获取运行时参数,Java8增强反射可以在运行时获取参数名

    技术公众号:Java In Mind(Java_In_Mind),欢迎关注! 原文:Java8增强反射可以在运行时获取参数名 介绍 在JDK增强意见:JPE 118:Access to Paramet ...

  3. js版palppy brid代码_从 JS 引擎到 JS 运行时(上)

    V8 和 Node.js 的关系,是许多前端同学们所津津乐道的--浏览器里的语言,又兼容了浏览器外的环境,两份快乐重叠在一起.而这两份快乐,又带来了更多的快乐--但你有没有想过,这两份快乐到底是如何重 ...

  4. 云原生运行时的下一个五年

    文|马振军(花名:古今 ) 在基础架构领域耕耘多年 目前在蚂蚁集团中间件团队 负责 MOSN.Layotto 等项目的开发工作 校对|卓与.齐天 本文 9053 字 阅读 18 分钟 |前言| 在过去 ...

  5. 蚂蚁云原生应用运行时的探索和实践 - ArchSummit 上海

    点击上方"程序猿技术大咖",关注并选择"设为星标" 回复"加群"获取入群讨论资格! Mesh 模式的引入是实现应用云原生的关键路径,蚂蚁集团 ...

  6. VFP在运行时扩展报表系统,这是报表转换任意格式的秘决

    VFP在运行时扩展报表系统,这是报表转换任意格式的秘决 译者:Fbilo.其实你只要掌握了VFP9的报表系统,你就可以开发出报表转任意的文件格式. 除了在第六章"在设计时扩展报表系统&quo ...

  7. .net报表控件ActiveReports教程:运行时修改数据(附源码)

    ActiveReports 是一款专注于 .NET 和 .NET Core 平台的报表控件.通过拖拽式报表设计器,可以快速地设计 Excel表格.Word文档.图表.数据过滤.数据钻取.精准套打等类型 ...

  8. ActiveReports中如何在后台导出运行时绑定数据源报表

    ActiveReports支持运行时绑定数据源功能,这种绑定数据源方法使用较为普及,然而很多系统中都需要在后台导出报表文件,所以用户就很困惑,ActiveReports中如何在后台导出运行时绑定数据源 ...

  9. 如何实现 JS 运行时的 Inspector 能力

    前言:无论什么语言,调试能力都是非常重要的,像 C.C++ 等语言,我们可以使用现成的工具去调试.JS 也不例外,我们可以通过浏览器来实现对 JS 的调试,但是 JS 运行时就不太一样了,因为 JS ...

最新文章

  1. opencv各版本 IplImage Mat 转换
  2. java camel dsl,Apache Camel与Spring DSL
  3. 什么是尾递归?测试python尾递归
  4. 算法与数据结构(python):递归
  5. orb-slam2在PC和ARM上运行
  6. Keepalived时主备负载均衡器都有VIP的问题:VRRP协议问题
  7. 一次Web请求返回406原因与解决方案
  8. 高通-物理专线2.0新版资费计划
  9. C++算法学习(分支限界法)
  10. Cocos2d-x特殊节点对象(瓦片地图、粒子系统、视差滚动)概述
  11. Qt配置使用VS2010进行开发
  12. LACP链路聚合控制协议
  13. 基于MYSQL的新闻发布系统数据库设计项目实战
  14. 锯齿波调制的FMCW雷达中频回波信号的公式推导
  15. Rust 学习3, 枚举,集合
  16. Android静态壁纸和动态壁纸的使用和理解
  17. 如何快速搭建一个 “简单模式” 的微服务架构
  18. 性能测试基础——内存
  19. java程序设计实践教程张永常_java程序设计实用教程
  20. 正则表达式转NFA,DFA,最小化DFA

热门文章

  1. 如果父母依旧辛苦,那我们的成长又有什么意义?
  2. Aspose.PDF for Java 21.4 Crack
  3. 《初级会计电算化实用教程(金蝶ERP—K/3版)》一1.2 会计电算化发展概况
  4. 麦肯锡:13家银行去年经济利润为负 银行业需实施九大转型
  5. leetcode股票问题
  6. 工厂人员定位系统如何实现工厂数字化转型
  7. 修改Eclipse .eclipse和.p2位置
  8. [学习笔记] Pell方程
  9. Memcache的分布式介绍
  10. Mysql B+树索引