1、第 10 章 数据窗口高级技术10.1 概述数据窗口对象主要用于操作数据库中的数据,它不仅为数据的增加、删除、修改、更新和查询等数据库操作提供了图形化接口,而且还可以指定数据的输入格式、输出格式以及数据的显示风格。此外,在 PowerBuilder 7.0 以后的版本中,用户还可以在数据窗口对象中增加多种对象(包括按钮、静态文本框、图片等 )。应用程序中使用的数据窗口通常由数据窗口对象和数据窗口控件两部分组成。数据窗口控件是粘贴到窗口上的一个对象,与 OLE 控件有点类似;数据窗口对象是粘贴到数据窗口控件或数据存储中的对象,它通过数据窗口画笔来创建,并保存到应用库中。通过数据窗口对象与数据窗口
2、控件的配合使用,来完成数据的显示、增加、删除、修改等操作。创建数据窗口的一般步骤为:(1) 使用数据窗口画笔创建数据窗口对象,并把它保存到 PowerBuilder 应用库中。创建数据窗口对象的操作一般包括下述内容:定义数据源、选择数据窗口的表现风格、设置数据窗口对象及该对象内其他对象的属性(例如显示格式、编辑风格、跳转次序、有效性规则、排序与检索条件)等。如图 10-1 所示。图 10-1 数据窗口对象的创建(2) 在窗口或用户对象中建立一个数据窗口控件,如图 10-2 所示。图 10-2 创建数据窗口控件(3) 设置数据窗口控件的属性或编写代码,建立数据窗口控件与数据窗口对象的关联。(4)
3、 针对具体应用,编写数据窗口控件的事件处理程序,如显示数据、响应用户操作。考虑到本书的读者对 PowerBuilder 已经有了一定的了解,这里只给出了创建数据窗口的大致步骤,具体细节请参阅 PowerBuilder 的入门书籍或者帮助文件。第 10 章 数据窗口高级技术10.2 数据窗口控件的重要属性、事件和函数(1)与其他控件相似,数据窗口控件也是放置在窗口或用户对象上的一个控件。数据窗口控件的属性、事件和函数的数量相当庞大,这里主要介绍一些不容易掌握的属性、函数和事件。10.2.1 数据窗口控件的重要属性在 PowerBuilder 的可视化界面中,可以设置数据窗口控件的绝大部分属性,多
4、数属性的作用从属性名称中就可以判断出来,但是有些属性的作用却不容易判断,例如:DataObiect、DragAuto 等,此处主要介绍一下这些属性的作用。(1) DataObject 属性String 类型,指定与数据窗口控件相关联的数据窗口对象名或报表对象名。比如代码中使用语句 dw_1.DataObject = d_zuozhe,可将数据窗口对象 d_zuozhe 显示在数据窗口控件 dw_1 中。这在创建动态数据窗口时经常用到。(2) DragAuto 属性Boolean 类型,指定 PowerBuilder 是否自动把数据窗口控件置入拖曳模式(Drag Mode)。有效取值为:True
5、,当数据窗口控件被单击时,数据窗口控件自动进入拖曳模式; False,当数据窗口控件被单击时,数据窗口控件不自动进入拖曳模式。此时,如果需要让数据窗口控件进入拖曳模式,需要在代码中使用 Drag()函数手工设置。(3) Object 属性DWObject 类型,用于在代码中直接操作数据窗口对象中的对象,包括设置对象的属性、得到数据窗口中的数据等。数据窗口对象中的对象包括:列对象、文本对象、图像对象、按钮对象、Datawindow 对象等。(4) 示例例如,放置了数据窗口 dw_zuozhe 的窗口 w_test 如图 10-3 所示。图 10-3 更改数据窗口属性前在窗口的 open 事件中添
6、加代码:dw_1.Object.s_zuozhexingming_t.text=“修改后的姓名编码“显示的变化如图 10-4 所示。图 10-4 更改数据窗口属性后10.2.2 数据窗口控件的重要事件数据窗口控件的事件很多,这里主要从如何利用事件进行应用开发的角度对数据窗口控件的事件分类介绍并给出部分实例。当然,本书对事件的分类并不是绝对的。对于一些比较容易的事件,例如 Clicked 事件等,这里就不再赘述。1. 用于触发数据窗口内部控件的事件PowerBuilder 的数据窗口提供了用于触发内部控件的事件,这些事件主要用于数据窗口内的按钮控件,下面分别介绍:(1) ButtonClicki
7、ng 事件ButtonClicking 事件在单击数据窗口内的按钮对象时触发。触发的条件是该按钮的SuppressEventProcessing 属性设置为 no。该事件在 ButtonClicked 事件之前、Clicked 事件之后触发。该事件在系统处理按钮的默认动作前触发。返回值的意义为:0,继续处理;1,不执行按钮的指定动作,但仍会接着触发 ButtonClicked 事件。返回的参数包括: row:长整形,用户单击的行号。 Actionreturncode:长整形,该事件返回的动作代码。 dwo DWObject:指针类型,指向用户单击的对象。(2) ButtonClicked 事件
8、当数据窗口内的按钮对象的 SuppressEventProcessing 属性设置为 no 后,单击该按钮时触发ButtonClicked 事件。该事件在系统处理完按钮的默认动作后触发。返回的参数包括: row:长整形,用户单击的行号。 dwo DWObject:指针类型,指向用户单击的对象。(3) 示例在 dw_1 的 Buttonclicking 的事件上添加代码:dw_1.Object.s_xiaozhuan_t.text=“触发 buttonclicking 事件后的小传“单击数据窗口中的【确定】按钮后可以看见窗口内容的变化,如图 10-5 所示。图 10-5 Buttonclicki
9、ng 事件演示2. 用于处理数据窗口错误的事件要使应用程序具有良好的容错性,处理好数据窗口的错误事件至关重要。下面分别介绍常用的数据窗口错误事件。(1) DBError 事件当数据窗口控件访问数据库时发生数据库错误则触发该事件。该事件返回值的意义为:0,默认值,系统显示出错信息;1,系统不显示出错信息。可以利用该事件进行数据窗口的错误处理。在这个事件中,可以编写自己的出错处理程序,以提高程序的容错性。该事件的参数为: sqldbcode:长整数类型,包含由数据库厂商提供的特定出错代码,代码含义可以参见数据库厂商提供的有关文档。如果数据库厂商未提供出错代码,则sqldbcode 值的意义如表 1
10、0-1 所示。表 10-1 sqldbcode 值的意义sqldbcode 值 意 义1 不能连接到数据库(可能是因为事务对象中未正确提供某些参数)2 不能连接到数据库3 Update 或 Retrieve 中指定的键值与现有行不匹配4 写 Blob 型数据时发生错误 sqlerrtext:字符串型,数据库厂商提供的错误消息文本。 Sqlsyntax:字符串型,发生错误的 SQL 语句的全部代码。 Buffer:数据窗口缓冲区,错误发生时数据行所在的缓冲区。它的取值为Delete!、Filter!或 Primary!。 Row:长整型数,在对数据行进行 UPDATED、SELECTED、INS
11、ERTED 或 DELETED操作时发生错误的数据行号。例如,在 DBError 事件中可以编写如下脚本:CHOOSE CASE sqldbcodeCASE -4 /写 Blob 数据类型时出错。MessageBox(“Error“,“出错行在“+string(row)+ “写 Blob 数据时出错“)CASE /其他出错代码END CHOOSERETURN 1 /隐藏系统出错消息窗口(2) Error 事件Error 事件当数据窗口对象的数据或属性表达式发生错误时触发。该事件的参数为: errortext:字符串型,PowerBuilder 的出错消息文本。 errornumber:无符号整
12、型数,PowerBuilder 的出错信息编号。 errorwindowmenu:字符串型,引起错误的窗口或菜单名。 errorobject:字符串型,引起错误的对象。 errorline:无符号整型数,发生错误的行号。 errorscript:字符串型,引起错误发生的脚本。 action:ExceptionAction,该参数指定执行完 Error 事件中的脚本以后,应用程序要做的相应工作。该参数的取值如表 10-2 所示。表 10-2 ExceptionAction 参数取值参 数 取 值 意 义ExceptionFail! 触发 SystemError 事件ExceptionRetry!
13、 如果是 OLE 服务器没有准备好,重新执行函数或检查表达式,该选项对数据窗口控件不适用ExceptionIgnore 忽略发生的错误(使用该参数时要小心,忽略当前错误可能会引起其他错误)ExceptionSubstituteReturnValue! 取消错误条件并使用 returnvalue 指定的值代替 OLE 服务器或数据窗口返回的值 Returnvalue:Any 型(Any 型可以保存各种数据类型,包括标准数据类型、对象、结构等,但是它不能用于 EAServer 的组件定义),用于ExceptionSubstituteReturnValue!选项的返回值。例如,在 Error 事件中
14、编写以下脚本 (该脚本将在报错后触发 SystemError 事件) :MessageBox(“错误号:“+string(errornumber),“错误为:“+String(errortext)Action= ExceptionFail!对于数据窗口控件来说,如果正在运行数据或属性表达式时发生错误,且 Error 事件中没有脚本,或者参数 action 被置为 ExceptionFail!,则 PowerBuilder 首先触发 Error 事件,然后 SystemError 事件被触发;如果 SystemError 事件中也没有脚本,应用程序发生错误并终止运行。10.2 数据窗口控件的重要
15、属性、事件和函数(2)(3) ItemError 事件该事件在用户修改了字段,然后移走焦点,但数据未能通过该列的有效性检查时触发。该事件返回值的意义如下。 0:(默认值),拒绝输入值并显示有效性检查出错信息,同时不允许移走焦点。 1:拒绝输入值,但不显示出错信息,同时不允许移走焦点。 2:接收输入值。 3:拒绝输入值,但允许移走焦点。它的参数包括: row:长整数型,表示数据行号。该行即发生改变但没有通过有效性检验的字段的行号。 dwo:dwobject,发生错误的数据窗口对象。 data:字符串型,新输入的发生改变的项的数据。例如,在 ItemError 事件中添加如下脚本,则除了长整数类型
16、的字段可以为空外,不允许数据窗口控件中的其他字段为空,系统自动检查这些字段并为其赋值。string str_colname,str_datatypestr_colname=dwo.Namestr_datatype:dwo.ColTypeIF str_datatype50 THENMessageBox(“STOP!“,“已经检索 50 条记录“)RETURN 1ELSERETURN 0END 1F(3) RetrieveEnd 事件RetrieveEnd 事件在当数据窗口检索完数据后触发。(4) Updatestart 和 UpdateEnd 事件当数据窗口更新数据库后触发 UpdateEnd
17、事件。在调用 Update()函数后、修改数据库数据前触发 UpdateStart 事件。该事件返回值的意义如下。 0:(默认值)继续更新。 1:不执行更新。UpdateEnd 事件提供以下参数。 argument:参数描述。 rowsinserted:长整型数,更新操作中新插入数据库的行数。 rowsupdated:长整型数,更新操作中被更新的行数。 rowsdeleted:长整型数,更新操作中被删除的行数。(5) SQLPreview 事件该事件在调用 Retrieve()、Update()或 ReselectRow()函数后,SQL 语句被发送到 DBMS 前发生。由 Update()函
18、数触发该事件时,该事件返回值的意义为:0,继续更新;1,停止更新;2,跳过本次请求继续执行。该事件提供以下参数。 request: SQLPreviewFunction 类 型 , 表 示 要 求 访 问 数 据 库 的 函 数 类 型 。 它 的 取值 如 下 。 PreviewFunctionReselectRow!:ReselectRow()函数。 PreviewFunctionRetrieve!:Retrieve() 函数。 PreviewFunctionUpdate!:Update()函数。 sqltype: SQLPreviewType 类 型 , 指 发 送 到 DBMS 的 S
19、QL 语 句 的 类 型 , 它 的 取 值 如下 。 PreviewDelete!:DELETE 语句。 Previewlnsert!:INSERT 语句。 PreviewSelect!:SELECT 语句。 PreviewUpdate!:UPDATE 语句。 sqlsyntax:字符串型,全部 SQL 语句的文本。 buffer:DWBuffer 类型,与数据库操作有关的包含数据行的缓冲区。 row:长整数型,将要被更新、插入、选择或删除的数据行。用户可以使用 sqlsyntax 参数修改将要执行的 SQL 语句,例如,可以通过获得 sqlsyntax 参数获得语句,修改以后调用 SetS
20、QLPreview 函数,再将 SQL 语句发送给 DBMS。若用户在数据库描述中设置了绑定选项,sqlsyntax 参数得到的 SQl 语句就可能不完全,绑定的变量没有被实际的变量所代替,而是以问号的形式出现。所以,如果需要 SQL 语句的完全语法,应该取消数据库的绑定设置。方法是,打开 DatabaseProfile Setup 对话框,选择Transaction 选项卡,取消选择 Disable Bind 复选框。10.2 数据窗口控件的重要属性、事件和函数(4)10.2.3 数据窗口控件的重要函数数据窗口控件的函数很多,使用起来也非常灵活。为便于查阅使用,本章将按使用方法分类介绍数据窗
21、口控件的重要函数。1. 用于数据库操作的函数PowerBuilder 的数据窗口控件提供了用于检索、更新、插入、删除数据库中数据的函数,下面分别介绍。(1) Retrieve()函数Retrieve()函数的调用格式为:dwcontrol.Retrieve ( , argument, argument . . . )其中,dwcontrol 为数据窗口控件名;argument 为向数据窗口对象的 SQL SELECT 语句提供的检索参数。Retrieve()函数使用指定的数据窗口控件从数据库中提取数据。如果为该函数提供了参数,那么这些参数的值将用作数据窗口对象的 SQL SELECT 语句的提
22、取参数。Retrieve()函数的返回值为 Long 数据类型。函数执行成功时,返回显示在数据窗口中的数据行的行数(即主缓冲区的数据行数 );函数执行失败时返回 -1。如果任何参数的值都为NULL,则返回 NULL。使用 Retrieve()函数检索数据时,系统自动执行数据窗口对象的过滤条件,不满足过滤条件的行被立即移动到过滤缓冲区中,Retrieve() 函数返回的行不包括移动到过滤缓冲区中的行。在执行 Retrieve()函数之前,必须用数据窗口控件的对象函数 SetTransObject()为数据窗口控件设置事务对象。当使用 SetTransObject()函数时,在调用之前,需要使用嵌
23、入式 SQL 语句CONNECT 建立事务对象与数据库的连接。正常情况下,执行 Retrieve()后,数据窗口中原有的数据被丢弃,并被新的数据所取代。如果想改变这种默认操作,可以通过在数据窗口控件的 RetrieveStart 事件中编写代码来实现,方法很简单,只要在该事件的事件处理程序中放上语句“Return 2”即可。这时,Retrieve() 检索出的数据将被增加到数据将被窗口原有数据的后面。如果数据窗口控件中的数据窗口对象需要检索参数,而 Retrieve()函数中又没有提供这些参数,那么执行 Retrieve()函数时,系统将显示一个对话框,让用户输入检索参数的取值。执行 Retr
24、ieve()函数时,可能触发数据窗口控件的 DBError、RetrieveEnd、RetrieveRow 和RetrieveStar 事件。(2) InsertRow()函数InsertRow()函数的调用格式为:dwcontrol.InsertRow ( row )其中参数 row 表示插入行前面一行的行号。若 row 为 0,则在最后 行插入新行。LnsertRow()函数的功能为在数据窗口控件中的指定行前面插入一行。如果数据窗口中某些列定义了默认值,那么在新插入行显示之前,相应数据项的值首先使用默认值进行初始化。函数执行成功时返回新插入行的行号,函数执行出错时返回1;如果任何参数的值都
25、为NULL,则 InsertRow()函数返回 NULL。新插入的行的编辑状态为 New!,为该行输入数据以后,其编辑状态变为 NewModify!,这时该行才会包含在改变行总数(由 ModifiedCount 函数获得)之中。(3) DeleteRow()函数DeleteRow()函数的调用格式为:dwcontrol.DeleteRow ( row )其中,dwcontrol 表示数据窗口控件名;row 表示要删除数据行的行号,当该参数的值为 0时,删除当前行。删除了数据窗口中的行之后,数据库中的数据并没有变动,只有在应用程序执行了数据窗口控件的 Update()函数之后,数据库中的相应数据
26、才会被删除。(4) RowsMove()函数RowsMove()函数的调用格式为:dwcontrol.RowsMove ( startrow, endrow,movebuffer, targetdw, beforerow, targetbuffer ) 其中,参数 startrow 表示移动行的起始行,endrow 为结束行,movebuffer 为源缓冲区, targetdw 为目标数据窗口控件,beforerow 表示数据行移动到另外缓冲区的位置,targetbuffer 为目标缓冲区。RowsMove()函数的功能是将一个数据窗口控件中指定的行移动到另一个数据窗口,或将同一个数据窗口控件
27、中一个缓冲区的指定行移动到另一个缓冲区中。RowsMove()函数的返回值为 Integer 类型。函数执行成功时返回 1,发生错误时返回1。如果任何参数的值都为 NULL,则 RowsMove()函数返回 NULL。使用 RowsMove()函数把某些行复制到目的数据窗口控件的主缓冲区中后,这些行的修改状态为 NewModified!。此时,如果应用程序使用 Update()函数更新目的数据窗口控件对应的表,那么 PowerBuilder 将对新插入的行生成 SQLINSERT 语句,并把这些语句发送给数据库管理系统。如果在同一个数据窗口控件的不同缓冲区之间移动行,PowerBuilder
28、能够自动改变这些行的状态。例如,如果把未修改过的行从主缓冲区移动到同一个数据窗口的删除缓冲区,那么这些行将被标记为删除状态。如果又把这些行从删除缓冲区中移动到主缓冲区中,则这些行的状态恢复为原来的 NotModified!。需要注意的是,当把一个数据窗口中的某些行移动到另一个数据窗口之后,又把它们移动回原来的数据窗口,那么这些行的状态将变为 NewModified!,这是因为它们是在不同的数据窗口中移动。利用 RowsMove()函数可以实现从数据窗口的主缓冲区中移动多行数据到删除缓冲区(这时只有在应用程序执行了数据窗口控件的 Update()函数之后,数据库中的相应数据才会被删除),也可以把
29、删除缓冲区中的数据移动到主缓冲区中,这样就在应用程序中实现了恢复(Undo)功能。(5) Update()函数Update()函数的语法为:dwcontrol.Update ( accept , resetflag ) 其中,各参数意义如下。 dwcontrol:数据窗口控件名。 accept:可选项,boolean 类型,指定数据窗口控件在更新数据库之前是否自动执行 AcceptText()的功能,该功能把编辑框中的内容放置到缓冲区中。有效取值为:TRUE,默认值,执行 AcceptText()函数的功能(如果数据没有通过有效性验证,那么数据更新过程被取消);FALSE,不执行 Accept
30、Text()函数的功能。 resetflag:可选项,boolean 类型,指明更新数据库后是否自动复位更新标志。有效取值为: TRUE,默认值,复位更新标志。 FALSE,不复位更新标志。该函数的功能是把数据窗口控件中所有的数据修改(插入、删除、修改等) 传送到数据库,从而更新数据库中的数据。Update()函数在更新数据库之前会调用 AcceptText()函数把“漂浮”在当前行/列上的编辑框中的内容放入到数据窗口控件的缓冲区中。Update()函数的返回值为 Integer 类型。函数执行成功时返回 1,发生错误时返回1。如果任何参数的值都为 NULL,则 Update()函数返回 NU
31、LL。在默认情况下,Update 函数在完成更新数据库操作以后自动重置编辑状态标记,但是如果用户需要在完成其他有效性检验以后再重置这些标记,可以将 Resetflag 置为 False,然后,当确定更新时调用 ResetUpdate 函数,重置数据项的编辑标记。另外,在 ItemChanged 事件中调用 Update 函数时,一定要将 accept 参数置为 FALSE,以避免应用程序陷入死循环或发生堆栈错误。以后还会讲到,用户还应避免在 ItemChanged事件中调用 AcceptText 函数,因为该函数的调用将触发 ItemChanged 事件。但是,在 ItemChanged 事件
32、将 Update 函数的 accept 参数置为 FALSE 时也会产生一个问题,因为此时更新的是数据项中的“旧”值,新值还在可编辑控件中。要解决这个问题,就需要在该事件中适当地调用 Setltem 函数。10.2 数据窗口控件的重要属性、事件和函数(5)(6) ResetUpdate()函数ResetUpdate()函数的语法为:dwcontrol.ResetUpdate ()参数 dwcontrol 指数据窗口控件名。该函数用于清除数据窗口控件主缓冲区、过滤缓冲区的更新标志并清空删除缓冲区。该函数执行成功时返回 1,发生错误时返回1。如果 dwcontrol 的值为 NULL,则Reset
33、Update()函数返回 NULL。当需要在一个事务中更新多个数据窗口时,应用程序可以在更新每个数据窗口时都不清除更新标志。只有所有的数据窗口更新都成功完成后,才能对每个数据窗口调用ResetUpdate()函数清除更新标志。如果某个数据窗口的更新失败,应用程序可以保留更新状态,提醒用户更正错误,之后重新更新数据窗口。使用数据窗口控件的对象函数GetItemStatus()可以找到哪些行标志为更新状态。如果某行在删除缓冲区中,或该行虽然在主缓冲区或过滤缓冲区,但其具有 NewModified!或 DataModified!的状态,那么该行的更新标志被设置。清除更新标志之后,主缓冲区或过滤缓冲区
34、中的行具有 NotModified!或 New!状态,并且删除缓冲区被清空。例如,当需要更新两个数据窗口对象时,可编写如下代码:int rtncodeCONNECT USING SQLCA;dw_1.SetTransObject(SQLCA)dw_2.SetTransObject(SQLCA)rtncode = dw_2.Update(TRUE, FALSE)IF rtncode = 1 THENrtncode = dw_1.Update(TRUE, FALSE)IF rtncode = 1 THENdw_1.ResetUpdate()dw_2.ResetUpdate()COMMIT USIN
35、G SQLCA;ELSEROLLBACK USING SQLCA;END IFEND IF(7) Reset()函数Reset()函数的调用方法为:dwcontrol.Reset()该函数用于清除数据窗口控件中的所有数据。执行该函数和在数据窗口中删除数据不同,它只影响应用程序,对数据库不做任何操作。例如,当在数据窗口中使用 DeleteRow 函数删除一条数据并更新以后,数据库中的该数据不再存在。而当调用了 Reset 函数以后,数据库没有发生任何变化。如果用户使用了按需检索(Retrieve As Needed)选项,调用 Reset 函数将清除已经检索出 来的数据行,但是由于是按需检索,数
36、据窗口会立即检索出下一批数据。如果想避免这种情况发生,可以在调用该函数之前调用 DBCancel 函数。例如:dw_1.DBCancel()dw_1.Reset()2. 用于在数据窗口界面中滚动数据行的函数数据窗口控件包括 6 个在主缓冲区中滚动显示数据行的函数,分别是Scroll、ScrollToRow、ScrollNextPage、ScrollPriorPage、ScrollNextRow 和 ScrollPriorRow()函数。(1) Scroll 和 ScrollToRow 函数Scroll 函数按参数 row 指定的行数滚动数据窗口中显示的数据,调用语法为:dwcontrol.Sc
37、rolI(number)当 row 为正数时,数据向下滚动,当 row 为负数时,数据向上滚动。如果函数调用成功,将返回在控件中第一行显示的数据行号。ScrollToRow 函数用于将数据滚动到用户指定行号 row 的数据行。它的语法为:dwcontrol.ScrollToRow(row)调用该函数以后,指定的数据行变为当前行,但是并不高亮显示该行,用户可使用SelectRow 高亮显示当前行。(2) ScrollNextPage 和 ScrollPriorPage 函数这两个函数用于在数据窗口控件中整页滚动数据,每一次滚动都将改变当前行,但是不改变当前列,调用方法很简单:dwcontrol.
38、ScrollNextPage()dwcontrol.ScrollPriorPage()这两个函数返回相同的值,都是显示在控件顶端的数据行号。(3) ScrollNextRow 和 ScrollPriorRow 函数这两个函数用于逐行滚动数据,每一次滚动都会改变当前行,但是不改变当前列。调用格式是:dwcontrol.ScrollNextRow()dwcontrol.ScrollPriorRow()使用数据窗口对象的按钮增强对象,也可以实现这些函数的功能。3. 用于行列控制和数据项的函数PowerBuilder 的数据窗口控件提供了 7 个用于行列控制和数据项控制的函数,下面分别介绍。(1) G
39、etRow()函数GetRow()函数用于返回数据窗口当前行的行号。语法格式为:dwcontrol.GetRow()参数 dwcontrol 为数据窗口控件名。该函数的返回值为 Long 数据类型。函数执行成功时返回数据窗口控件 dwcontrol 的当前行;如果没有当前行,函数返回 0;发生错误时函数返回1;如果 dwcontrol 的值为 NULL,则返回 NULL。需要注意的是,数据窗口的当前行并非总显示在数据窗口当前的可视区域中,比如,如果当前插入点位于数据窗口的第 10 行、第 5 列,然后用户通过拖曳滚动条把可视区域移动到第 50 行,那么,虽然第 10 行被移出数据窗口的可视区域
40、,但是当前行依然是第 10 行。当用户单击了第 60 行后,第 60 行会变成当前行。因此,有时需要调用 ScrollToRow 等函数将当前行滚动到可视区域。(2) SetRow()函数SetRow()函数用于设置指定行为的数据窗口控件的当前行。语法格式为:dwcontrol.SetRow(row)参数 dwcontrol 为数据窗口控件名,row 为 long 类型,指要设置为当前行的行号。该函数的返回值的 Integer 类型。函数执行成功时返回 1,发生错误时返回 1。如果参数 row 的值小于 1 或大于数据窗口的总行数,那么 SetRow()函数失败。如果任何参数的值都为NULL,
41、则 SetRow()函数返回 NULL。执行了 SetRow()函数后,数据窗口的光标移动到新的当前行上,但 SetRow()并不会滚动数据窗口,以使新的当前行显示在数据窗口中。因此,有时需要调用 ScrollToRow 等函数将当前行滚动到可视区域。SetRow()函数可能会触发数据窗口控件ItemChanged、ItemError、ItemFocusChanged、RowFocusChanged 事件。不要在数据窗口控件的上述事件的事件处理程序中调用 SetRow()函数。10.2 数据窗口控件的重要属性、事件和函数(6)(3) RowCount()函数RowCount()函数用于返回数据
42、窗口控件当前可用的行数(提取的所有行数减去删除的行 数 ,加 上 插 入 的 行 数 , 再 减 去 过 滤 掉 的 行 数 , 即 当 前 主 缓 冲 区 中 的 数 据 行 数 )。 语 法 格 式 为 :dwcontrol.RowCount()参数 dwcontrol 为数据窗口控件名。该函数的返回值为 Long。函数执行成功时返回主缓冲区中数据的行数,发生错误时返回1。如果 dwcontrol 的值为 NULL,则 RowCount()函数返回 NULL。(4) GetColumn()函数GetColumn()函数用于得到数据窗口控件当前列的列号。当前列是指当前得到输入焦点的数据项所在
43、的列。语法格式为:dwcontrol. GetColumn()该函数的返回值为 Integer 类型。函数执行成功时返回数据窗口控件 dwcontrol 当前列的列号;如果没有当前列(在所有列的跳转次序 (即 tab 值)均设置为 0 的情况下,所有列都不能编辑),则函数返回 0;发生错误时返回 -1;如果 dwcontrol 的值为 NULL,则 GetColumn()函数返回 NULL。当应用程序在 Clicked 或 DoubleClicked 事件中调用 GetColumn()或 GetClickedColumn()函数时,得到的列号有可能不同。因为除非单击的刚好是当前列,在 Clic
44、ked 或 DoubleClicked事件处理程序执行完毕之前,用户单击或双击的列并没有变成当前列,执行了上述事件处理程序后,用户单击或双击的列才可能成为当前列。如果需要得到用户单击或双击列的列名,则可使用 GetColumnName()函数。(5) SetColumn()函数SetColumn()函数用于设置指定列为数据窗口控件的当前列。语法格式为:dwcontrol.SetColumn (column)其中,参数 dwcontrol 为数据窗口控件名,column 为指定的新当前列。column 参数可以使用列名(string 类型)也可以使用列号 (integer 类型)。执行 SetC
45、olumn()函数后,光标移动到当前列上,但并不左右滚动数据窗口。只有可编辑列才能成为当前列。不要在数据窗口控件 ItemChanged、ItemError、ItemFocusChanged 的事件中使用该函数,因为这个函数可能会触发这些事件。(6) GetItem*函数Getitem*函数用于获得数据项的GetItemString、GetItemDate、 GetItemDateTime、GetItemTime、GetItemNumber 和GetItemDecimal 函数,并且这些函数的返回值与其函数名的意义相同,这里以GetItemDatetime 为例讲述该函数的使用。GetItem
46、DateTime()的功能是得到数据窗口控件中指定行、指定列的 DateTime 型(日期时间型)数据值。利用该函数,应用程序既能够得到原始缓冲区( 从数据库中检索出的值,用户对数据窗口中数据的修改在下次检索之前不影响这些值)中的值,也可以得到主缓冲区、删除缓冲区、过滤缓冲区中的当前值。该函数的语法格式为:dwcontrol.GetItemDateTime( row, column , dwbuffer, originalvalue )其中,参数 dwcontrol 为数据窗口控件名;row 为 long 数据类型,指要得到数据值的单元所在的行;column 指要得到数据值的单元所在的列,该列
47、的数据类型必须是 datetime 类型。column 参数可以是列号 (integer 类型),也可以是列名(string 类型)。dwbuffer 是 dwbuffer 枚举类型,指示想得到数据窗口哪个缓冲区的值。dwbuffer 的有效取值为:Primary!,为默认值,表示得到主缓冲区中的数据(未被删除或过滤掉的数据) ;Delete! ,表示得到删除缓冲区中的数据(从数据窗口中已经删除的数据 );Filter!,表示得到过滤缓冲区中的数据( 从数据窗口中已经过滤掉的数据)。另一个参数 originalvalue 为 boolean 类型,指示要得到的指定单元(由行/列值决定)是原始值
48、还是当前值。该参数的有效取值为 True 时,表示得到原始值(从数据库中检索出的初始值,该值不受当前修改的影响),为 False 时,为该参数的默认值,表示函数将得到指定单元的当前值。GetItemDateTime()函数执行成功时,返回指定单元的日期时间型数据值;如果指定单元的数据值为 NULL,则函数返回 NULL;如果发生错误,则函数返回 1900-01-01 00:00:00.000000;如果任何参数的值为都 NULL,则函数返回 NULL。其他几个函数的语法与 GetItemDateTime()函数类似,这里不再赘述。(7) SetItem()函数SetItem()函数用于设置数据窗口控件中的指定数据项的值。该函数的语法为: