计算机应用
COMPUTER APPLICATIONS
1999年 第19卷 第6期 Vol.19 No.6 1999



PowerBuilder的若干公用对象设计
李振华　吕国斌　墙芳躅
　　摘　要　在PowerBuilder开发过程中，将常用操作做成公用对象，并存入公用库（.pbl）中，这种设计方法有利于提高程序的可重用性和可维护性。设计公用对象的一种方法及其设计实例在本文中作了探讨。
　　关键词　PowerBuilder，公用对象，公用库
引言
　　PowerBuilder作为主要的数据库前台开发语言，已得到了广泛的应用。但在实际的开发过程中，特别是在大型的开发项目中，某些操作总会多处重复出现，比如查询、打印等操作，几乎在每一个窗口里都会出现。如果每出现一次这样操作都相应的为其写一次程序的话，那么，这些不同窗口中的程序是相似的甚至是重复的，这既增加了程序的编写工作量，又增加了程序的维护工作量。一种可行的方法是将这些常用操作做成公用对象，并存入公用库（.pbl）中，这样，在程序设计时便可直接地调用或使用这些对象。这种做法既提高了程序的可重用性和程序编制效率，又提高了程序的可维护性。
1　设计思想
　　公用对象的设计难点在于其通用性的设计：能普适几乎所有的操作要求，同时其程序设计又必须保持独立。本文所提出的方法是采用参数传递：公用对象只针对入口参数进行设计，使用或调用公用对象时再向其传入具体的参数，这样，公用对象的设计便可与具体的应用设计相互独立。当然，采用此种方法，设计的关键就在于传递参数的选择及其处理。
2　几个设计实例
　　以下将要讨论的几个公用对象按其性质可以分为两类：窗口和自定义控件。相应的，它们的使用方式也不相同，公用窗口需带参数的调用；而控件则可直接在父窗口中被使用。以下分述之。
2.1　窗口类
2.1.1　查询窗口
　　查询窗口的设计流程是：在获取了被查询数据窗口的有关参数后，即弹出本窗口，由用户在本窗口
中构造出检索表达式（或称条件表达式，同where子句），并将此表达式回送原数据窗口进行过滤，并在原数据窗口中得到用户所需的查询结果。
　　在使用查询窗口前，需知道被查询窗口的有关参数。因此须先定义一公用函数，以获取数据窗口的有关参数。
　　. 数据窗口参数获取函数
　　本函数获取数据窗口以下参数：所有的字段名及其数据类型和标识。
　　定义如下:
　　入口参数：数据窗口控件名（类型Reference）。返回值：字符串。
　　设计步骤如下(限于篇幅，仅给出关键的实现语句)：
　　① 得到数据窗口中字段个数。
i—ColCount = Integer(dw—1.Describe(′DataWindow.Column.Count′))[ ZK)〗 
　　其中dw—1为欲检索的数据窗口对象。
　　② 建立循环，以第1步得到的字段个数为循环次数，依次得到数据窗口中每个字段的字段名及其数据类型和标识，并将它们存入字符串中。
　　相关语句如下：
　　取字段名：
s—ColName = dw—1.Describe(′#′ + String(i) + ′.name′)
　　取字段类型：
s—ColType = dw—1.Describe(′#′ + String(i) + ′.coltype′)
　　取字段标识：
s—ColText = dw—1.Describe(s—ColName + ′—t′ + ′.text′)
说明：在生成数据窗口时，系统缺省地将字段标识的名字定为字段名+′—t′
　　上述语句中的dw—1为入口参数，i 是指第几个字段。
　　③ 返回此字符串。
　　. 查询窗口
　　定义如下:　　
入口参数：字符串（系上述公用函数返回结果）。返回值：字符串（即检索表达式）。
　　窗口中主要控件为一数据窗口和一命令钮（见图1）。

图1　公用查询窗口示例
　　数据窗口控件用于构造检索表达式，它对应的数据窗口对象以入口参数（即原数据窗口有关参数）为数据源（其数据源设计为外部（External）），其结果集（Result Set）由以下四项组成：
　　① 字段标识——由入口参数提供，在窗口open事件中生成，编辑形式为下拉列表框，其显示值（Display Value）对应于入口参数中s—ColText，其数据值（Data Value）对应于入口参数中s—ColName。
　　② 检索符——关系运算符，编辑形式为下拉列表框。
　　③ 检索值——此项由用户填入。
　　④ 逻辑符——与或符，编辑形式为下拉列表框。
　　命令钮则根据数据窗口的用户操作结果，生成一字符串（即检索表达式）并返回。
　　有关的程序设计主要有：
　　本窗口open事件：
　　① 获取传入的参数。并将它们传入数据窗口标识字段的编辑形式中。
dw—1.Modify(′#1.values = "′ + Message.StringParm + ′"′)
　　注意传入参数Message.StringParm须符合编辑形式的定义格式。② 如第1步操作无误，则在数据窗口是插入一空行，等待用户的输入。
　　数据窗口的itemchanged事件：当数据窗口中当前行的所有列都填满时自动插入一行，等待用户下一行的输入（程序略）。
　　命令钮clicked事件：
　　③ 删除空行。
　　④ 计算当前数据窗口中行数。如为空，则返回空值。否则以数据窗口中行数为循环次数，依次取字段名，检索符，检索值（并根据其字段类型决定其表示形式），逻辑符，并将以上各项存入字符串中返回。此返回的字符串即为所需的检索表达式。
2.1.2　打印预览窗口
　　本窗口对数据窗口如下参数作定义：边界、纸张尺寸、打印方向、预览缩放比例，并作相应输出。
　　定义如下：
　　入口参数：数据窗口对象　　　返回值：无
　　窗口除数据窗口控件外，其余主要的控件可分为两类：参数设置类、操作类。
　　数据窗口是原数据窗口的一个拷贝。本窗口的所有操作都是针对此拷贝数据窗口进行。不直接对原数据窗口进行操作也是基于通用性的考虑。
　　参数设置类控件一般为单行编辑框或下拉式列表框，供用户设置打印参数。
　　操作类控件一般为命令钮或检查框。
　　有关的程序设计主要有：
　　本窗口的open事件：
　　① 取入口参数，并据此产生本数据窗口数据源。
　　dw—1.Create(dw—source.Object.DataWindow.Syntax) 其中dw—source为原数据窗口
　　② 取本窗口中数据窗口有关打印参数，并将它们填入相应的控件中。有关参数有：边界、纸张尺寸、打印方向、页数。

图2　公用打印预览窗口示例
　　以取边界参数为例：
　　取上边界值em—top.text=dw—1.Object.DataWindow.Print.Margin.Top取边界参数单位st—topunit.text = ′PBU′ （据取得单位程序′0′， ′1′， ′2′， ′3′ 相应地给′pbu′， ′pxl′， ′in′， ′cm′值）
　　虽然每个参数都要进行设置，但它们的操作步骤是相同的：
　　① 参数设置。用Modify函数实现。
　　以边界参数设置为例：
　dw—1.Modify("datawindow.print.margin.top="
+em—top.text+&
"datawindow.print.margin.bottom="+em—bottom.text+&
"datawindow.print.margin.left="+em—left.text+&
"datawindow.print.margin.right="+em—right.text)
　　② 重新计算页数。如当前数据窗口已在预览状态下，则直接计算出。否则须改变数据窗口至预览览态下计算，计算毕，再改变回原状态。
　　计算页数：
i—Count = dw—1.Describe ("Evaluate(′PageCount()′,0)")
　　改变至预览状态：
　　dw—1.Modify("datawindow.print.preview=yes")
　　至于打印操作，可另建一公用打印窗口，用于设置打印选项，如打印范围、打印方式（分奇、偶数）、自动分页、打印份数、打印定向（到文件或打印机）等。限于篇幅，不再赘述。
　　要说明的是，上述只是常用的公用窗口两个特例，参照以上方法，可以建立其它的公用窗口。
2.2　控件
　　插入、删除、保存等也是数据窗口经常要使用的操作。用自定义控件实现这些操作是一种可行的方法。用以下方法设计的自定义控件，可在父窗口中直接被使用。
　　以删除操作为例进行说明，其余操作的设计方法与此类似。删除操作的完整脚本如下：
　//注意：本自定义对象的设计只针对父窗口中
//只有一个数据窗口的情形
//如父窗口有多个数据窗口,
//则选取排序最靠前的数据窗口作为操作对象
Window w—Parent
GraphicObject gb—WhichControl
DataWindow dw—Here

integer i—Count,i

w—Parent=PARENT
i—Count = UpperBound(w—Parent.Control［］)

//依次寻找当前窗口中的所有控件，直到找到数据窗口
FOR i = 1 TO i—Count
gb—WhichControl = w—Parent.Control［i］
CHOOSE CASE TypeOf(gb—WhichControl)
CASE DataWindow!
dw—Here=gb—WhichControl
EXIT
END CHOOSE
NEXT

//删除操作
dw—Here.DeleteRow(0)
　　这段程序中，真正执行删除操作的语句只涉及最后一行，其余的程序都是针对通用性所进行的设计。
　　以上讨论了两类公用对象：窗口类和控件类。当然，这两类公用对象在设计时也可以互相包含，公用窗口中可以直接使用公用控件，反过来，公用控件也可以调用公用窗口。
3　结语
　　将常用操作做成公用对象放入公用库中，在设计时直接调用或使用它们，是一种有效率和可维护性好的设计方法，在大型开发项目中，这种设计方法的优越性更为明显。在本文中，为保证公用对象的通用性，采取了参数传递的方法。当然，为了获得通用性，牺牲了一定程序运行效率。
　　在程序编制和撰写本文的过程中，得到了武汉菲旺电子科技有限公司的大力帮助，在此深表谢意！
作者简介：李振华　讲师。
吕国斌　副教授。
墙芳躅　 教授。均从事计算机网络及应用的教学与科研。
作者单位：中国地质大学网络中心　湖北.武汉（430074)
参考文献
［1］　Biberdorf,D,著.PowerBuilder 5开发人员指南.陈向群,译.北京：机械工业出版社，1997,9
收稿日期:1998-12-27(修改稿)
