PowerBuilder 8.0开发指南

Author: 杨志鸿 Date: 2001年 60期

PowerBuilder是美国Powersoft公司开发的客户机/服务器应用程序开发工具,它所采用的图形用户界面使得程序员能够快速容易地开发出相互独立的对象,而这些对象可供其他程序员共享或重复使用。作为专门的数据库应用系统开发工具,PowerBuilder在C/S结构的MIS开发中表现出众,深得用户青睐。其最新版本是PowerBuilder 8.0(以下简称PB8)。
  #1    一、安装PowerBuilder 8.0
      PB8的安装过程采用InstallShield标准,安装过程极为简单此处不再赘述。需要注意的是,在安装时要选中PowerBuilder 8.0和Adaptive Server Anywhere 7.0.1两项,否则安装后会无法联接数据引擎。在安装过程中会提示你安装DCOM98.exe,该文件在与OLE DB进行联接或远程调试一个Web站点时是必需的,但安装盘中并未提供该文件。如果你只进行一般的C/S模式MIS开发,可以忽略该信息,你也可到http://www.microsoft.com/com/dcom/dcom98/download.asp下载(在VB6里也可找到)。
  #1    二、PowerBuilder 8.0设计基础
      (一)PB8中的关键概念
      1.对象(Object)、属性(Property)、事件(Event)
      在所有面向对象的编程工具中,对象都是一个最基本的概念。 PB8中提供了诸如窗口、命令按钮、数据窗口等图形对象以及数据仓库、错误等非可视对象。对象通过属性对其特征进行描述和区分。例如,一个窗口对象,其属性包括窗口名、菜单名、是否可见、背景色、宽度、高度、在屏幕中所处的位置等。而用户对对象的操作则是通过对对象进行诸如点击、双击、拖动等动作来实现的,在动作发生时,“事件”即被触发。
      2.窗口(Window)和控件(Control)
      窗口是应用中所有可视对象的载体,也是应用与用户直接交互的直观途径。PB8中提供了丰富的控件,你可以在窗口画板工具栏的控件箱中找到它们。总的来说有五种类型的控件:
      (1)激活动作控件:包括Commandbutton(命令按钮)、PictureButton(图像按钮)和PictureHyperLink(图像超链接)、StaticHyperLink(静态超链接)控件。
      (2)输入和显示数据控件:包括DataWindow(数据窗口)、DropDownListBox(下拉列表框)、DropDownPictureListBox(下拉图片列表框)、EditMask(编辑屏蔽)、Graph(图表)、ListBox(列表框)、ListView(列表视图)、MultiLineEdit(多行编辑框)、PictureListBox(图片列表框)、RichTextEdit(大文本编辑框)、SingleLineEdit(单行编辑框)、StaticText(静态文本)和TreeView(树形视图)。
      (3)指示选择控件:包括RadioButton(单选按钮)和CheckBox(复选框)。
      (4)装饰界面控件:包括GroupBox(组框)、Line(线)、Picture(图片)、Rectangle(矩形)、RoundRectangle(圆角矩形)、Oval(椭圆)。
      (5)其他辅助控件:包括HprogressBar(水平进度条)、HscrollBar(水平滚动条)、HtrackBar(水平轨道条)、OLE (OLE控件)、Tab(标签页)、VprogressBar(垂直进度条)、VscrollBar(垂直滚动条)和VtrackBar(垂直轨道条)。
      所有的控件都有定义好的事件,用户也可以根据需要为控件自定义若干事件。
      3.工作区(Workspace)和目标(Target)
      在以往的PowerBuilder版本中,每次只能打开一个应用,对其中的对象进行处理。在8.0版本中,引入了工作区(Workspace)的概念,使你可以同时在几个应用(Application)或目标(Target)上进行工作。用户每次只能打开一个工作区,但每个工作区中都可以加入任意多个目标。你可以同时建立并展开多个目标,对其中的对象进行编辑。工作区文件和目标文件分别被命名为*.pbw和*.pbt。
      PowerBuilder 目标有两种类型:
      (1)PowerScript 目标:是一个C/S的(或多层的)可执行应用或一个服务器组件。
      (2)Web 目标:是一个Web应用,包括HTML文件、脚本、图片、下载组件等建立一个Web站点所必须的一切元素。
      4.库文件(library)
      每个目标是由一个或多个库文件组成的,所有编译过的对象都被储存在其中。当执行应用时,PB8从库文件中取得相应的对象进行处理。库文件被命名为*.pbl。
      (二)PowerBuilder 8.0面向对象的特性
      提到一门语言的面向对象特性,它应当具有继承性、多态性和封装性,如缺少其中的一个都只能称其为基于对象的系统,而不是面向对象的系统,而PB8则很好地具备了全部三个特性。
      1.继承
      在PB8中,只有窗口、菜单和用户对象是可以继承的。一旦继承了一个对象,所得到的子类将具有祖先类的属性、实例变量、共享变量、控件、用户自定义事件、对象级函数、事件和代码(Script)。也就是说一旦继承了一个类,就几乎得到了这个类的全部。不过值得注意的是,在子类中可以修改、添加但不能删除任何一个继承到的特性。
      在继承了祖先类后,你可以在子类中扩展或覆盖祖先的元素。例如代码,在PB8中缺省的是采用扩展方式,先执行继承到的祖先代码,后执行子类的扩展代码。你也可以选择 “Compiler→Override Ancestor Script” 菜单命令,只执行子类的代码,并可在代码中的任意位置调动祖先代码。如,CALL w_l∷open语句行。
      重载函数是面向对象程序设计的重要特性,即同一函数名却有着不同的参数和返回值。在运行时,系统自动寻找执行参数相匹配的那个函数,
      对于对象的继承,PB8中所有对象都有其共同的基类PowerObject,从这一个基类下面分成继承Graph-icObject和NonVisualObject等。
      2.多态性
      在PB8中有大量的多态函数,如Print()、TriggerEvent()等。在运行过程中,你只需要指出对象和函数名即可。在有些函数中,即使不知道对象类,也可以用Class Name()函数得到对象类,或得到实例名,将对象名作为函数参数调用该函数。
      3.封装性
      封装的目的是为了实现数据隐藏和数据保护。封装为对象提供了对外操作的接口,使其他对象通过函数来访问,而不允许直接操纵对象的属性。在PB8中有三种访问类型Public、Protect、Private,这三种访问控制类型可以用在对象的变量和函数上,缺省的实例变量和对象函数都是Public类型的。为保护数据,应尽可能使用Private和Protect类型,前者只允许对象内部的元素来访问,后者可以接受对象内部和继承类的元素访问。
      (三)PowerScript语言简介
      1.数据类型
      PB8中支持的标准数据类型在许多编程语言和数据库服务器之间都是通用的。有数值类型(Integer、Decimal、Double、Long、Real等)、字符类型(String、Char)、日期类型(Date、Datetime、Time)、逻辑类型(Boolean)、以及二进制大型对象类型Blob等。
      2.运算符
      PowerScript中有四类运算符:算术运算符(+、-、* 、/ 、^等)、关系运算符(=、>、<、<>等)、逻辑运算符(NOT、AND、OR)以及连接运算符(+)。其中连接运算符“+”用于连接两个同为String类型或Blob类型的变量或常量的内容,例如:“Power”+“Builder”得到“PowerBuilder”。运算符优先级的排列顺序为:算术运算符(或连接运算符)、关系运算符、逻辑运算符。
      3.变量与常量
      变量可以是一个标准数据类型,也可以是一个对象。定义对象的语法如下:
      数据类型 变量名(=初值)
      如:Integer  li_sum=7  (定义一个初值为7的整型变量li_sum)
          Window  w_main (定义一个窗口变量w_main)
      根据变量作用域的不同,可将变量划分为全局变量、实例变量、共享变量和局部变量。
      常量的定义语法为:
      CONSTANT 数据类型 常量名=常量值
      一经声明,常量值就不可再修改。
      4.数组和结构(Structure)
      数组是一组相同数据类型的变量或常量的集合。数组有一维数组和多维数组两种类型。后者必须有一个固定的大小,而前者可为无界数组。
      结构也是一组变量或常量的集合。与数组不同的是,组成结构的元素可以是不同的数据类型。
      5.函数
      PowerScript提供了丰富的内部函数,可以利用这些函数来对应用程序的各种对象和控件进行处理。如打开窗口的函数、关闭窗口的函数、使按钮有效的函数、获取数据的函数和更新数据库的函数等等。除此以外,我们还可以定义自己的函数来执行某种特殊的处理过程。函数调用的语法为:
      {objectname.}{type}{calltype}{when} functionname ({argumentlist})
      这些参数的说明如下:
      type:所调用方法的类型,可以是EVENT或FUNCTION,其中FUNCTION为缺省。
      Calltype :所调用的类型,可以是动态(关键词为DYNAMIC)或静态(关键词为STATIC),其中STATIC为缺省。
      When :调用的时间,POST或TRIGGER,其中TRIGGER为缺省。
      下表中,我们给出了PowerScript的数据转换函数。
      (^60090204a^)
      6.语句
      在PowerScript中提供了丰富的语句结构,下面是部分常用的语句。
      (1)赋值语句:变量名=表达式
      (2)调用语句:Call 祖先对象名{控件名} ::事件
      (3)条件选择语句:(CHOOSE CASE 和 IF…THEN)
      其中CHOOSE CASE 的格式为:
      CHOOSE CASE 表达式
        CASE 值1
          语句块
        { CASE 值2
          语句块
      ...CASE 值3
          语句块 }
        CASE ELSE
          语句块 }
        END CHOOSE
      (4)循环语句:(DO…LOOP,FOR…NEXT,GOTO)
      其中DO…LOOP的格式有如下几种:
      ①DO UNTIL 条件:
       语句块
       LOOP
      ②DO WHILE 条件:
       语句块
       LOOP
      ③DO:
       语句块
       LOOP UNTIL 条件
      ④DO:
       语句块
       LOOP WHILE 条件
      (5)事务管理语句:
      COMMIT:向数据库提交一个更新处理。
      ROLLBACK:取消对数据库事务对象所作的更新。
      CONNECT:连接一个数据库事务对象。
      DISCONNECT:断开已连接的一个数据库事务对象。
      7.ASCII字符
      PB8允许用户在字符串中使用特殊的ASCII字符。
      (^60090204b^)
  #1    三、PowerBuilder 8.0应用开发指南
      下面我们通过一个简单的检索实例来认识PB8。
      (一)PB8的IDE(集成开发环境)
      PB8提供了功能完善的集成开发环境(IDE),它通过一个MDI风格的主窗口集成了主菜单、工具栏、系统树窗口(System tree window)、剪贴窗口(Clip window)、输出窗口(Output window)、画板区等多个子环境,下面我们对其中的重要部分作详细介绍,便于你熟悉基本概念并掌握其使用方法。
      1.主菜单和工具栏
      菜单是IDE与使用者进行交互的重要环节,大多数主要操作均可通过主菜单及其下的各级子菜单完成。与常见的MDI窗口类似,在菜单下的工具栏Powerbar中以图标的方式罗列了最常用的子菜单项。当鼠标移至工具栏某图标上并稍作停留时,会在鼠标下方出现黄色的帮助,同时在窗口下部的状态栏中出现有关该图标所代表子菜单项的详细说明。此外,如果在工具栏上单击右键,在弹出的浮动菜单中选中“Show text”项,也会在图标中显示图标名称。
      除了Powerbar工具栏外,根据所打开的对象画板的不同,还会出现不同的画板工具栏。
      2.工作窗口和画板区
      启动PB8后,在IDE的左边是系统树窗口(System tree window)和剪贴窗口(Clip window),在底部是输出窗口(Output window),其余的灰色区域则是在打开某个对象时用于显示对象画板或编辑器的画板区。
      (1)系统树窗口(System tree window):
      在系统树窗口中,以树形结构显示了当前所开发目标的所有资源信息,包括工作区、目标、库文件、应用、对象等。系统树窗口不仅将这些信息展示出来,还提供了对它们的属性、脚本的编辑功能。对PowerBuilder老版本的用户来说,编辑不同库中的多个对象更方便了,而且整个应用的层次性也显得更为清晰。
      (2)剪贴窗口(Clip window):
      剪贴窗口实际上是一个功能更为强大的剪贴板。你可以将可能需要重复使用的代码段赋予一个名字保存在剪贴窗口中,在需要时再拷贝出来。由于剪贴窗口中可以保存许多条剪贴信息,而且在一个工作区中定义的剪贴信息可以为其他工作区所用,这就大大提高了代码的编辑效率和可重用性。在剪贴窗口上部有四个图形按钮,从左到右的名称和功能如下表:
      (^60090204c^)
      (3)输出窗口(Output window)
      在进行迁移、展开、创建、重建、保存对象、搜索、运行等操作时,操作结果将会在输出窗口中显示。
      (4)画板区
      当对对象进行处理时,会在画板区中出现该对象的编辑器,也叫画板。PB8中为窗口、菜单、数据窗口对象、可视或不可视用户自定义对象、函数、结构、数据库、数据管道和应用本身提供了画板。此外,当使用“Edit”菜单项打开一个文件编辑器时,编辑器也显示在画板区内。
      (二)创建新工作区
      第一次进入PB8时,会弹出一个欢迎窗口,其中以超链接的形式给出了5个选项:
      (1)创建一个新工作区和一个新目标。
      (2)创建一个新工作区并加入一个已存在的目标。
      (3)只创建一个新工作区。
      (4)打开一个已存在的工作区。
      (5)关闭本窗口。
      选择第一项后弹出建立新工作区对话框,选择合适的路径,输入文件名后单击“Save”按钮,便可建立一个新的工作区。接着会弹出“New”窗口,可以看到当前页面上的“Application”项已被选中,单击“OK”按钮,进入指定新应用及库文件的对话窗口,依次输入应用名、库文件所在路径及文件名、目标文件所在路径及文件名后单击“Finish”按钮,便可完成新应用的创建工作。现在,你可以发现,在System Tree子窗口中显示了你所创建的工作区,并可将其按目标文件、库文件、应用的顺序逐级展开。
      你也可通过单击菜单“File”中的“New”菜单项打开刚才已见过的“New”窗口,单击“Tab”标签中的“Workspace”选项,然后双击当前页面中的“Workspace”项重新建立一个新的工作区。
      (三)数据库的创建、配置与联接
      下面我们创建一个自己的数据库文件。单击Powerbar图标栏中的“Database”图标,出现 “Database - 0 Connections”的窗口。在窗口左部的树形图中显示了所有已安装的数据库接口。展开“ODB ODBC”项,下面有三个子项,其中“EAS Demo DB V4”和“EAS Demo DB V4 IM”是PB8自带的数据库概述文件。展开“Utilities”项,双击“Create ASA Database”(创建一个ASA 数据库)项,弹出对应的对话窗。
      系统默认给出的“User ID”和“Password”分别为“DBA”和“sql”,一般不必改动。在“Database Name”后的编辑框中输入数据库所存放的路径和文件名(如test.db)后单击“Finish”按钮,此时将在“ODB ODBC”树下增加一个名为“Test”的概述文件。该项前打有小勾,表明数据库已连接成功。双击该概述文件,在弹出的配置窗口中对其进行配置。既可以将“Profile Name”后的“Test”改为其他概述文件名,也可在“Data Source”后的下拉列表框中选择其他的数据源,对此概述文件重新配置。配置完成后,可切换至“Preview”页面,查看生产该文件的SQL语句。并可单击“Test Connection”按钮检查是否能与数据源正常连接。
      接下来为已创建的数据库添加一个表。有两种方法:单击工具栏中的“Create Table”图标;或是展开“Test”,在“Tables”子项上单击右键,在弹出的菜单中选择“New table”命令。此时在画板区内会增加一个标题为“Columns(Test)-Untitled”的画板,在其中可完成对表中各字段的定义。本例中我们只定义三个字段:
      (^60090204d^)
      注意:每个字段定义完毕后按回车进入下个字段的定义。
      定义完成后,单击工具栏上的“Save”图标,在对话框中输入表名“Person”,回车后在“Object Layout”画板中即会出现新建的“Person”表。值得注意的是,只有在定义主键后,这个表才能被进行有效的数据操作。
      在表名上单击右键,从弹出式菜单中选择“New→Primary Key”命令,将出现新的“Primary Key-Person”画板。在要选作主键的“id”字段前打勾,单击工具栏上的“Save”图标完成定义。
      对表的修改可通过在表名上单击右键后弹出的菜单中选择“Alter Table”命令实现,但不能修改字段类型和是否为空。下面为“Person”表添加几条数据。在表名上单击右键后的弹出式菜单中选择“Edit Data→Grid”命令,然后单击工具栏中的“Insert Row”图标,即可添加记录。完成后单击工具栏上的“Save Changes”图标保存数据。
      至此,我们已完成了对一个数据库的创建过程,接着就该在应用中与之相连接了。在左边的“System Tree”子窗口中完全展开工作区,双击应用“test”,在输出窗口区内将出现应用“test”的脚本画板,当前事件为open,在画板中编写如下代码:
      //为事务对象赋值
      SQLCA.DBMS = ″ODBC″
      SQLCA.AutoCommit = False
      SQLCA.DBParm = ″Connectstring=′DSN=test′″//连接数据库
      connect using sqlca;
      //若连接失败,报错并中止应用
      if sqlca.sqlcode <> 0 then
            MessageBox (″对不起!无法连接数据库″, sqlca.sqlerrtext)
      Halt
      end if
      在这里,我们接触到PB8中的缺省事务对象SQLCA,即SQL通信区域。这是一个全局性的事务对象,用于与数据库交换信息。上述代码首先给SQLCA的各个属性赋值,使之与数据源test相关联,然后进行连接。如果连接失败则给出一个消息框进行错误提示。
      (四)放置窗口和控件
      接下来,我们创建一个数据窗口,用于显示“大于20岁”的人名和年龄。单击“File”→“New”菜单命令。在“New”窗口中,单击“DataWindow”标签,双击“Grid”项进入选择数据源窗口,再双击“Quick Select”项,进入“Quick Select”窗口。从左边的“Tables”列表中选中“Person”,此时右边的“Columns”列表中出现了表Person的所有字段,选中“name”和“age”后单击“OK”按钮,进入色彩和边界设定窗口,可在此调整数据窗口的背景色、文本和字段的颜色、边界等。完成后单击“Next”按钮,再确认无误后单击“Finish”按钮,便可在Object Layout子窗口中看到已生成的数据窗口。
      但是,这个数据窗口显示的是数据库中现存的所有数据。要实现按条件过滤,单击工具栏中的“Data Source”图标(图标上写有SQL的那个),注意在新的画板下方有一排小标签,单击“Where”页,在其中的“Column”下拉列表框中选择“″person″.″age″”项,“Operator”下拉列表框中选择“>”,“Value”栏中填写“20”,此时再切换到小标签中的“Syntax”页,你会发现当前的Sql语句是:
      SELECT″person″.″name″,
            ″person″.″age″
          FROM ″person″
        WHERE ″person″.″age″ > 20
      单击工具栏中的“Return”图标返回,并单击“Save”图标,在“Save Datawindow”对话框中输入数据窗口名“d_test”。保存后,在System Tree窗口中test.pbl下增加了一个名为d_test的数据窗口对象。
      下一步,我们为这个数据窗口提供一个载体,使其能为用户所见。首先打开“New”窗口,单击“PB Object”标签,双击“Window”选项,在画板中得到一个空白的窗口对象,在右边的属性画板中将“Title”属性值改为“查询窗口”。从工具栏的控件箱中选取一个DataWindow控件,单击窗口中的区域放下控件。此时右边的属性画板中数据窗口的“name”属性值为“dw_1”,DataObject值为空。单击空白框后的小方块,弹出数据窗口对象选择对话框,选择“d_test”。这样,原本空白的数据窗口控件中出现了刚才定义的数据窗口对象,但其中没有任何数据。现在双击窗口的空白区域,出现窗口的脚本画板,当前事件为“open”。在画板中输入如下代码:
      //将数据窗口控件与事务对象相连接
      dw_1.settransobject(sqlca);
      //检索数据
      dw_1.retrieve();
      然后从控件箱中选取一个Commandbutton控件,放下后将属性画板中“Text”属性值改为“退出”。双击按钮进入脚本画板,在“clicked”事件下输入:
      //关闭窗口
      close(parent);
      现在从工具栏中保存新建的窗口,命名为w_test。返回到应用test的“open″事件脚本,在脚本末端加入代码:
      //打开查询窗口
      open(w_test);
      接下来从事件列表框中选择“close”事件,输入代码:
      //断开数据库,退出应用
      disconnect using sqlca;
      最后保存整个应用。
      这样,一个完整的实例程序就结束了。试着单击工具栏上的“run test”图标,看一看结果吧!
      (五)程序的调试与发布
      1.PB8的调试器
      PB8带有内置调试工具,有助于找出任何应用程序的脚本中的错误。调试器允许在想调试的不同程序中设置停止(或断点)。以调试模式运行应用程序时,PB8在执行含有断点的PowerScript语句之前将进程挂起。这时,就可以单步执行代码的每一行,观察执行了什么代码,检查当前作用域内的变量。调试能使用户查看变量在断点处的值,并且可以改变变量的值。
      单击PowerBar中的“Debug”图标就可以进入调试器画板群。在“Source Browser”画板中列出了所有5个可能包含有脚本的PowerBuilder对象:应用程序、窗口、菜单、用户对象和函数。展开要设置断点的对象类型后,这种类型的所有对象都会出现在树形图中。当选择了某个对象名(例如w_test)后,所有写有脚本的事件就会展开。双击该事件即可打开此事件的脚本编辑画板。
      当一个脚本选中后,它即处于调试模式。在设置断点处双击每一个PowerScript语句,进程将在有断点的行被执行之前停止。注意,注释、变量说明和空行不能包含断点。断点设置完成后单击“start”图标就可进入调试过程。
      2.创建可执行(exe)文件
      PB8使开发者能用三种方式建立一个可执行文件。
      第一种方法是产生一个用户能够运行的包括所有可执行文件的产品。
      第二种方法是使用称为PB8动态库(PBD)文件和一个较小的可执行文件,PBD同DLL相似,它们能在文件内加载对象,以便对应用程序消费的内存提供更多的控制。
      第三种方法是对可执行文件和PBD编译16或32位机器代码。一个PBL文件现在可直接编译成DLL,而不是PBD。
      通过主菜单中的“New→Project→Application”就可进入创建应用程序画板。你可选择以上三种方式之一发布应用程序。
  #1    四、PowerBuilder 8.0核心技术:数据窗口
      (一)数据窗口对象
      数据窗口(DataWindow)是PowerBuilder的一大特色。
      面向数据库的应用均以数据为中心的,而数据窗口正是显示和操作数据的窗口。首先要注意区分数据窗口控件和数据窗口对象。前者是一个可视控件,通过在其上放置数据窗口对象实现数据的显示与操作;后者是一种对象,数据的存取被封装到该对象里,从而可以把面向对象的各种特征(如重用、继承等)贯穿到从用户界面到数据存取的应用程序开发的全过程。
      数据窗口提供了大量原本需要应用开发者自己来设计的功能,从而大缩短了开发时间并显著提高了数据存取的效率。如数据窗口属性“Retrieve only as needed”,它使从数据库取数据时每次只取所需的部分,而不是一次把所有的行(记录)都取出来。
      数据窗口使我们可以方便地把数据从后台提到界面上来,可以把数据窗口放置到一个数据窗口控件中去,使它同编程框、单选按钮等一样成为用户界面的一部分。按照通常的处理方法,一个表中的每一个域被当成一个对象,都得为它写一段程序进行屏幕显示处理。而在PB8中,无论要显示多少列,它们都可以被放在一数据窗口中,一次性地交给Windows操作系统,这就明显地提高了屏幕显示速度。
      当定义一个DataWindow对象时,可以选择一种表现风格和一种数据源。
      1.表现风格
      数据窗口提供了十一种表现风格,在每一种表现风格中都可以自定义数据的显示方式,下表中列出了所有的表现风格。
      (^60090204e^)
      2.数据源
      数据源指定了数据窗口中数据的来源和要显示的数据项。数据可以来源于数据库的表,或者从一个文件中直接导入数据,或者在代码中指定数据。对数据库来说,数据的指定存在一个SQL语句中。在所有情况下,数据窗口对象保存了要显示的数据项的名字和它们的数据类型。各种不同的数据源及其描述见下表:
      (^60090204f^)
      使用数据窗口包括以下两个主要步骤:
      首先,使用DataWindow画板创建或编辑一个DataWindow对象。在画板中,可以定义DataWindow的数据源、表现风格和对象的其他属性,例如显示格式、有效规则、排序过程和过滤条件以及图表等。
      然后,在开发环境中,把一个DataWindow控件或组件放在一个窗口、表单或Web页中,并使之与一个DataWindow对象关联。
      应用程序是通过这个控件与在DataWindow画板创建的 DataWindow对象进行通信的。用户可以编写代码来操纵这个DataWindow控件及其相关联的DataWindow对象,并可以通过代码对数据进行检索和存取,也可以改变数据的显示形势、处理异常情况及在DataWindow控件之间共享数据。
      (二)动态维护数据窗口
      在实际应用中,往往需要由用户在应用程序中自己定义数据窗口的数据来源和显示类型。为此,我们必须在运行程序阶段根据用户自己的需求,动态地建立一个数据窗口。
      在建立动态数据窗口之前,必须先得到数据窗口对象的语法,PB8中为我们提供了SyntaxFromSQL()函数,利用这个函数可以得到建立数据窗口的语法。在利用 SyntaxFromSQL()函数建立一个数据窗口语法后,必须利用Create()函数将它与已经存在于窗口上的数据窗口控件结合。
      不但如此,PB8还提供:dwModify和dwDescribe函数。dwModify函数使我们可以动态地修改某个已存在的数据窗口的各种属性,dwDescribe函数使我们可以动态地定义、生成数据窗口。
      (三)数据仓库(DataStore)
      在开发中,有时你会需要使用一个数据窗口获取或转移数据,但又不希望在界面上为使用者可见。当然你可以通过设置该数据窗口控件的“Visible”属性为“False”来实现,但这样的弊端也是显而易见的:在应用程序中导致过多的系统开销,从而影响系统的效率。
      为减轻这种负担,PB8提供了一个不可视的数据窗口控件“Datastore”,除了不能与用户相交互外,它具有其他数据窗口控件的一切功能 。在使用“Datastore”时要首先予以创建并实例化,例:
        //声明Datastore变量
          Datastore  Lds_ Datastore
        //将Datastore实例化
          Lds_ Datastore=Create Datastore
        //为Datastore分配 DataWindow对象
          Lds、Datastore.DataObject=‘d_employee’
        //检索数据
            Lds_ Datastore.Settransobject(SQLCA)
            Lds_ Datastore.Retrieve()
      结束使用后,再通过Destroy Lds_datastore将其释放。
      (四)数据窗口的缓冲区和行状态
      1.数据缓冲区
      在每一个数据窗口对象中都有3个数据缓冲区用来存储查询到的数据。用户在数据窗口中对数据处理系统内部的操作实际上都是将数据在这几个缓冲区中进行的修改和移动,最后在用户提交数据库时,系统根据这三个缓冲区中的信息形成SQL的Insert、Update、Delete等语句。这三个缓冲区是:
      (1)Primary Buffer:
      这个缓冲区是存放填充窗口中数据窗口控件中数据的,调用数据窗口的Retrieve()函数和InsertRow()函数可以将数据填入这个缓冲区中。当使用有关数据窗口删除和过滤函数时,相应记录将从这一缓冲区中删除。而在执行数据窗口的Update()函数时,PB8将查看这一缓冲区中的记录,以形成SQL Insert和Update语句。
      (2)Delete Buffer:
      这个缓冲区保存的是用DeleteRow()函数从Primary Buffer中删除的记录,执行Update()函数时,系统根据这一缓冲区的记录形成Delete语句。
      (3)Filter Buffer:
      这个缓冲区存储的是从使用Filter()函数过滤后剩余记录。
      如果当前使用的数据窗口没设置修改的权力,将不能对Delete缓冲区进行操作,而且当调用Update()时也将引起系统错误。
      2.数据缓冲区的状态值
      当用户在数据窗口缓冲区中处理数据时,数据窗口中的每一行都有一个标志,说明了该行目前的状态:
      New!:表明该行刚被插入,但尚未添加任何数据。
      NewModified!:表明是一个新行,且已至少输入了一栏数据。
      NotModified!:表明该行从数据库中被检索,用户没有修改任一栏。
      DataModified!:表明该行由检索而得,且至少修改了一栏。
      利用这一知识,可以对数据窗口的更新实现更细微的控制。例如,在许多实际应用中,用户会发现输入的大多数数据与以前输入的一些数据很相似,他们想以模板来标识行并且更换其中不同部分。
      对此,我们可以先检索作为模板的行,再使用SetItemstatus()函数将该行的行状态从NotModified!变为New!实现这一功能:
      dw_Control.SetItemStatus(1,0,Primary! New!)
     (五)实现多表数据窗口的数据更新
      在创建数据窗口时,有时选择的数据源需要包含两个以上的表,即构成数据窗口的列来自两个以上的表。这种数据窗口的优点是可以把多个表的安排有机地组合到一起,供用户查阅。缺省情况下这种数据窗口没有数据更新能力。那么,如何能使这种数据窗口不仅可以同时查看多个表中的数据,而且可以同时修改这些数据呢?
      首先了解一下数据窗口的数据更新原理。众所周知,对关系数据库的任何操作都必须使用SQL语句,数据窗口也不例外。实际上,当数据窗口中的数据被修改并执行Update()函数时,PB8会自动根据所做的修改产生相应的Update语句来更新后台数据库中的数据。由于Update语句一次只能更新一个表,所以数据窗口每执行一次Update()函数也只能修改一个表中的数据。为了对数据窗口包含的每个表分别执行Update()函数,以实现多表更新,就要对数据窗口的一组Update属性用程序进行处理,以控制数据窗口的数据更新能力。在执行Update()函数前,通过设置这些属性可以控制数据窗口产生针对某个表的Update语句。这样,通过改变Update属性就可以产生不同的Update语句,实现数据窗口的多表更新。
      在 “Specify Update Properties”对话框中,数据窗口的更新属性分为七组:
      (^60090204g^)
      在编写程序时,我们需要使用“Table to Update”、“Updateable Columns”和“Unique Key Columns”这几个属性。通过这三个属性,就可以指定要更新的表、列和表的键列,实现数据窗口的多表更新了。