赞
踩
数据窗口控件
数据窗口控件-datawindow
PB9.0提供了28个属性、35个默认事件、162个函数。注意与数据窗口对象的区分。
【其他】
■脚本的执行效率
*尽量不要在RetrieveRow事件下编写脚本(包括注释)。
*如果数据窗口的DoubleClicked事件中编写了脚本,那么在数据窗口的C1icked事件中的脚本应该尽量短,否则双击事件中的脚本永远不可能得到执行。一般来说,Cliked中脚本的执行时间和两次击鼠标之间的间隔时间之和,不应该大于操作系统中所设定的鼠标双击时间间隔,否则双击事件永远不可能触发,双击时仅仅是接连两次触发c1icked事件。
*在数据窗口中录入数据时,事件EditChanged是触发频率最高的,每一个按钮都触发该事件;触发频率仅次于该事件的是ItemChanged事件和ItemFocusChanged,只要修改了单元中的内容,每次触发ItemFocusChanged事件都会触发ItemChanged事件。在这些事件下编写过长的脚本会非常影响录入工作的效率。同样,事件RowFocusChanged的触发频率也是相当高的。一般来说是可以避免在这四个事件中编写脚本的。
■dwo参数使用
数据窗口的某些事件中可以使用一个称为dwo的变量,该变量保存数据窗口中的部分信息,用数据窗口的属性可以读取这些信息dwo.type:读取在dwo中保存的对象类型。对象类型可能有bitmap、button、column、compute、graph、groupbox、line、ole、ellipse、rectangle、roundrectangle、report、tableblob、text、datawindow(当用户没有单击特定对象时)
dwo.Name:column的列名
dwo.Primary[row]:column的数据
dwo.Selected:选中column的数据
■数据缓冲区
数据窗口在运行时要创建四个缓冲区,分别是主缓冲区、删除缓冲区、过滤缓冲区和原始缓冲区,这四个缓冲区各司其职、共同配合,来保证数据窗口对数据的正确处理。下面分别加以介绍。
1、主缓冲区-Primary
这是最重要的一个缓冲区,保存的是当前显示在数据窗口中的所有数据以及它们的修改状态。在保存数据时使用这些状态生成SQL语句。平常的大多数操作都是针对该缓冲区,函数中的缓冲区参数缺省也是该缓冲区。
2、删除缓冲区-Delete
该缓冲区保存所有删除了的数据。保存数据时,该缓冲区中的数据用来产生delete语句。在数据没有提交到数据库之前,可以从该缓冲区中将数据恢复出来。数据提交后,该缓冲区中的数据清空。
3、过滤缓冲区-Filter
该缓冲区中保存的是没有通过过滤规则的所有数据,这些数据在存储时同主缓存区的数据一起生成相应的insert或update语句。
4、原始缓冲区-original
用来保存从数据库中检索到的初始值,在保存数据时用来生成where语句。
上面这四个缓冲区中,original缓冲区在脚本中很少使用,其他三个经常涉及到,很多数据窗口函数都需要指定对这三个缓冲区中的哪个进行操作,大多数情况下都使用缺省的缓冲区Primary!。这三个缓冲区,除了保存相应的数据外,都自动维护这些数据的修改标志,它们之间的协作也是自动维护的。例如,当使用过滤函数时,没有通过过滤规则的数据自动从Primary缓存区移送到Filter缓存区;执行删除操作时,数据自动从Primary缓存区移送到Delete缓存区。所有这些数据的移送无需脚本的干预,只管使用相应的函数即可。
■DWBuffer
Primary! 0
Delete! 1
Filter! 2
■DWItemStatus
NotModified! 0
DataModified! 1
New! 2
NewModified! 3
■编辑控件
和数据窗口控件打交道都是通过编辑控件进行的。在数据窗口中录入数据、修改数据,实际上是在修改单元上的编辑控件中的内容。当编辑控件移动到另外单元上之前,要对编辑控件中的数据进行校验,如果能通过字段的校验规则,就保存到字段中。编辑控件是可以移动的,需要编辑哪个单元,编辑控件就移动到哪个单元上,接受输入或者修改。
编辑控件在没有离开当前字段时,用户录入或者修改的数据就不会被保存到字段中,如何确保在数据窗口失去焦点时,最后位置上编辑框中的内容不被遗漏呢?前面介绍了在数据窗口的LoseFocus事件中编写如下脚本:
this.AcceptText()
这个方法在很多情况下能解决该问题。美中不足的是,如果编辑框中的内容不能通过字段的校验规则,有时会显示两次错误信息窗口。造成两个错误信息窗口,往往是在选择其他单元时发生,在数据窗口失去焦点之前(如单击“保存”按钮等)只会显示一个错误信息窗口。用户选择其他单元时,编辑框中的数据开始进行校验,不能通过校验规则,显示校验错误信息,在显示校验错误信息时数据窗口失去焦点,触发数据窗口的LoseFocus事件执行AcceptText函数,又一次显示校验错误窗口。
所以,显示两次校验错误窗口的原因是LoseFocus事件中的AcceptText函数造成的。可以想法让该函数在这种情况下不执行。为此定义一个实例变量:
Boolean ib_accept = True
该变量用来表示是否正确通过了校验,然后将LoseFocus中的脚本改成下面的脚本:
If ib_accept Then
This.AcceptText()
Else
ib_accept = true
End If
在数据窗口的ItemError事件中编写脚本:
ib_accept = False
这样就可以解决显示两个校验错误信息窗口了,并且不会遗漏最后一个编辑框中的内容。
*当在某个单元中修改或者录入数据后,编辑框要离开时,要进行4个校验步骤,前面两个步骤由PowerBuilder完成,后面两个由开发者编写。
(1)看数据和编辑前相比是否发生了改变,没有改变则不做任何处理。
(2)检查测试此值是否违反了任何一个在字段上定义的有效性校验规则,违反则拒绝接受此值,并触发ItemError事件。
(3)检查此值是否与编辑前真的不同,没有改变则终止有效性校验。
(4)检查开发人员在ItemChanged事件中编写的脚本。具体的发生情况取决于分配给被称为动作代码的值。
■读取和设置数据
读取:
1、使用函数
dw_1.getitemX()
2、直接使用数据窗口对象属性来读取数据
dw_1.object.data.primary.current[row,column]
该语句的格式是:
dwcontrol.object.data[buffer[.whichvalue]][row,column]
dwcontrol是数据窗口控件名称。
whichvalue既可以是current(缺省值),也可以是original。这样就允许用户访问一个列的初始值或当前值。
row和column是要访问的单元所在的行号及列号。
object、data是保留字,buffer是缓存区的名称,有Delete、Primary、Filter。
这种引用方法速度比较快,尤其读取大量数据时。
设置:
使用函数
SetItem()
SetText()
【属性】
▲DataObject 数据源
▲Title
用来显示在数据窗口的标题条(TitleBar)上的一个字符串。建议该字符串要有一定的含义,能够标明数据窗口的用途或者其中的数据的类别。该属性的缺省值none。当属性TitleBar为True时,该属性起作用。
▲Visible
是否显示数据窗口控件,缺省为True。有时为了向其他数据窗口提供数据,除了使用datastore控件外,还可以使用Visible属性为False的数据窗口。如果仅仅是为了处理数据,不赞成使用Visible属性为False的数据窗口,而应该使用Datastore对象,这样可以节省计算机资源,提高处理效率。
▲Enabled
数据窗口控件是否可以获得焦点,缺省为True。可以在脚本中修改该属性以**用户执行了某些特定操作后再允许操作数据窗口。
▲TitleBar
是否显示标题条,缺省为False。使用该属性可以在数据窗口上部显示标题条,类似于窗口的标题条。设置属性为True后,用户就能够拖动数据窗口。
▲ControlMenu
是否显示控制菜单,缺省为False。该属性当TitleBar属性为True时才有效。
▲MaxBox和MinBox
是否显示最大和最小控制按钮,缺省为False。当属性TitleBar为True时,该属性有效。属性TitleBar和ControlMenu、MinBox、MaxBox共同控制数据窗口的外观是否像窗口的外观。
▲HscrollBar和VscrollBar
这两个属性用来控制数据窗口控件的横向和纵向滚动条是否显示。设置为True时,滚动条可以根据需要自动显示,数据够显示时则不出现滚动条。
▲LiveScroll
该属性是一个比较重要的属性,缺省为True,表示当拖动垂直滚动滑块时,数据窗口中的行也跟随滚动;属性为False时表示拖动垂直滚动滑块时,数据窗口中的行不跟随滚动,放开垂直滚动滑块后,数据窗口中的数据才滚动到适当数据行上。建议选中该属性,这样当数据很多时,用户就可以拖动垂直滚动小滑块来快速浏览数据了。
▲HsplitScroll
该属性是一个非常有实际用途的属性。该属性决定是否显示分割滚动条,缺省为False。当数据窗口比较宽,要显示水平滚动条时,建议将该属性设置为True。
▲RightToLeft
该属性为True时表示数据窗口中的所有字符都从右向左显示。缺省为False。当设置该属性为True时,还必须要操作系统的支持,该属性才能起作用。
▲Resizeable
用户是否可以调整数据窗口的大小,缺省为False。
▲Border
是否显示边框,默认为True,只有在True的情况下BorderStyle才起作用
▲BorderStyle
取值为枚举型,用来定义数据窗口边框样式。有四个取值:StyleBox!、StyleLowered!、StyleRaised!、StyleShadowBox!,缺省边框类型为StyleLowered。
▲Icon
用来给数据窗口指定标题条左上角的图形,缺省为Windows标志图。
【事件】
◆Clicked
鼠标左键在数据窗口控件上任意位置单击时触发该事件。该事件中有4个参数,可以在脚本中直接使用。
xpos:表示和数据窗口最左侧的距离的整数。
ypos:表示和数据窗口最上部的距离的整数,不包括标题条。
row:表示用户所单击的行号的long型数。
dwo:用户单击对象,是DWObject类型。
在该事件的脚本中使用这些参数,可以给用户一些提示信息或者获取用户单击内容的信息。
返回值:0表示继续处理,这是缺省值。1表示停止处理。
*当选择和当前行不同的数据行时可以触发ItemFocusChanged和RowFocusChanged事件,当单击当前行的其他字段时可以触发ItemFocusChanged事件。DoubleClicked事件也可以触发该Clicked事件。
◆DBError
在数据窗口控件中发生数据库错误时触发该事件。该事件有以下参数。
SQLdbcode:long类型的错误代码,具体含义由DBMS指定。当DBMS没有指定错误代码时,SQLdbcode提供4个错误代码,-1表示事务对象参数错误而不能联结到数据库,-2表示不能联结到数据库,-3表示因为其他用户的修改导致用来进行检索或修改的键值在数据库中已经不存在而产生错误,-4表示向数据库中写blob对象时失败。
SQLerrtext:string类型,数据库指定的错误信息。
SQLsyntax:string类型,当错误发生时,发送到数据库的SQL语句。
buffer:DWBuffer枚举型,表示导致错误的数据所在的缓冲区。
row:long类型,导致错误的数据的行号。
返回值:可以用return语句任意指定返回什么数据。有特定含义的返回值是0和1。0表示显示错误信息,1表示不显示错误信息。
◆DoubleClicked
鼠标左键在数据窗口控件中双击时触发该事件。该事件中的4个参数和Clicked事件中的名称及含义完全相同,也可以直接在该事件的脚本中直接使用。
该事件的返回值可以用return指定。有特殊函数的返回值是0,表示继续处理。
◆EditChanged
在数据窗口控件的编辑框中每次按钮都触发该事件。一般很少在该事件下编写脚本。该事件提供三个参数。
row:long类型,当前编辑的行号。
dwo:DWObject类型,正在编辑的对象。
data:String类型,当前编辑框中的内容。
返回值:可以用return指定任意返回值,0表示继续处理。
*每次编辑时触发
◆Error
当数据窗口对象中的数据或者表达式错误时触发该事件,在分布式系统中联结发生错误时也会触发该事件。和DBError事件不同的是,该事件在没有和数据库交互时就有可能触发,而DBError事件触发时肯定和数据库发生了交互。通常在该事件中编写脚本,提供对错误的处理。该事件提供了很多参数。
errornumber:unsigned integer类型,由PowerBuilder指定的错误代码号。
errortext:string类型,由PowerBuilder指定的错误信息。
errorwindowmenu:string类型,造成错误的脚本所在对象的父对象的名称。
errorobject:string类型,造成错误的脚本所在的对象的名称。
errorscript:string类型,造成错误的语句所在的脚本的全部内容。
errorline:unsigned integer类型,造成错误的语句在其脚本中所占的行号。
action:在Error事件下的代码执行完后,该参数取值由脚本设定。可以指定的值有:ExceptionFail!表示错误处理失败(执行该值有可能触发应用的SystemError事件);ExceptionIgnore!表示忽略错误继续执行(要谨慎使用该取值,因为忽略错误有可能将再次导致其他错误);ExceptionRetry值只能用于OLE,对于数据窗口控件,没有该取值,该取值表示再次执行刚才造成错误的功能;ExceptionSubstituteReturnValue!表示使用参数returnvalue的返回值,而不是返回OLE服务器或数据窗口控件的错误代码,并且取消错误状态。
returnvalue:当Action指定为ExceptionSubstituteReturnValue!时返回该参数的取值。
*对于数据窗口控件来说,如果在运算数据或属性表达式时发生了错误,将进行如下的错误处理过程:
a.触发Error事件;
b.如果Error事件中没有脚本或者Action变量设置成ExceptionFail!,则触发应用的SystemError事件;
c.如果SystemError事件下也没有脚本,便会发生应用程序错误,然后终止应用程序。
所以,在该事件或者应用的SystemError事件下应该编写脚本。这样才不至于退出应用程序,使用户没有处理的机会,甚至录入了半天的数据连个保存的机会也没有了。
返回值:该事件没有返回值,也不在该事件中使用return语句。
◆ItemChanged
当某单元(行和列的交叉点叫做单元)编辑后(内容改变),光标要离开时触发该事件,如使用了Enter按钮、单击了Tab按钮、使用了光标键、在其他字段上单击了鼠标左键等。当编辑完一个单元的内容而没有离开该单元,这时数据窗口失去焦点,这种情况不会触发该事件(所以在LoseFocus事件中要使用函数AcceptText)。三个参数row、dwo和data的含义和EditChanged事件的三个参数完全相同。
返回值:可以使用return语句返回任意值。0表示接受刚刚修改的数据,该值是缺省值;1表示放弃刚才的修改,不允许焦点离开;2表示放弃刚才的修改,允许焦点离开。
*编辑框内容有变化并离开此编辑框时触发;注意:当editchanged事件下有代码,编辑框内容有变化且离开此编辑框时,不会触发此事件
◆ItemError
当某单元被编辑后光标要离开时,如果单元中的新数据不能通过有效性校验,则触发该事件。(同ItemChanged:当编辑完一个单元的内容而没有离开该单元,这时数据窗口失去焦点,这种情况不会触发该事件)该事件在ItemChanged事件之前触发,该事件触发就不能再触发ItemChanged事件了。该事件中的三个参数和ItemChanged事件中的三个参数完全相同。
返回值:可以使用return语句返回任意数值, 0表示放弃修改的数据,并显示错误信息,焦点不离开该单元,该取值是缺省值;1表示放弃修改的数据但不显示错误信息提示,焦点不离开该单元;2表示接受刚刚修改的错误数据;3表示放弃刚刚修改的数据,并且焦点不离开该单元。
◆ItemFocusChanged
当焦点离开某单元时触发该事件(不管内容有没有改变)。该事件提供了row和dwo两个参数,含义和前面介绍的完全相同。可以使用return语句返回任意数值,0表示继续处理。
*不管编辑框中的内容有没有改变,离开编辑框时触发该事件,注意:当离开数据窗口时不触发
◆PrintEnd
当打印工作完成时触发该事件。参数PagesPrinted可以在脚本中直接使用,是一个long类型的变量,表示已经被打印的页数。
◆PrintPage
在数据窗口每页进行打印格式处理之前触发该事件。参数Copy和PageNumber在脚本中可以直接使用,表示该页要打印的份数和当前页的页号。返回值0表示不要跳过当前页,1表示跳过当前页。一般在该事件下编写脚本显示打印进度信息,例如:
st_1.text="正在打印第"+String(pageNumber)+ "页……"
也可以在该事件中决定是否真正要打印该页。例如,下面的脚本只打印偶数页码的页面:
If Mod(pagenumber,2) = 0 Then
return 0
Else
return 1
End If
◆PrintStart
数据窗口打印开始时触发该事件。该事件中的参数PagesMax是一个long型变量,表示将要被打印的总页数(不包括跳过的页)。返回0表示继续处理。
◆RetrieveEnd
当数据窗口检索完毕时触发该事件。参数rowcount是一个long型变量,表示检索完后检索到的记录数。
◆RetrieveRow
每检索到一条记录时都触发该事件。参数row是long类型变量,记录当前检索到的数据的序号。返回值0表示继续检索,1表示停止检索。检索大量数据之前可以设置中断标志,让用户在检索过程中可以停止检索。
◆RetrieveStart
当数据窗口的检索操作将要开始时触发该事件,该事件中没有参数。返回值0表示继续执行,该值是缺省值,1表示不执行检索,2表示在检索之前不清除数据行和缓存区。通常不在该事件下编写脚本,即使编写脚本,一般也是利用返回值2的特性来控制检索操作不清除缓存区,这样可以将检索到的数据添加到数据窗口中,并且在数据窗口中保留检索之前的数据。
◆RowFocusChanged
当前行改变时触发该事件。CurrentRow参数是一个long类型变量,保存当前记录号。该事件下的典型编程是修改当前行标识,将当前行明显地标识出来,可以让用户清楚地知道要对哪行进行操作,在该事件和其他事件的配合下共同修改当前行标识。
*不管内容有没有改变,当前行改变时触发;在离开数据窗口时不触发
*RowFocusChanging:当前行改变前触发;参数currentrow触发前所在行,newrow触发后当前行;rowfocuschanged的currentrow等于rowfocuschanging的newrow
◆ScrollHorizontal
当使用光标键、Tab按钮、滚动条等等在数据窗口中进行水平滚动时触发该事件。很少在该事件上编写脚本。
◆ScrollVertical
当在数据窗口中使用光标键、滚动条、Tab键等进行上下滚动时触发该事件。通常在该事件中编写脚本来改变当前行。因为当上下滚动数据窗口时,如果当前行不在当前显示的区域内,则容易给用户造成错觉,可以在该事件中编写脚本将当前页面的第一行数据设置为当前行。使用Describe和Evaluate函数可以实现该功能
◆SQLPreview
当执行函数Retrieve、ReselectRow和Update时,SQL语句要提交到DBMS,这时触发该事件。该事件的参数比较复杂。
request:取值为PreviewFunctionReselectRow!、PreviewFunctionRetrieve! 或PreviewFunctionUpdate!分别代表触发该事件的函数是ReselectRow、Retrieve和Update。 SQLtype:引起该事件的SQL语句类型。取值为PreviewDelete!、PreviewInsert!、PreviewSelect!、PreviewUpdate! 分别表示是Delete 、Insert、Select、Update语句。
SQLsyntax:string类型,取值为提交到DBMS的SQL语句。
buffer:当前SQL语句所涉及到的数据所在的缓存区,取值为枚举型,Delete!、Filter!、Primary!分别表示删除缓存区、过滤缓存区和主缓存区。
row:long类型变量,表示该事件中涉及到的记录数。
返回值0表示继续处理,1表示停止处理,2表示处理下一个SQL请求。
◆UpdateEnd
当从数据窗口控件发送来的对数据库的修改都完成后触发该事件。该事件的三个参数RowsInserted、RowsUpdated、RowsDeleted都是long类型的变量,分别表示插入、修改和删除的记录数。
◆UpdateStart
在调用了update函数之后、开始修改之前触发该事件,该事件没有参数。返回值0表示继续处理,1表示停止修改。
◆LoseFocus
数据窗口失去焦点时触发。
该事件中编写脚本,主要是保证用户在数据窗口中最后输入的内容不丢失。数据窗口中的输入内容只有当焦点改变时才真正转交给数据窗口,否则只是保存数据窗口的编辑控件。脚本比较简单:this.AcceptText()
*GetFocus:数据窗口得到焦点时触发。
【函数】
★SetTransObject
语法:dwcontrol.SetTransObject ( transaction )
功能:给数据窗口或者datastore控件dwcontrol设置事务对象transaction,缺省事务对象是SQLCA。
返回值:成功设置事务对象则返回1,执行过程中发生了错误则返回-1,有任意参数为Null时返回Null。
★Retrieve
语法:dwcontrol.Retrieve ( {, argument, argument . . . } )
功能:使用数据窗口控件的当前事务对象检索数据库中的数据。如果数据窗口控件对应的数据窗口对象定义了检索参数,则应该在该函数中指定检索参数,参数的个数和数据窗口对象的检索变量个数相等,对应的数据类型相兼容。
返回值:返回数据窗口控件主缓存区(PrimaryBuffer)中的记录数,如果检索数据时发生错误则返回-1,如果任意参数为Null则返回Null
*该函数的参数和数据窗口对象定义的参数的顺序要相同,类型要兼容。个数不能少于数据窗口对象定义的参数,即可以等于和多于数据窗口对象定义的参数,多的参数忽略。
★DeleteRow
语法:dwcontrol.DeleteRow ( row )
功能:删除数据窗口dwcontrol中的第row行数据,如果row为0则表示删除当前行的数据。
返回值:执行成功则返回1,执行错误则返回-1,如果任意参数为Null则返回Null。
*该函数执行后只是将被删除的数据从数据窗口的主缓存区移放到Deleted缓冲区,在数据库中并没有真正删除数据,当正确执行了Update函数并且使用commit语句提交了事务后,才真正从数据库中删除该数据
★InsertRow
语法:dwcontrol.InsertRow ( row )
功能:在数据窗口dwcontrol的第row行前插入一行空白数据。当指定row为0时,表示在当前行之前插入一行空白数据。
返回值:返回插入的数据的行号,如果执行过程中发生错误则返回-1,如果任意参数为Null则返回Null
★Update
语法:dwcontrol.Update ( { accept {, resetflag } } )
功能:提交数据窗口或者datastore中的数据。如果accept为True,表示在提交数据之前自动执行AccpetText函数,否则不执行该函数,该参数缺省为True;如果resetflag为True,表示数据提交后自动清除修改标识,该参数缺省为True。
返回值:执行成功则返回1,发生错误则返回-1,如果dwcontrol为Null则返回Null
★AcceptText
语法:dwcontrol.AcceptText ( )
功能:该函数执行时,首先对当前编辑框中的内容进行对应字段的校验规则,能够通过校验规则,则保存在对应字段中,否则显示校验信息提示错误。需要执行该函数的原因是,当在某字段上的编辑框中输入内容而没有移动光标到别的字段上时,其他控件获得焦点,此时编辑框中的内容不能被保存到字段中,所以就应该在数据窗口失去焦点时执行该函数。
返回值:执行成功则返回1,执行过程中发生错误则返回-1,如果dwcontrol为Null则返回Null。
*该函数在数据窗口的ItemChanged事件中不起作用,因为项目改变是发生在接受编辑框中内容之后
★ModifiedCount
语法:dwcontrol.ModifiedCount ( )
功能:获取数据窗口或者Datastore中被修改过但还没有提交到数据库中的记录数。
返回值:返回long类型的数据窗口控件中被修改过的记录数,如果没有记录被修改过或者修改后都已经保存到了数据库中则返回0,执行过程中如果发生错误则返回-1,如果dwcontrol为Null则返回Null。
*该函数获得的修改过的记录数包括主缓存区和Filter缓存区的被修改过的和新添加到数据窗口中的记录数
★DeletedCount
语法:dwcontrol.DeletedCount ( )
功能:获取数据窗口控件或者datastore控件dwcontrol中被删除的记录数。
返回值:返回long类型的已经被删除但还没有提交到数据库中的记录数,如果执行过程中发生了错误则返回-1,如果dwcontrol为Null则返回Null,如果没有删除过记录则返回0
★RowsMove
它可以将数据从一个缓冲区移动到另外缓冲区中。该函数的语法是:
dwcontrol.RowsMove ( startrow, endrow, movebuffer, targetdw, beforerow, targetbuffer )
其中,dwcontrol是进行移动操作的源数据窗口;startrow和endrow是要移动数据的范围(包括这两个行号的数据);movebuffer指要从哪个缓存区移出数据,可以是Primary!、Delete!、Filter!;targetdw是目标数据窗口控件名称;beforerow表示在目标数据窗口的哪一行之前插入移入的数据,如果该数值比目标数据窗口的行数大,则在最后插入移入的数据;targetbuffer是目标缓存区,取值同movebuffer一样。
★GetItemStatus和SetItemStatus
使用函数dwcontrol.GetItemStatus ( row, column, Primary! )可以获取该缓冲区内指定单元的状态,当参数column为0时,表示读取整个行的修改状态。有以下状态。
NotModified! :指定单元的数据和原始数据相同,没有修改过。
DataModified!:指定单元的数据和原始数据不同,修改过。
New!:该数据行是新增加的,但还没有在该行上输入数据。
NewModified!:该数据行是新增加的,并且已经在该行上录入了数据。
这些修改标识都是由数据窗口自动维护的,一般情况下没有必要编写脚本修改这些标记,但并不是说就不能修改。PowerBuilder提供了函数SetItemStatus,它的语法是:
dwcontrol.SetItemStatus ( row, column, dwbuffer, status )
其中,row参数指定将要修改状态的行;column参数指定将要修改状态的列(可以是整型的列号,也可以是string类型的列名),当列号为0时表示要修改row指定的整行的状态;dwbuffer指定要修改哪个缓冲区(肯定不能是original),status为上面的四个取值中的一个,但不是任意的取值,因为有些状态不能用该函数设置成另外一种状态,必须是能够转换的状态。下面列出了能够转换的状态。
期望的状态 New! NewModified! DataModified! NotModified!
当前状态
New! \ Yes Yes No
NewModified! No \ Yes New
DataModified! NewModified! Yes \ Yes
NotModified! Yes Yes Yes \
表中的Yes表示可以使用SetItemStatus进行该状态设置,No表示不会产生预期的状态,如果标明了某个特定的状态,则说明是新的状态,而不是期望的状态。例如,数据窗口dw_1的第1行第1列的当前状态为DataModified!,使用函数dw_1.SetItemStatus(1,1,New!)后,第1行第1列的状态改变为NewModified!。同样对于该数据窗口dw_1,如果使用函数dw_1.SetItemStatus(1,1,NotModified!),则会将其状态改变为NotModified!。当从一种状态不允许转变到另一种状态时,可以修改成其他一个中间状态,然后再进行一次转换。例如,要从new!改成NotModified,应该首先转换到DataModified!
★GetItemX
读取数据窗口中的数据
dwcontrol.GetItemX( row, column {, dwbuffer, originalvalue } )
其中的X可以替换成Date、DateTime、Decimal、Number、String、Time,所以读取数据的函数有6个。参数row表示要读取哪行的数据,是一个long类型数值。column代表列,可以是string型的列名,也可以是整型的列号。dwbuffer是DWBuffer枚举型,取值Primary!、Delete!、Filter!分别代表主缓冲区、删除缓冲区和过滤缓冲区。originalvalue为Boolean型,表示是否读取最近一次检索时检索到的初始值,当指定dwbuffer时必须指定该参数,该参数和dwbuffer都是可选的。函数正确执行则返回对应类型的数据,执行过程中发生错误则返回空值(""),任何参数为Null则返回Null
★SetItem和SetText
函数SetItem的语法格式是:
dwcontrol.SetItem ( row, column, value )
各个参数的含义如下。
dwcontrol:数据窗口或datastore控件名称。
row:要设置的数据所在行。
column:要设置的数据所在的列。可以用整型列号,也可以用string型列名。
value:要设置的值,应该和要设置的列的类型一致。
函数正确执行则返回1,这时数据窗口中row行column列显示的数据是刚刚用该函数设定的数据,如果函数执行过程中发生错误则返回-1。注意,该函数执行时仅仅检查函数中指定数据的类型和字段的类型是否一致,不会进行有效性校验,包括在数据窗口中设置的校验规则、在ItemChanged事件中编写的校验规则、在ItemChanged调用的校验规则都不会执行。
函数SetText的语法格式是:
integer dwcontrol.SetText ( string text )
功能是设置当前编辑框中的内容。注意,当编辑框离开当前单元时要进行有效性校验,如果校验数据正确,则当前字段接受该数据,否则触发ItemError事件。所以,可以使用该函数给带有校验规则的字段设置数据。
EG:
int li_i
dw_1.SetColumn("name") //使name列成为当前列
For li_i = 1 To dw_1.RowCount()
dw_1.SetRow(li_i) //使第I行成为当前行
dw_1.SetText("屁") //向当前编辑框中写入内容
Next
dw_1.SetColumn("本人") //选中性别列,保证最后一个也要通过校验规则
★SetColumn、SetRow和GetColumn、GetRow和GetClickedColumn、GetClickedRow和GetColumnName
设置当前列
integer dwcontrol.SetColumn ( string column)
integer dwcontrol.SetColumn ( integer column)
设置当前行
integer dwcontrol.SetRow ( long row )
得到当前列
integer dwcontrol.GetColumn ( )
得到当前行
long dwcontrol.GetRow ( )
得到用户单击的列
integer dwcontrol.GetClickedColumn ( )
得到用户单击的行
long dwcontrol.GetClickedRow ( )
得到当前列的名
string dwcontrol.GetColumnName ( )
★SetFilter、Filter和Find
这两个函数必须配对使用,首先使用函数SetFilter设置过滤规则,然后用函数Filter进行过滤。过滤规则是boolean类型的表达式,能够使用过滤规则的,将表达式为True的数据行显示在数据窗口中,使其为False的数据行被移送到数据窗口的Filter!缓存区。在设计数据窗口对象时也可以定义过滤规则,使用这两个函数可以根据需要来动态改变过滤规则。在设计时,指定了过滤规则的数据窗口可以使用这两个函数再进行过滤。每次过滤都是对数据窗口的Original!缓存区进行的,而不是在前一次过滤出来的数据基础上再次过滤。
函数SetFilter的语法是:
dwcontrol.SetFilter ( format )
其中,dwcontrol是要进行过滤的数据窗口控件名称。format是过滤规则,string类型。过滤规则是由字段、常量、运算符、函数构成的boolean表达式。需要取消过滤规则显示所有的数据时,可以指定过滤规则为空(""),如果让用户可以随便指定过滤规则,则可以使用Null的过滤表达式,这时PowerBuilder提供一个和数据窗口设计时相同的过滤规则指定窗口。该函数正确执行返回1,否则返回-1。执行完后,数据窗口中显示的数据没有发生变化,只有当执行了Filter函数后才按照刚刚指定的过滤规则显示数据。
该函数的语法是:
dwcontrol.Filter ( )
dwcontrol是和SetFilter中同名的数据窗口控件名称。该函数执行正确则返回1,否则返回-1,如果dwcontrol为Null则返回Null。
函数Find也可以用来进行查询。该函数可以在数据窗口中的指定范围查找符合某些条件的数据。该函数的语法格式是:
dwcontrol.Find ( expression, start, end )
其中,dwcontrol是要进行查找的数据窗口控件名称,expression是表达式,含义和注意事项同SetFilter中的完全相同。start和end都是long类型变量,用行号表示的查找范围,它们之间没有大小约束。函数返回的是在指定范围内找到的第一个符合条件的记录号,如果没有找到或发生了错误则返回0,如果参数有Null的则返回Null
★SetSort和Sort
数据的排序可以在数据窗口对象设计时就指定排序规则,也可以在脚本中动态指定。使用函数SetSort和Sort可以完成这一任务,它们和SetFilter、Filter一样也必须配对使用。函数SetSort设置排序的规则,不改变数据的显示,只有当执行了函数Sort时,数据才真正进行重新排列。
函数SetSort的语法是:
dwcontrol.SetSort ( format )
其中,dwcontrol为要进行排序的数据窗口控件的名称;format为排序规则,是string类型,由字段、函数、ASC或DESC、逻辑联结符、常数构成。可以使用字段名,也可以使用字段号来表示字段,字段号的格式是#X,其中X为正整数。该函数正确执行返回1,否则返回-1。
和SetFilter函数类似,当指定format为空("")时,可以取消排序,当指定format为Null时,可以由用户指定排序规则。
使用函数SetSort后,再使用Sort函数才能重新排列数据。
该函数的格式是:
dwcontrol.Sort ( )
其中,dwcontrol是和SetSort中同名的数据窗口控件名称。该函数正确执行则返回1,否则返回-1,如果参数dwcontrol为Null,则返回Null。
★SelectRow
选中指定的行
dwcontrol.SelectRow ( row, boolean )
其中,dwcontrol是数据窗口控件的名称;row是行号,该参数为0则表示是对数据窗口中的所有数据行进行操作;boolean表示是否选中,如果是True,表示选中行号row的数据行,如果是False则取消。该函数正确执行返回1,发生错误返回-1,如果参数有Null则返回Null。
★PrintSetup、Print、PrintOpen、PrintDatawindow、PrintClose、PrintCancel
PrintSetup():打印设置
PrintOpen():启动打印作业
PrintOpen函数用来打开一个作业,并返回当前可以使用的打印作业号,该打印作业号可以标识当前的打印工作。该函数的语法是:
PrintOpen ( { jobname } )
如果发生错误,该函数返回-1。打印作业名称是可选的,名字在打印队列中。在打印作业的最后必须关闭打印作业,使PowerBuilder和Windows清除打印作业所占用的所有资源。因此,每个启动作业的语句都有一个关闭作业的语句相对应。
PrintClose()、PrintCancel():关闭打印作业
有两个函数可以用来关闭打印作业。PrintClose()函数把当前页传送给打印机,并关闭当前打印作业。语法格式为:PrintClose(printjobnumber)
函数PrintCancel()取消打印作业并删除当前的打印文件。这个函数可以与Print或者PrintDataWindow()函数组合使用。用于PrintDatawindow()的语法是:
DatawindowControl.PrintCancel()
用于Print()的语法是:
PrintCancel(printjobnumber)
PrintClose()函数和PrintCancel()函数是互相排斥的,成功调用过一个以后,不要在没有再次打开打印作业时调用另一个函数。
PrintDatawindow():
该函数是以单个打印作业的形式打印数据窗口控件中的内容。PowerBuilder使用数据窗口对象中定义的字体和布局进行打印。用这个函数可以在一个打印作业中打印多个数据窗口,但是每个数据窗口控件都从新的一页开始打印;如果要让几个数据窗口打印在同一页中,则需要利用底层的打印函数或将要打印在同一页中的数据窗口,创建成一个composite显示样式的数据窗口。PrintDatawindow函数的语法是:
PrintDatawindow(printjobnumber,datawindow)
其中,printjobnumber是PrintOpen函数返回的打印作业号,datawindow是要打印的数据窗口控件的名称。除了能够和Printopen()、PrintClose()函数共同使用外,其他函数都不能和PrintDatawindow共同使用。下面是一个完整地使用函数PrintDatawindow()进行数据窗口打印的例子,该例子中同时打印三个数据窗口:
Long ll_job
Ll_job = PrintOpen("数据窗口打印")
PrintDatawindow(ll_job,dw_1)
PrintDatawindow(ll_job,dw_2)
PrintDatawindow(ll_job,dw_3)
PrintClose(ll_job) //关闭打印作业
Print():
该函数是一个通用的函数,可以用来打印PowerBuilder中许多可视对象。下面介绍打印数据窗口时的语法,格式如下:
datawindowname.Print ( { canceldialog } )
datawindowname为要打印的数据窗口控件名称,canceldialog是一个boolean型变量,指示在打印时是否显示一个无模式的可以随时取消打印的窗口,该变量缺省为True。该函数正确执行则返回1,执行过程中发生错误则返回-1。
*虽然该函数和PrintDatawindow一样都可以打印数据窗口,但是它们之间是有区别的。Print函数使用设置在数据窗口对象的打印规范来打印数据窗口,而PrintDatawindow函数使用打印机当前的设置来打印数据窗口。
〓获取数据窗口信息
※函数Describe
使用函数Describe可以获取数据窗口对象中的信息。该函数语法是:
dwcontrol.Describe(propertylist)
其中,dwcontrol是数据窗口控件名称,propertylist是以空格分隔的特性或运算表达式列表,它用来报告列与图形对象的属性值。表达式可以用特定行与列的值进行运算。Describe函数返回的是一个字符串,该字符串是对指定属性的描述,不同的属性占用不同的行(不同属性用~n分隔)。如果有无效属性则返回该属性之前的属性取值和一个惊叹号(!)。如果某个属性没有值,则返回一个问号(?)。
如:
dw_1.describe("datawindow.bands datawindow.objects")
header~tdetail~tsummary~tfooter~nemp_id~temp_id
dw_1.describe("datawindow.band datawindow.objects")
!
dw_1.describe("datawindow.bands datawindow.object")
header~tdetail~tsummary~tfooter!
如果特性值容易引起混淆,例如,带有感叹号、问号、Tab键或换行符,这些符号在返回字符串中将用引号括起来。为了测试这种情况,先给数据窗口中的标签name_t中输入内容为name?,然后使用下面的语句:
dw_1.describe("name_t.text")
上面的语句显示"name?",这是因为如果值列表中的第一个值用引号引着,那么该特性列表中的剩余值也用引号引着。
*标签name_t和addr_t中分别输入内容为name?和zjhz
dw_1.describe("name_t.text addr_t.text")-------"name?" zjhz
dw_1.describe("addr_t.text name_t.text")-------zjhz "name?"
*最后不显示空格(~n)
※对列的引用
在属性描述时,经常要对列进行引用。引用列的方法有两种,或者使用列名,或者使用列号。应尽量避免使用列号,因为列号是和创建数据窗口时选择字段的顺序相对应的。在以后的修改中很有可能取消某些字段或者调整字段的选择顺序,或者改变数据源,这时就很容易出现错误,更糟糕的是这时很有可能没有错误信息,张冠李戴了。
下面是一个使用列号进行属性描述的语句:
dw_1.describe("#5.coltype")
这种语法可以和函数getcolumn搭配使用,用来检索当前列号。下面是一个显示数据窗口中所有字段类型的例程:
integer li_count,li_index
li_count = integer(dw_1.describe("datawindow.column.count"))
for li_index = 1 to li_count
messagebox(string(li_index),dw_1.describe("#" + string(li_index) + "coltype"))
next
※函数Evaluate
在使用Describe描述数据窗口对象中的相关信息时,有一个非常重要的函数不能不掌握,就是Evaluate。虽然函数Describe可以获取对象的信息,但是表达式的取值就不能正常读取了,而这又是经常遇到的。所以,函数Evaluate非常重要,它可以使函数Describe获取表达式的取值。该函数的语法是:
Evalute('expression',rowno)
其中,expression是属性表达式,rowno是要描述的行号。该函数放置在Describe的属性列表中。例如,判断第3行的salary工资是否大于1000,如果大于则返回1,否则返回0,
可以使用下面的语句:
dw_1.describe("evaluate('if(salary > 1000,1,0)',3)")
而使用下面的语法就是错误的:
dw_1.describe("if(salary > 1000,1,0)")
*单行(如第二行)
dw_1.describe("evaluate('if(isnull(emp_no) or emp_no = '',~~'*~~',emp_no)',2)")
*多行
long ll_i
string ls_emp
for ll_i = 1 to dw_1.rowcount()
ls_emp = dw_1.describe("evaluate('if(isnull(emp_no),~~'NULL~~',emp_no)'," + string(ll_i) + ")")
dw_1.setitem(ll_i,'emp_no',ls_emp)
next
※函数LookUpDisplay
字段使用了下拉列表框、下拉数据窗口和单选按钮等有代码表的编辑风格时,在数据窗口控件上显示的值和字段实际得到的值并不相同,使用函数GetItemX只能读取这样的字段的真实取值,而不是用户看到的值。如何才能读取用户看到的值?可以使用函数LookUpDisplay。
LookUpDisplay函数不能直接从PowerScript调用,可以在Describe和Evaluate函数配合使用。因为函数LookUpDisplay不能指定对哪行数据进行操作,它的参数只有一个字段名称,所以必须和Evaluate函数配合使用。该函数的语法是:
LookUpDisplay(columnname)
其中,参数columnname是字段的名称,而不是一个字符串。函数执行错误则返回空字符串。
下面是一个和函数GetItemString相比较的例子。假设在一个数据窗口中定义字段本人的编辑风格为DropDownListBox,定义该字段使用编码表,编码表的定义是显示值“Male”,“Female”分别对应“男”和“女”。然后,在某个按钮的clicked事件中编写如下脚本:
messagebox("getitemstring:"+dw_1.getitemstring(1,"本人"),"lookupdispaly:"+dw_1.describe("evaluate('lookupdisplay(本人)',1)"))
::getitemstring:男
::lookupdisplay:male
〓修改数据窗口信息
为了在运行时修改数据窗口对象特征,应该使用Modify函数,而不是直接访问语法。该函数的语法如下:
dwcontrol.Modify(modstring)
其中,dwcontrol是数据窗口控件名称,既可以是数据窗口也可以是子数据窗口,还可以是datastore对象。modstring是修改字符串,用来指示要修改哪些对象的哪些属性。如果修改成功函数则返回空字符串,如果修改的语法错误则返回对错误的描述,格式是:line n Column incorrect syntax,这里是第n列是从modstring开始计数的错误位置。
数据窗口对象可以在运行时使用合适的语法修改其外观、行为和数据库信息。通过提供完整的对象规范,甚至可以在数据窗口对象内部创建和删除对象。
使用modstring参数可以指定Create、Destroy和Attribute alteration三种类型的语句。
※创建对象
可以使用下面的语法来添加对象(如文本、计算域以及位图):
Create object(settings)
其中,settings为将要创建的对象定义的一组特性和值,定义对象时,用户必须提供足够的信息。
想要得到某个对象的正确语法的最好的方法就是导出一个包含对象的简单的数据窗口。然后就能把对象的语法剪切并粘贴到应用程序中。另一种办法是使用那些能成为数据窗口内特定对象显示语法的许多工具之一(它们正变得越来越商业化)。
下面的示例用来说明这种格式,假设用户刚刚从头开始动态地创建了一个完全新的数据窗口,现在需要在标题头放置一个公司标志,其语法是:
string ls_modify,ls_result
ls_modify = "Create bitmap(band = background filename = 'c:\logo.bmp' x = '60' y = '8' width = '1308' height = '513' border = '0' name = logo)"
ls_result = dw_1.modify(ls_modify)
if ls_result <> "" then
messagebox("提示",ls_result)
end if
这段代码为用户刚刚创建的报表数据窗口在恰当的位置创建标识。
※删除对象
除了可以在数据窗口内创建对象外,还可以使用下面语法删除对象:
Destroy [Column] object
这里的object是数据窗口对象内要删除对象的名字。若要把列和列的数据从缓冲区中删除,需要指定Column关键字。
例如,上一个示例中向动态创建的报表中添加了一个公司标志。如果用户把这一功能作为运行时的选项,比如说通过复选框,那么就不仅需要能够创建对象而且还需要删除该对象。下面是用于删除的代码:
string ls_result
ls_result = dw_1.modify("destroy logo")
if ls_result <> "" then
messagebox("错误",ls_result)
end if
下面的示例使用这种modify格式删除列及其相关的标签:
string ls_result
ls_result = dw_1.modify("destory column salary destroy salary_t")
if ls_result <> "" then
messagebox("错误",ls_result)
end if
※特性修改
Attribute alteration 类型的语句格式是modify三种格式中最常用的一种,这种语法的格式如下:
objectname.attribute = value
按照被影响的attribute的不同,value可以是下面类型中的任何一种:
a)常量:指简单的、不使用表达式的特性修改值。如:
columnname.band = footer
b)带引号的常量:也是指简单的特性修改值。如:
columname.height = '65'
c)表达式:由一个默认值及其后的表达式组成,它的返回值与特性的数据类型相同。如:
'167725~tif(emp_status=~'A~',255,16777215)'
请注意这种表达式的格式。整个表达式括在单引号中,表达式需要缺省值,而且该值通过Tab键(~t)与余下的表达式隔开。表达式返回0或者1,它们是特性的有效值。
在实际使用时,这种格式的语句经常简单写成属性访问格式。如:
dw_1.modify("oval_1.background.color = rgb(255,0,128)")
和以下直接属性访问方式是等价的:
dw_1.object.oval_1.background.color = rgb(255,0,128)
〓字段和计算域的属性-更多见帮助(DataWindow object properties)
*获取字段的类型(Coltype属性)
字段的ColType属性是一个非常有用的属性,使用该属性可以在程序运行时获取字段的类型。但是不能在运行时修改该属性。下面是它的语法:
直接引用:dw_1.object.object.objectname.coltype
在Describe函数中:"objectname.coltype"
不管使用哪种方式,对同一个字段获得的类型都相同。字段类型有char(n),date,datetime,decimal(n),int,long,number,real,time,timestamp及ulong共11种,其中的n代表字符的长度或者小数后的精度。
如:
ls_coltype = dw_1.objcet.emp_id.coltype
ls_coltype = dw_1.describe("emp_id.coltype")
在实际编程中,获取字段的类型后,紧接着使用choose case语句针对不同的类型进行相关的处理。
*背景属性(background.property)
在运行时修改字段的背景,这是标识特殊数据行的一种手段。使用该属性可以在程序运行时获取字段的背景,也可以修改字段的背景。它的语法如下:
直接引用:dw_1.object.objectname.background.property
在Describe和Modify函数中:"objectname.background.property{ ='value'}"
其中,property可以是color或者mode。当为color时取值应该是长格式表示的颜色,或者使用RGB函数中红、绿、蓝表示的颜色;当为mode时,0表示将背景设置为不透明的(即可以显示背景颜色),1表示背景为透明的。
实际上,字段的背景属性也可以在数据窗口画板中进行设定。下面是修改和读取字段背景属性的实例:
//修改字段的背景颜色
dw_1.object.oval_1.background.color = rgb(255,0,128)
dw_1.modify("emp_name.background.color = '11665407'") //这里好象不能用rgb()
//读取字段的背景颜色
ls_data = dw_1.describe("oval_1.background.color")
//读取字段的背景模式
ls_data = dw_1.describe("emp_name.background.mode")
//设置字段的背景模式
dw_1.modify("emp_name.background.mode = '1'")
dw_1.modify("mdrect_1.background.mode = '0'")
*指定检索规则(Criteria.property属性)
在脚本运行时,可以控制是否显示检索规则窗口或者读取数据窗口这方面的信息。语法如下:
直接引用:dw_1.object.columnname.criteria.property
在describe和modify函数中:"columnname.criteria.property{ = value}"
其中,dw_1是数据窗口控件名称,columnname是要获取或者设置检索规则的字段名称,value为yes或者no,property是以下属性:
a)Dialog:是否显示检索规则窗口。取值为yes则显示,取值为no则不显示。如,在一个数据窗口中放置了字段name,可以编写如下脚本:
dw_1.modify("name.criteria.dialog = yes 本人.criteria.override_edit = yes")
dw_1.retrieve()
脚本运行,显示检索规则输入窗口
b)override_edit:是否用户必须在检索规则窗口中输入数据。取值为yes则用户必须输入数据,取值为no时用户可以不输入数据。
c)required:是否用户只能使用等号进行查询。如果取值为yes则用户的输入只能是等号,如果取值为no则用户可以使用各种符号,包括=、<>、>、>=、<=、<等。
*Edit风格的字段属性(Edit.property属性)
编辑风格为Edit类型的字段,可以通过edit.property来获取其相关信息或者设置其外观及动作。下面是它的语法:
直接引用:dw_1.object.columnname.edit.property
在describe和modify函数中:"columnname.edit.property{ =value}"
其中,columnname是哟啊读取或者设置属性的字段名称,value根据property不同而可以使用不同类型的值。property可以有17个取值,其中:
a)和滚动控制有关的有AutoHScroll,AutoVScroll,HscrollBar和VscrollBar,它们的取值都是yes或者no,表示是否显示该滚动条。
b)和显示的内容有关的属性有Case,CodeTable,Format,NillsNull和Password,这些属性用来控制字段中的内容如何显示。Case的取值为Any,Upper,Lower与Painter,表示不管用户在该字段上输入的大小写,都按照该属性自动进行转换。CodeTable的取值为yes或者no,表示该字段是否有代码表。Format规定对用户输入的内容进行格式化时应该采用的格式。NillsNull的取值为yes或者no,表示当用户在字段中不输入内容而离开该字段时,是否将该字段中的内容自动置为NULL。Password属性的取值也是yes或者no,表示是否将用户的输入作为密码样式显示,如果作为密码则用户的输入内容作为*号显示,显示的个数和用户输入字符个数相等。
c)和编辑控制有关的属性有AutoSelect,DisplayOn1y,FocusRectangle,Limit,Required,Style和ValidateCode,除了Limit取值为正整数、Stylee取值为String类型外,其他属性的取值都是yes或者no。AutoSelect属性表示当字段获得焦点时是否自动选中该单元中的内容。Display0nly表示是否允许用户修改该字段中的内容,如果取值为yes,则用户虽然可以选中该字段中的内容但是不能修改。FocusRectangle表示当字段获得焦点时是否显示矩形的边框,以表示当前焦点的位置。Limit是一个相当重要的属性,用来**用户可以输入字符的长度。Required属性如果为yes,则在获得焦点后用户不输入内容就休想离开。虽然该属性可以很好地保证非空字段不为空,但该属性非常不友好,建议慎重使用。Style属性在程序运行时不能修改,只能读取其中的信息。该属性返回的是关于字段的编辑风格。ValidateCode属性表示是否使用代码表进行有效性校验。该属性当CodeTable属性为yes时才有效。
下面是关于该属性的一些实例:
ls_setting = dw_1.objcet.emp_name.edit.autohscroll //是否允许自动横向滚动
ls_setting = dw_1.describe("emp_name.edit.Autohscroll") //同上
dw_1.object.emp_name.edit.required = "no" //将字段设置成必须输入的字段
dw_1.modify("emp_name.edit.required = no") //同上
*字段的显示格式(Format属性)
可以使用Format属性来指定字段的显示格式。但是,在实际编程中使用更多的是函数GetFormat或者SetFormat,以取代Modify或者Descrie来设置字段的显示格式。
该语法使用时的重点在于格式串的使用。下面是相关的语法:
直接引用:dw_1.object.objectname.format
在函数describe和modify中:"objectname.format{='value'}"
其中,objectname是字段或者计算字段或者计算域的名称value是字符型的表达式,取值是一种格式串。下面是一些使用实例:
ls_setting = dw_1.object.phone.format //读取字段的电话显示格式
ls_setting = dw_1.describe("phone.format")
dw_1.object.shipdate.format = "yyyy-mm-dd" //设置日期格式
dw_1.modify("shipdate.format = 'yyyy-mm-dd'")
*设置数据窗口修改时的主键(key属性)
该属性在一个数据窗口修改多个表时非常有用,因为这时必须根据要修改的表动态修改主键,属性key就可以实现该功能。该属性使用时的语法如下:
直接引用:dw_1.object.columnname.key
在函数modify或者describe中:"columnname.key{=value}"
其中,columnname是要作为主键的字段名,或者是要判断是否为主键的字段的名称;value取值为yes或者no。如:
ls_setting = dw_1.object.empid.key //判断字段empid是否为主键
ls_setting = dw_1.describe("empid.key")
dw_1.object.empid.key = "yes" //将字段empid作为主键
dw_1.modify("empid.key = yes")
*字段名称(name属性)
使用name属性可以获取字段的名称。可以使用字段号或者字段名称来标识一个字段,但使用字段号不太安全,所以用获取字段名比较好一些。语法如下:
直接引用:dw_1.object.objectname.name
在函数describe中:"objectname.name"
其中,objectname是要获取名称的控件标识,因为在数据窗口对象中有很多控件有多种标识方法。如,下面可以获取字段号为1的字段的名称:
dw_1.describe("#1.name")
*字段中的数据保护(protect属性)
该属性表示是否对字段中的数据进行保护,取值为0或者1。1表示实行保护,0表示不保护。当进行数据保护时,即使字段的TabOrder值大于0用户也不能对字段进行编辑,并且该字段都不能获得焦点(和TabOrder取值为0时的表现完全相同)。下面是该属性使用时的语法:
直接引用:dw_1.object.columnname.protect
在函数describe和modify中:"columnname.protect{='integer'}"
其中,columnname是要获取或者设置protect属性的字段的标识,integer取值为0或者1。
下面是使用实例:
ls_setting = dw_1.object.emp_start.protect //获取字段emp_start的protect属性取值
ls_setting = dw_1.describe("emp_start.protect")
dw_1.object.emp_start.protect = 1 //设置字段emp_start的protect属性
dw_1.modify("emp_start.protect = 1")
dw_1.modify("emp_start.protect = '1~tif(isrownew(),0,1)'")
//设置protect属性为表达式,含义是:如果是新数据行则将protect设置为0,否则设置为1//,缺省为1。
*字段的滑动属性(slideleft和slideup)
使用字段的滑动属性可以更好地根据运动时的情况安排数据的布局。有两个和滑动有关的属性,SlideLeft表示当左面空白时是否向左滑动,SlideUp表示当上面出现空白时是否向上滑动。使用该属性的语法是:
直接引用:
dw_1.object.objectname.slideleft
dw_1.object.objectname.slideup
在函数describe和modify中:
"objectname.slideleft{='value'}"
"objectname.slideup{='value'}"
其中,slideleft中的value取值为yes或者no。slideup中的value取值为:
a)AllAbove:当上面数据行中的所有 对象都为空时向上滑动
b)DirectlyAbove:当上面和本对象对应位置的对象为空时向上滑动
c)No:不进行滑动
下面是应用的实例:
dw_1.object.emp_lname.slideup = 'no'
ls_setting = dw_1.describe("graph_1.slideup")
dw_1.modify("emp_lname.slideup = no")
*字段的TabOrder值(TabSequence属性)
字段的TabOrder值是一个比较重要的属性,取值大于0时用户可以编辑该字段,等于0时无法编辑该字段。在运行时,根据程序的运行情况有可能动态修改字段的TabOrder值,这时可以使用TabSequence属性。该属性应用时的语法如下:
直接引用:dw_1.object.columnname.TabSequence
在函数modify或Describe中:"columnname.TabSequence{=number}"
其中,number为从0到32000的正整数,当为0时表示字段不允许编辑。下面是使用实例:
ls_setting = dw_1.object.emp_name.tabsequence //获取字段的TabOrder值
ls_setting = dw_1.Describe("emp_name.tabsequence")
dw_1.object.emp_name.tabsequence = 10 //设置字段的taborder值
dw_1.modify("emp_name.tabsequence = 10")
实际上,在编程时经常使用函数SetTabOrder来设置或者获取字段的TabOrder值,因为该函数正确执行后,字段被设置成指定的TabOrder值,并且返回设置之前的TabOrder值。
*用户是否可以保存字段内容(update属性)
当数据窗口中的数据提交时,可以修改的字段及其对应的数据用来产生update SQL语句,使用该SQL语句进行数据的保护。所以,在程序运行时,如果不希望用户保存某字段中的数据,可以修改字段的update属性。下面是该属性的语法:
直接引用:dw_1.object.columnname.update
在函数modify或者describe中:"columnname.update{=value}"
其中,value的取值为yes或者no。下面是使用实例:
ls_setting = dw_1.object.emp_name.update //获取字段是否可以修改
ls_setting = dw_1.describe("emp_name.update")
dw_1.object.emp_name.update = "no" //使字段emp_name不能修改
dw_1.modify("emp_name.update = no")
在应用时,可以根据用户的权限,或者根据用户的录入数据是否齐全(通常需要保证数据一致性)来动态修改某些字段的update属性。另外,在一个数据窗口修改多个数据表时也经常使用该属性。
*字段校验(Validation和ValidationMsg属性)
字段的校验规则在数据窗口画板中可以指定,但有时需要在程序运行时动态地修改,可以使用Validation和ValidationMsg属性来指定。属性Validation使用时的语法如下:
直接引用:dw_1.object.columnname.validation
在函数describe和modify中:"columnname.validation{='validationstring'}"
其中,validaionstring是一个包含校验规则的字符串,该字符串的结果或者是True或者是False。下面是使用实例:
ls_setting = dw_1.object.emp_status.validation //获取字段的校验规则
ls_setting = dw_1.describe("emp_status.validation")
dw_1.modify("本人.validation = '本人 = ~~~'f~~~' or 本人 = ~~~'m~~~''") //设置规则
dw_1.object.本人.validation="本人='f' or 本人='m'"
字段的校验规则设置好后,用户在该字段上输入数据并要离开时,如果数据不能通过校验则显示错误信息,采用系统缺省的错误信息不太友好。这时,可以通过设置validationgMsg属性来指定错误信息。该属性使用时的语法如下:
直接引用:dw_1.object.columnname.validationMsg
在函数describe和Modify中:"columname.validationMsg{='string'}"
其中,string为数据不能通过校验规则时要提示的信息。如:
dw_1.object.本人.validationgmsg = "性别必须为f或者m!"
实际上,当用户输入的数据不能通过校验规则时将触发数据窗口控件的itemerror事件,该事件的返回值可以决定是否显示错误信息提示窗口。如果在itemerror事件中也编写了错误信息提示脚本,该脚本能够正常执行并且用validationgmsg属性定义的错误信息也会显示。
*计算域的属性
计算域除了具有上面介绍的属性外,还有一个重要属性Expression。使用这个属性可以根据用户的执行情况来更好地调整程序的动作,下面是其使用时的语法:
直接引用:dw_1.object.computename.expression
在函数modify和describe中:"computename,expression{='string'}"
其中,computename是计算域的名称,string是字符串,它应该包含合法的表达式。如:
ls_setting = dw_1.object.comp_1.expression //获取表达式
ls_setting = dw_1.describe("comp_1.expression")
dw_1.object.comp_1.expression = "avg(salart for all)" //设置表达式
dw_1.modify("comp_1.expression = 'avg(salary for all)'")
〓Button重要属性
*Action属性
该属性是Button控件最重要的一个属性。在数据窗口画板中,可以选择一个按钮有哪个动作。可选的动作都是事先定义好的,开发人员没有机会精确定义某个动作的执行,只能在运行时动态改变按钮的动作。
可以在设计时指定按钮的动作。在按钮属性窗口的General属性页,下拉列表框Action
中可以选择可用的动作。
在程序运行时可以使用Action属性来获取或者修改按钮的动作。该属性使用时的语法如
下:
直接引用:dw_1.object.buttonname.action
在函数Describe和Modify中:"buttonname.action{='value'}"
其中,buttonname是要获取或者设置动作的按钮的名称;value是动作代码,可以是下拉列表框Action中的值。
代码 动作 解释 返回值
11 AppendRow 在最后增加一空白行 新增加行的行号
3 Cancel 取消使用了yield函数的检索过程 0
10 DeleteRow 如果按钮在detail带中则删除按钮 成功返回1,否则-1
,否则删除当前数据行。
9 Filter 显示Filter对话框, 过滤掉的数据行数。
并在指定条件后进行检索 如果发生错误则返回小于0的数
12 InsertRow 如果按钮在detail带中,则以按钮 新插入行的行号
所在行为参数插入数据,否则在当
前行插入一空白行
6 PageFirst 翻到第一页 成功返回1,否则返回-1
7 PageLast 翻到最后一页 最后一页中第一行的行号。
如果失败则返回-1
4 PageNext 翻到下一页 同上
5 PagePrior 翻到前一页 同上
16 Preview 进入、退出预览状态 0
17 PreviewWithRulers 打开或者关闭标尺 0
15 Print 打印一份数据窗口 0
20 QueryClear 删除where子句 0
18 QueryMode 进入、退出查询模式 0
19 QuerySort 指定查询时的排序规则 0
2 Retrieve 从数据库中检索数据 检索到的记录数
1 Retrieve(Yield) 从数据库中检索数据,并随时允许 检索到的记录数
用户终止
14 SaveRowsAs 以用户指定的格式保存数据 记录数
8 Sort 显示排序窗口并按指定规则排序 成功则返回1,否则-1
13 Update 将修改了的数据保存到数据库。修 成功则返回1,否则-1
改成功则自动执行commit,否则执
行rollback
0 UserDefined 允许为按钮的ButtonClicked和 用户脚本中定义的返回值
ButtonClicking事件编写脚本
*SuppressEventProcessing属性
SuppressEventProcessing属性用于是否触发ButtonClicked事件或者ButtonClicking事件。
语法格式是:
直接引用:dw_1.object.buttonname.suppresseventprocessing
在函数describe和modify中:"buttonname.suppresseventprocessing{='value'}"
其中,value的取值为yes或者no,表示是否触发事件。如:
dw_1.object.b_name.suppresseventprocessing = 'yes'
dw_1.modify("b_name.suppresseventprocessing = 'no'")
ls_setting = dw_1.describe("b_name.suppresseventprocessing")
*Text属性
通过Text属性可以获取或者设置按钮上的文字。当运行时,如果要动态修改按狃的Action属性,就应该利用Text属性修改。该属性使用时的语法如下:
直接引用:dw_1.object.textname.text
在函数modify和describe中:"textname.text{='string'}"
其中,string是一个字符串或者表达式,如果要给按钮设置快捷键,可以在字符串中使用&符号。如:
ls_setting = dw_1.object.text_1.text //获取按钮上的文字
ls_setting = dw_1.describe("text_1.text")
dw_1.object.text_1.text = "employee &Name" //给按钮设置文字,并有快捷键
dw_1.modify("text_1.text = 'employee &Name'")
数据窗口对象的数据源
----------
PB提供5种数据源:Quick Select(快速选择类型)、SQL Select(SQL选择类型)、Query(查询类型)、External(外部类型)和Stored Procedure(存储过程类型)
----------
Quick Select
只能从一个数据表或者视图中选取数据(无关联的表或者视图)??
----------
SQL Select
1、选择表
可以一次选择多个表
2、选择字段
Select All //选择所有字段
Select Tables //重新选择表
Convert to Syntax //进入SQL语法状态
Compute //计算字段,右键->Columns //选择字段
右键->Functions //选择函数
3、指定检索条件
Retrieval Arguments //定义检索参数变量的类型和名称
where //检索条件,右键->Columns //选择字段
右键->Functions //选择函数
右键->Arguments //选择参数
右键->Value //选择值
右键->Select //从其他表中选择
----------
Query
PB可以将特定的SQL语句保存为Query对象,不同的Query数据源的数据窗口都可以使用这些已经保存好的SQL语句来提取数据
----------
External
当和不存在于数据库中的数据打交道或者要利用数据窗口的某些特性但不进行数据处理时,使用此数据源。无SQL语句。
----------
Stored Procedure
使用已经定义好的存储过程来做数据源
----------
数据窗口对象的显示样式
----------
数据窗口对象显示样式有11种:Grid、Tabular、Group、Freefrom、Label、N-Up、Crosstab、Graph、Composite、RichText、OLE2.0
----------
Grid:
字段横向排列在detail band中,标签横向排列在header band中,和字段相对应,字段和字段之间有网格线分隔,类似于电子表格。在数据窗口的预览状态下可以调整字段的顺序,并且自动反馈到数据窗口的设计状态中,调整字段顺序时,对应的标签顺序也相应地自动调整。缺省情况下,字段不能随意移动,只能在detail band中做上下移动。这种显示样式的数据窗口布局整齐,但不能灵活地安排字段、标签、表头的布局,所以常用来显示数据或录入数据,而很少用来做报表。Grid显示样式的数据窗口中,表头只能和标签放置在同一个header band中,在放置表头处仍然有网格线。
----------
Tabular:
当刚刚创建这种样式的数据窗口时,字段、标签的布局和 Grid显示样式的数据窗口相同,都是横向排列的,但是字段之间没有网格线分隔。字段和标签的布局可以随意调整,在header band中的标签可以随意拖放到detail band中,detail band中的字段也可以拖动到header band中。这种显示格式的数据窗口布局安排非常灵活,开发人员可以根据需要设计字段和标签的布局,然后手工画线制作表格,在制作中国式
报表时经常使用,虽然比较烦琐,但是表格比较美观,比较适合中国式报表的要求,另外,这种格式的数据窗口在数据录入、查询时也经常使用。
----------
Group:
Group分组显示样式的数据窗口可以指定按哪个(或哪些)字段进行分组,可以用指定的分组条件将数据分组显示,并且允许为每组指定一些计算。例如,要显示某公司在各地区的销售数据,可以按地区分组,为每个分组指定统计计算,在地区改变时显示地区的销售总金额。
当选择多个字段时,这几个字段共同作为分组的条件,而不是以每个字段都创建一个分组。使用Group类型只能创建一个分组,要创建多个分组必须在DataWindow画板中完成。
----------
Freefrom:
前面讨论的三种显示样式都是一次可以显示多行数据的。对于比较重要的数据,用户可能需要一次只编辑一行这时可以使用Freefrom显示样式的数据窗口。该类型的数据窗口将标签放置在字段的左例,字段和标签放置在同一个detail band中,先从上到下再从左到右依次排列。实际上,这种显示样式的数据窗口布局也很灵活,可以随意安排字段和标签的位置。这种显示样式的数据窗口在卡片式数据的录入和显示方面也经常使用。
----------
Label:
如果用户想要生成邮件标签,可以使用Label显示样式的数据窗口来实现。
----------
N-Up:
这是可以在同一页上显示多列相同字段的一种特殊的显示样式。当要显示的字段比较少或者不同行之间的数据需要做比较时,经常使用这种显示样式。使用向导可以创建N-up显示样式的数据窗口,需要指定的一个重要参数是每行重复显示的字段的次数,也就是Number of rows per detail band,缺省为2。该参数的大小视需要显示的字段总长度和报表使用的打印纸宽度而定。N-up显示样式的数据从左到右显示。另外,当选中行数据时,并不能选中实际上看到的一整行,而是逻辑上的一行。
----------
CrossTab:
当需要做数据统计和分析时,最好使用CrossTab显示样式的数据窗口,虽然报表在显示格式方面不适合中国人的口味,但还没有哪个C/S数据库开发软件将数据统计分析做得如此之好。使用CrossTab显示样式可以创建复杂的分类统计表,不管是表头分类还是行分类。
创建CrossTab显示样式的数据窗口时,有几个重要参数需要指定。这些重要参数是行、列和统计值。每个参数可以指定多个字段,也可以使用表达式。当指定多个字段(或表达式)时,字段的顺序决定在表中的分组顺序。比如,统计某销售公司某年各个月份各种产品、不同花色在各个地区的销售情况,可以用月份和地区作为列,用产品名称和花色作为行。在Columns列表框中按Month、Region的顺序加入字段,没有Month可以使用表达式Month(sales_date)来获取销售时的月份。Rows列表框中的字段对应数据窗口中左侧的表头,Columns列表框中的字段对应数据窗口中上面 表头,Values是出现在数据窗口表格单元中的统计值;Source Data列表框中是可以使用的字段,使用鼠标选中并拖动到相应的列表框即可。在Rows、Columns、Values三个列表框中都可以用鼠标双击已有字段,可以在接下来的对话框中输入组合表达式。比如,使用year作为Columns是可以的,也可以双击然后在上面的窗口中输入下面的表达式:year+"年"
----------
Graph:
Graph显示样式的数据窗口可以以多种图形样式将数据显示出来,例如饼图、柱状图、折线图等。Graph显示样式的数据窗口给用户的感觉是使用方便、表达直观。从开发者的角度来讲,创建Graph显示样式的数据窗口也是很简单的事情,所以在开发应用程序时不要忘记这费力不多却很受用户欢迎的显示样式。
创建Graph显示样式的数据窗口时,最重要的参数是Category、Values及Series。在创建向导中可以指定这几个参数。指明这三个参数的操作很简单,在下拉列表框中选择合适的字段即可。Category可以理解成显示在横向坐标铀上的字段,Values可以理解成显示在纵向坐标轴上的字段,而Series是横向坐标轴上同组比较时的分组标准。
----------
Composite:
这种显示样式的数据窗口可以将多种类型的、多个逻辑上毫不相关的数据窗口放置到一起,是一种灵活的数据表现形式。因为Composite显示样式的数据窗口不允许修改其中的数据,所以不能用于数据录入和数据修改,只能在报表时使用这种显示祥式的数据窗口。使用这种显示样式的数据窗口创建报表,经常将对同一问题不同表现形式的数据窗口或者是关系紧密的数据放到一起。例如,将几个关键数据的统计结果以Graph显示样式显示在最上面,用CrossTab类型的数据窗口将比较详细的数据统计结果显示在中间,然后是Grid类型的详细数据,这样的报表数据表现能力要比任何单一的一种数据窗口要强得多。
----------
RichText:
RichText祥式的数据窗口使数据库中的数据和文字可以在一起排版,可以方便地特数据库中的数据和文字内容一起形成文档、报告等;提供了很强的文字编辑处理能力,可以很方便地处理文字的多种格式:可以开发更有表现力的应用系统,自动生成报告、文档资料,省去了使用PowerBuilder的应用程序却需要切换到其他文字处理软件中的麻烦。
----------
OLE 2.0:
OLE是Object Link and Embedding的字头缩写,表示对象链接和嵌入。使用这种技术,可以将其他软件的功能引入到PowerBuilder开发的应用程序中。PowerBuilder中不仅提供了OLE 2.0显示样式的数据窗口,而且在窗口中提供了OLE 2.0控件。例如,在数据库中保存的图像在OLE 2.0显示样式的数据窗口中,可以借助一些专门的图像处理软件来处理,并可以把处理结果返回保存到数据库中。
只有当数据库的表中包含blob类型的字段时,才有必要使用OLE 2.0显示样式的数据窗口。将blob类型的字段作为OLE 2.0列,在处理其中的数据时,可以直接触发调用相关的软件进行处理,并能够将处理结果返回保存到数据库中。例如,某字段中保存的是Excel文档,可以创建OLE 2.0显示样式的数据窗口,当双击该字段时可以调用Excel,然后在Excel中编辑处理数据,保存编辑结果返回到数据窗口时,可以将结果反映到数据窗口中。
创建OLE 2.0显示样式的数据窗口,需要指定三类参数。Source Data框中显示的是所有可用字段,可以使用鼠标选中并拖动到其他两个列表框中;Group by列表框中显示的是用来分组的字段,由于OLE 2.0数据窗口的特殊性,它的分组不在设计时创建,只能在向导中创建;Target Data框中显示的是在数据窗口中要显示的字段,使用了分组,则对该框中的字段做统计(字符串型的列将统计记录数,数值型的列将统计累加和),没有使用分组,则直接显示它们的值。接下来要设置的是和OLE对象关系紧密的内容
----------
数据窗口对象的画板、band和层次
----------
数据窗口画板
整个数据窗口画板由6个视窗构成,分别是:
Design:设计数据窗口对象视窗,可以使用菜单Design-Options来改变Design窗口的外观
Preview:预览数据窗口的外观,显示相应表中的对应的数据,及对数据的各种操作
Control List:数据窗口中所有的部件构成的一个列表
Data:显示此数据窗口对象所对应的表中的各个字段的值
Properties:属性
Column Specification:该视窗是个比较重要的视窗,可以增加、删除、修改列的初始值、检验表达式或者校验信息
----------
数据窗口对象的band
数据窗口用带-band将其分隔成四部分:
Header:出现在每页的顶端,用于显示标题和列的题头
Detail:包含了数据窗口对象的主体,显示了各行的数据和相关的标签。在DataWindow对象高度的范围内,细节条能够按照需要自动扩大任意倍
Footer:出现在每页的底端,用来显示文本和页号
Summary:出现在DataWindow对象的最后一页,用来为整个数据窗口对象显示总计和总和
----------
数据窗口对象的层次
数据窗口分为三个层次,即背景层(background)、带层(band)和前景层(foreground)。在数据窗口上放置的部件可以属于任意一个层次,但如果设计不当,数据显示会凌乱不堪。通常情况下,背景层放置绘图对象以设置漂亮的背景;带层放置字段、计算域、标签等和报表内容紧密相关的内容,在运行状态下,PowerBuilder会自动格式化带层;前景层放置一些无需打印的内容,最典型的是Graph部件。
设置部件属于哪个层的方法是首先选中部件,然后在属性视窗中进入到Positon属性页,修改该部件的Layer属性,在Layer下拉列表框中选择适当的层即可。
不管哪个层上的对象,鼠标右键弹出菜单中都有Send to Back和Bring to Font两个选项。这两个功能和层之间有什么关系呢?没有任何关系!不管部件属于哪个层,都可以使用这两个菜单项,使用完后部件也不会属于其他的层,只是重叠部件的前后关系发生了变化。所以当部件没有重叠时,使用这两个菜单选项没有什么意义,虽然这两个菜单选项也可以使用。
选中数据窗口上的部件不区分层。也就是说,选中操作不受层的影响,可以同时选中不同层上的部件。当设置了较大的背景图片时,可能不能使用拖动鼠标来直接选中多个对象,因为拖动时,鼠标的起点可能就在背景图片上。解决方法是在所有操作都完成后再放置背景图片,也可首先将背景图片剪切掉,进行其他操作后再粘贴图片,或者先将背景图片拖到没有其他对象的位置上,操作完成后再将图片背景拖放到原来位置
----------
数据窗口对象及字段的修改属性
数据窗口只能修改一个数据表。当数据窗口的数据来源于不止一个数据表时,可以用脚本控制数据窗口的修改属性来对数据表逐个进行修改。
当数据窗口是用来接受用户的手工录入数据时,应该设置两方面的属性才能确保数据窗口能够用来修改数据表。一个是修改数据窗口的修改属性,另一个是用户可以修改的字段的相关属性值
----------
数据窗口对象的修改属性
Rows->Update Properties
如果数据窗口对应的数据表中定义了主键或者唯一性索引,则数据窗口创建时默认的就是允许修改,并且正确设置了所有的修改属性。否则就需要手工进行设置。当增加、删除、或者重新选择了字段时,PB将数据窗口的的修改属性为不允许,这时也应该进行手工设置。
Allow Updates:允许更新。
Table to Update:指定要被更新的表。
Where Clause for Update/Delete:配置如何在Update和Delete SQL语句中构造where子句
1、Key Columns 当开发单用户应用程序或者用户都以加锁方式访问数据库时可以选中该选项。该选项表示数据窗口只使用在“Unique Key Column”列表框中指定的唯一列进行数据更新。使用这种方式来修改数据库,并发性很高,不同的用户都可以并发地访问数据库,但是数据的完整性却非常差。因此要保护数据完整性,只有在单用户程序或者加锁访问方式下才使用这种修改方式。如:在add_book(通讯录)数据表中定义了4个字段,id为主键,name,address,telephone三个字段为可修改字段,有如下一条数据(001,陈,杭州,1395813)。若想把name改为“万”,数据窗口产生如下的update语句:update add_book set name = '万' where id = '001'
2、Key and Updateable Columns 这种修改方式是默认的修改方式,它用主键列和可以修改的列来创建where子句,具有很高的数据完整性,但是并发性不是太好。推荐使用这种修改方式。保存数据时将产生如下的SQL语句:update add_book set name = '万' where id = '001' and name = '陈' and address = '杭州' and telephone = '1395813'
3、Key and Modified Columns 该方法是上面两种方法的折中,当不同的用户并发修改同一行数据的不同字段时,都能成功修改,所以它的并发性有了一定的**,数据的完整性比第一种修改方式有所提高。这种修改方式使用主键和数据发生了变化的列来产生where子句。保存数据时产生如下的SQL语句:update add_book set name = '万' where id = '001' and name = '陈'
Key Modification:该组框用来指定当用户修改了主键时,数据窗口如何来更新数据表中的主键字段。有两种选择Use Delete then Insert和Use Update。第一个选项是先删除原有的主键值,然后再使用新的主键值插入一个完整的行。使用这种更新主键的方式可以减少组织数据的工作量,但在数据库中各个数据表之间存在父子制约关系,并且依赖该主键的外部键被指定为级联删除时,操作就不会成功的。因为级联删除方式要求当依赖主键的外部键有数据时就不能删除主键。当DBMS允许更新主键列时,可以使用第二个选项,该选项直接修改主键值,所以防止了级联删除带来的操作不成功的问题。
Updateable Columns:指定被更新的字段。当数据窗口中的字段来自不止一个数据表时,这时一定要选择同一个表中的字段,因为一个数据窗口一次只能更新一个数据表,当数据窗口中增添了字段时,新增添的字段往往是不允许修改的,一定要在该列表框中选择该字段。
Unique Key Column:选择唯一标识一行的列。如果在定义数据表时定义了主键,单击右面的“Primary Key”按钮可以在该列表框中选中主键。
Identity Column:该下拉列表框用于为下拉列表框中所指定的列(通常是主键列)生成序号,当且仅当DBMS支持序号生成时该作用才有效
----------
数据窗口对象字段的修改属性
**相关属性
数据窗口中字段的相关属性:
1、字段的Tab Order值
2、字段的Protect属性
3、字段的DisplayOnly属性
4、字段的Visible属性
上述属性前3个中任意一个都可以让用户无法修改字段中的数据:最后一个属性决定字段是否可见,不可见的字段不管其他属性如何设置.用户都无法修改字段中的数据。
当字段的Tab Order值为0时,肯定不能获得焦点,但是非0时也不一定能获得焦点,还得看字段的Protect属性是否设置为1;当字段的Tab Order值不为0,Protect属性不为1并且字段的Visible属性为True时,肯定可以获得焦点。DisplayOnly属性和焦点是否能够获得无关(即选中Displayonly时可以选中字段,可以复制,但不能更新)。
**数据保护
可以用以下三种方法将字段设置为用户不可修改的字段:
(1)在数据窗口设计时将这些字段的TabOrder值置为0,以使该字段不能获得焦点,用户无法选中和编辑该字段。
(2)将字段的DisplayOnly属性设置为True。该字段可以获得焦点,可以选中该字段,还可以拷贝复制该字段的内容,但不能编辑该字段中的内容。
(3)设置字段的Protect属性。字段的Protect属性如果设置为“1”,则该字段的TabOrder值即使不是0也不会得到焦点。使用该属性可以保护一些重要的数据。
----------
数据窗口对象的字段操作
----------
字段的编辑类型
PB提供了六种编辑类型:
1)Edit是字段的缺省编辑类型,可以用于所有类型的字段上。
2)CheckBox编辑类型在这里是一种状态选择,可以为其规定选中和非选中状态时的文字,当字段的输入内容非此即彼时,可以使用这种编辑类型。
3)DropDownDW是一种用来**用户输入数据的非常好的编辑方式,用户只能通过选择录入数据,并且选择的数据来自其他数据窗口的某字段,从而可以确保数据的一致性和正确性。当录入外部键时,经常使用这种编辑类型。使用这种方式可以增强程序的适应性和灵活性。
4)DropDownListBox在外观上和DropDownDW类型相同,但它的数据不会发生变化,是固定的,适合用来录入诸如学历、省份、月份等范围固定的数据项。
5)EditMask经常用来录入整型或日期型数据。它底优势在于可以给用户提供清晰的数据格式,对用户的操作有很强的提示性;还可以为该编辑类型设置Spin,以便用鼠标单击上下箭头来增大或减小数据。
6)Radio Buttons在录入取值为比较小范围内的数据经常使用,用户使用鼠标进行选择操作即可录入数据,操作比较方便。
----------
字段的编辑格式
1、Limit - **输入长度
可以规定在该字段中输入的信息长度,缺省是字段在数据表中定义的长度。如果在数据窗口创建以后又添加了字段,这时缺省长度是0,这时用户所能输入的长度取决于编辑框的长度(如果没有设置字段的AutoHorz Scroll属性或者设置了该属性并且Limit属性为0,则用户输入的最大长度取决于编辑框所能接受的最大长度),应该手工修改其**长度为字段在表中定义的长度。修改方法是,在字段属性窗口的Edit页Limited输入框中输入一个整数即可
2、Display Only - 不允许用户修改
选中字段对应属性窗口中的Display Only选项即可。在程序运行时,该字段中的内容可以显示,并且可以获得焦点,但是用户不能修改字段的内容,从而起到保护数据的作用。建议使用这种方式来保护字段中的数据,虽然不能编辑字段内容,但可以选中并复制,比设置字段的Tab Order值有更多的灵活性
3、Required - 必须输入
有些信息要求用户必须输入,这时可以选中字段的Required属性。不输入数据就无法离开该字段。
4、Password - 密码输入
选中字段属性窗口中Edit页上的Password属性即可,字段上数据显示为“*”号
5、Format - 格式
属性视图中Edit属性页中包含Format属性,并且还有一个专门的Format属性页。Edit属性页的Format属性可以设置字段编辑时的显示格式,Format属性页中的Format设置字段不被编辑时的显示格式。
Format的设置:
Numbers:可以使用“0”、“#”、“.”和一些算术符号来表示,使用保留字“[general]”或者“[Currency]”时,PB将使用操作系统的设置格式。关于操作系统的格式,Windows可以在控制面板的区域设置中修改。
[General] 5 -5 0.5
0 5 -5 1
0.00 5.00 -5.00 0.50
#,##0 5 -5 1
#,##0.00 5.00 -5.00 0.50
$#,##0;($#,##0) $5 ($5) $1
$#,##0;-$#,##0 $5 -$5 $1
$#,##0;[RED]($#,##0) $5 ($5) $1
$#,##0.00;($#,##0.00) $5.00 ($5.00) $0.50
$#,##0.00;[RED]($#,##0.00)$5.00 ($5.00) $0.50
0% 500% -500% 50%
0.00% 500.00% -500.00% 50.00%
0.00E+00 5.00E+00 -5.00E+00 5.00E-01
Strings:可以用两部分来表示该类型数据的显示,前面是必需部分,后面是NULL时表示。“@”代表一个字符。如:"[red](@@@)@@@-@@@@"
Dates:使用几个特定的字母代表特定的含义,它们的组合构成Data类型的格式。
d 表示天的数字,没有前缀0 9
dd 表示天的数字,有前缀0 09
ddd 星期几的英文缩写 Mon
dddd 星期几的英文全称 Monday
m 没有前缀0的月份 6
mm 有前缀0的月份 06
mmm 月份的英文缩写 Jun
mmmm 月份的英文全称 June
yy 两位数字表示的年份 97
yyyy 四位数字表示的年份 1997
两位的年份如果小于50,PB则认为是21世纪;大于50则认为是20世纪。比如,“85”表示的年份PB认为是“1985”年;“40”表示的年份PB认为是“2040”。
Times:使用几个特定的字母代表特定的含义,它们的组合构成Time类型的格式。
h 没有前缀0的表示小时的数字
hh 有前缀0的表示小时的数字
m 没有前缀0的表示分钟的数字,必须出现在h或者hh之后
mm 有前缀0的表示分钟的数字,必须出现在h或者hh之后
s 没有前缀0的表示秒的数字,必须出现在m或者mm之后
ss 有前缀0的表示秒的数字,必须出现在m或者mm之后
ffffff 没有0前缀的毫秒,必须出现在s或者ss之后
AM/PM 两个大写的缩写字母,代表上午和下午
am/pm 两个小写的缩写字母,代表上午和下午
A/P 一个大写的缩写字母,代表上午和下午
a/p 一个小写的缩写字母,代表上午和下午
6、Auto Selection - 自动选中
当字段获得焦点时,自动选中当前行字段中的内容,这在需要删除或者拷贝时用处比较大。选中字段对应属性窗口中Edit页上的auto selection即可。
7、设置滚动条
Auto Horz Scroll--自动横向滚动
Auto Vert Scroll--自动纵向滚动
Horz Scroll Bar --横向滚动条
Vert Scroll Bar --纵向滚动条
8、Use Code Table - 使用Code Table
使用Code Table可以自动转换用户的输入信息,也可以校验用户的输入信息是否正确。
a)选中字段的Use Code Table属性
b)在Code Table中定义代码表,该输入框中包括两列,Display Value用来进行显示,Data Value是和该显示值对应的实际值,是保存在数据库中的值。
c)选中Validate选项,从而可以确保用户的输入必须是代码表中定义了的,否则就出现报错信息。
9、Show Focus Rectangle - 显示焦点边框
焦点边框就是当字段获得焦点时,在字段编辑框的周围显示一个矩形边框,可以醒目地提醒用户当前的输入位置,这是一个比较好的界面,建议使用该属性。选中字段对应届性窗口Edit页中的Show Focus Rectangle即可。Tabular默认选中
10、Accelerator - 设置加速度
可以为字段设置加速键,以便很快捷地定位到特定的字段上。只要在字段对应属性窗口Edit页的Accelerator编辑框中输入字母或数字即可,只能输入一个字符。加速键由Alt和所输入的字母或数字构成。程序运行时,使用加速键可以将焦点马上转移到有该加速键的字段上。
11、Case - 选择大小写
可以给字符型字段指定大写、小写、还是原样显示输入内容。在字段对应的属性窗口Edit页中的Case下拉列表框中选择即可。Up代表始终大写,Any代表原样,Lower代表小写。
----------
增加和删除字段
进入数据窗口对象的SQL Select画板后可以对字段进行以下三种操作:
1、增加字段
2、删除字段
3、重选字段。取消某字段,再重新选中该字段。这看起来好像没有什么作用。实际上,这样做可以同步数据窗口对象和数据表的定义。当创建了数据窗口后又修改了该数据窗口对象对应数据表中某字段的定义,例如,增加了字段的长度,这是应该保证字段和数据窗口中的定义一致,使用上面的方法就可以做到数据的一致
*当添加字段时,PB不能正确设定新添加字段的默认属性,必须认真检查新添加的属性,最重要的属性是Limit的大小以及Show Focus Rectangle、Auto Selection和Auto Horz Scroll属性是否选中。如果数据窗口对应的数据表中既没有定义主键也没有定义唯一性索引,并且数据窗口还是用来进行数据录入的,这时不管是删除了数据窗口中的字段或添加了字段,还是重新选择了字段,都要仔细检查并重新设置数据窗口的Update属性了,如果数据表中定义了主键或者唯一性索引,就不用考虑这个问题了。
----------
字段的显示顺序
在大多数显示样式的数据窗口中都可以使用鼠标拖放直接改变字段的位置,惟独grid类型的数据窗口在Design窗口中不能。解决方法是,在预览窗口中拖动字段到适当的位置,Design窗口中的字段顺序就会自动做相应的调整。
可以用字段名或者字段号来标识一个字段。例如,产生数据窗口的SQL语句是:
select name,本人,address from addr_book;
在该数据窗口中,name和#1都是指同一个字段。显示位置的调整不会影响字段号,字段号和产生数据窗口的SQL语句中字段的顺序相对应,在SQL语句中,第一个字段对应的字段号为#1,依次增加一个。要调整字段号的顺序,可以进入到SQL select画板,取消所有字段,再按照正确的字段顺序重新选择字段;或者切换到语法状态,手工修改SQL语法中字段的顺序。经过这样的调整后,可能字段在数据窗口中显示的顺序没有变化,但是字段号却进行了重新分配。因为在窗口脚本中引用数据窗口的数据时,有可能用到字段号,在数据窗口的计算域中也有可能用到字段号,所以要保证字段号正确设定,尤其是习惯使用字段号引用数据时。
----------
计算域是指在数据窗口的设计状态下添加到数据窗口中的Computed Field部件,它是一个数据窗口部件,具有部件的属性特征。计算字段是指在数据窗口对应的SQL语句中添加的表达式,计算字段是一个字段,它具有字段的属性特征。它们的区别主要体现在脚本中。计算字段因为具有字段的特征,所以SetItem等对字段操作的函数可以用来操作计算字段而不能来操作计算域,当需要在程序中动态设置值时,就应该使用计算字段而不能使用计算域,典型情况是对计算出来的值进行误差校正。这两个对象都可以使用GetItem一类的函数来读取取值。
常用函数:
条件判断
If ( boolean, truevalue, falsevalue )
Case ( column WHEN value1 THEN result1 { WHEN value2 THEN result2 { ... } } { ELSE resultelse } )
累积,(表格最右面一列各行是某列对应行前面所有行的累加和)
CumulativeSum(column{for range})
其中,column是列名、列号,或者是由列名、列号、常量、运算符,甚至其他函数构成的表达式,但取值必须是数值型的。For range是进行累积的范围。大多数显示样式的数据窗口都可以使用如下内容。
All:缺省值,累积指定列的所有取值
Group n:在指定的分组内对指定字段进行累积运算。Group是保留字,n代表组号,如1。
Page:在页范围内进行累积运算。
百分比
Percent ( column { FOR range { DISTINCT { expres1 {, expres2 {, ... } } } } } )
Percent可以用来计算某字段在指定范围内当前行的取值占该范围内该字段累计和的比例。
其中,column以及For range和上面CumulativeSum函数中的完全相同。选项DISTINCT用来指定只统计不相等的字段,表达式expresX是用来区分行是否相同的标准。该函数和表达式column/sum(column for range)是等价的。
CumulativePercent(column{FOR range})
用来计算当前的累积和占总和的比例
其中的column和for range和上面的相同。该函数和下面的表达式是等价的:
CumulativeSum(column for range)/sum(column for range)
引用不同行的数据
在数据窗口的表达式中,可以直接使用列名数组引用不同行的字段值,下标是一个相对数,相对于当前行而言的。例如,假设在数据窗口中有一列名为product_id,在数据窗口表达式中,product_id和product_id[0]是指当前行的product_id值。product_id[-1]是指前面一行的product_id值,product_id[1]是指下一行的product_id值。
使用这种引用方法,可以很简洁地提供更友好的数据显示格式。例如,当product_id改变时,用另外一种颜色显示月份、销售量、库存量等,可以修改这些字段的颜色表达式(应该以product_id排序):
if(getrow()=1,rgb(255,0,0),if(product_id = product_id[-1],rgb(255,0,0),rgb(255,255,255)))
数据行的修改状态
isRowNew()
isRowModified()
if(isRowNew(),'新',if(isRowModified(),'改','旧'))
其他
date
isSelected
average
count
sum
排序、过滤和分组
----------
排序
Rows->Sort
*双击Columns列表框中的字段或表达式,进入Modify Expression窗口,可以进行表达式定义,表示要使用该表达式进行排序。
上面的方法定义的排序是在客户端执行的,要在服务器端进行数据排序,可以通过修改数据窗口对应的SQL来实现。
----------
过滤
Rows->Filter
在对话框中输入表达式,在定义表达式时,有些经常使用的运算符,如like、betweem、in、match等需要特别关注一下。*特别是match具体可以在程序中测试,具体见PB帮助-match。
上面的方法同排序是在客户端执行的,要在服务器端进行数据排序,可以通过SQL语句中使用where子句,然后用带参数的retrieve来过滤。
----------
分组
Rows->Create Group
*双击“Columns”列表框中的字段或表达式,进入Modify Expression窗口,进行表达式定义。创建分组后,数据窗口中又增加了两个带(band),Header group name用来先死组名,放置用来分组的表达式或者字段;Trailer group name放置分组的总结信息。
数据窗口创建后定义的分组和使用分组样式创建的数据窗口在显示效果上相同,区别在于前面一中方式是在数据完全从服务器端传送到客户端后进行的,后一种是直接在服务器按照分组取出数据的。
*最后介绍一种方法,同样可以达到Group的效果。比如,显示各个地区产品销售情况的数据,应该使用地区作为分组。在数据窗口画板中选择窗口菜单Rows->Sort,选择以字段“region”进行排序;然后再选择窗口菜单Rows->Supress Reapting values…,指定压缩字段“region”的重复值即可。
----------
其他
----------
数据窗口中的当前页和总共页
string ls_currentPageNo
string ls_totalPage
ls_currentPageNo = dw_1.Describe("evalue('page()',1)") // ?? 获取当前页号
ls_totalPage = dw_1.Describe("evalue('PageCount()',1)") //获取总共多少页
----------
数据窗口对象的中备份和恢复数据
备份:File->Save Rows As //或Preview窗口中右键->Save Rows As
恢复:Rows->Import
----------
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。