PB数据窗口其他.docx
- 文档编号:17600468
- 上传时间:2023-07-27
- 格式:DOCX
- 页数:19
- 大小:26.08KB
PB数据窗口其他.docx
《PB数据窗口其他.docx》由会员分享,可在线阅读,更多相关《PB数据窗口其他.docx(19页珍藏版)》请在冰点文库上搜索。
PB数据窗口其他
[PB]-数据窗口其他
////////////////////////////////
标识当前行
〓标识当前行也就是给当前行加上醒目的标记,以便用户更清楚当前要对哪一行数据进行操作,尤其当用户的操作中间有停顿时,继续进行操作就特别需要知道哪个是当前行。
这里的当前行不要狭隘地理解成仅仅是光标所在行。
当翻页时如果光标所在行不在当前页中,这时应该将当前页中的第一行置为当前行,否则容易造成错觉;当删除数据时,不能自动改变当前行,此时应该使用脚本设置当前行。
标识当前行的函数和方法很多,比较常用的有SelectRow,SetRowFocusIndicaTor,数据窗口对象中的函数CurrentRow和GetRow等,还有很多可以在数据窗口对象中实现的方法。
〓使用SelectRow函数
这是最常用的一种方法。
函数SelectRow的语法比较简单,重点要掌握需要在哪些事件中编写脚本。
函数SelectRow的语法是:
dw_1.SelectRow(row,boolean)
其中,dw_1是数据窗口控件名称;row是要操作的行号,如果取值为0则表示对数据窗口dw_1中的所有数据进行操作;boolean表示是否选中数据,如果为True则表示选中row指定的行,如果为False则表示取消选中row指定的行。
函数正确执行返回1,否则返回-1,如果有参数为NULL则返回NULL。
当选中数据窗口中的一行数据时,数据行以蓝底白字显示。
当用户在数据窗口中使用上下光标键、或者Tab键、或者鼠标点击时,如果改变了光标所在行号则这些操作都会触发数据窗口控件的RowFocusChanged事件。
所以,在数据窗口控件的RowFocusChanged事件中编写脚本来标识当前行,比仅在数据窗口的Clicked事件中编写脚本要全面得多。
脚本如下:
ifcurrentrow>0then
dw_1.selectrow(0,false)
dw_1.selectrow(currentrow,true)
endif
另外,由于滚动垂直滚动条操作不能触发RowFocusChanged事件,如果翻页后当前行不在当前页中,这样容易造成错觉,应该将当前页中的第一行设置为当前行。
在数据窗口控件的ScrollVertical事件中编写如下脚本:
longll_row
ll_row=long(describe("datawindow.firstrowonpage"))//当前页中第一行的行号
ifll_row<1thenreturn
setrow(ll_row)
通过上面两个事件(RowFocusChanged,ScrollVertical)中编写的脚本,就可以较为全面地修改数据窗口控件的当前行标识。
*对“插入”按键编写脚本时,应该使用可以自动触发数据窗口RowFocusChanged事件的语句,例如使用dw_1.scrolltorow(dw_1.insertrow(0))语句可以自动修改当前行标识,而仅使用dw_1.insertrow(0)语句就不能自动修改行标识。
longll_row
ll_row=dw_1.insertrow(0)//插入新行
dw_1.scrolltorow(ll_row)//滚动到新行
dw_1.setrow(ll_row)//设置新行为当前行
dw_1.setcolumn
(2)//设置第2列为当前列
dw_1.setfocus()//dw_1获得焦点
〓使用函数SetRowFocusIndicaTor
函数SetRowFocusIndicaTor可以给当前行指定的位置上设置指定的标志,函数的语法格式如下:
dw_1.SetRowFocusIndicaTor(focusindiacaTor{,xlocation{,ylocation}})
其中,dw_1为数据窗口控件名称;focusindicaTor是枚举型或者特定的图片的名字,可以是以下取值:
Off!
:
取消行标识
FocusRect!
:
在当前行的周围放置一个虚线构成的矩形边框
Hand!
:
使用PB提供的手形指示器
图片的名字:
使用图片的名字可以选择用户喜欢的行标识符号
该函数正确执行则返回1,否则返回-1,如果有参数为NULL则返回NULL。
该函数正确执行后,当数据窗口控件中的RowFocusChanged事件触发时将自动给当前行设置行标。
使用该函数时,只需要在适当的时候个数据窗口控件设置行标识即可,一般可以在检索之后马上设置。
例如,在窗口的open事件中可以如下编写脚本:
dw_1.settransobject(sqlca)
ifdw_1.retrieve()>0then
dw_1.setrowfocusindicator(hand!
)
dw_1.setrow
(1)
endif
在ScrolVertical事件中编写的脚本和上面的“使用SelectRow函数”中介绍的完全相同。
〓使用CurrentRow和GetRow两个函数
在数据窗口对象中实现标识当前数据行的方法和在窗口中编程类似,也是通过数据窗口控件的RowfocusChanged事件来触发函数,只是触发的是数据窗口对象中的函数。
所以,在数据窗口对象中放置函数后,还得在窗口的ScrollVertical事件中编写脚本,事件和上面介绍的完全相同。
程序运行时的效果和在数据窗口对象中编程效果完全相同。
GetRow()函数返回的是表达式触发的行号,CurrentRow函数返回的是当前行的行号,他们都没有参数,返回值都是long类型的行号。
使用这两个函数并配合其他的部件可以标识当前行。
通过修改当前行上text控件的可视性实现标识当前行,给用户的感觉好象当前行的边框发生了改变。
首先,在Detailband中放置一个Text控件,删除该控件中的“text”,设置其外观为3dRasied,将其背景修改为和字段中的数据不同的颜色,将Text控件的senttoback选中,在该Text控件的属性视窗中为visible属性输入如下表达式:
if(currentrow()=getrow(),1,0)
该表达式的作用是在当前行获得焦点时显示Text控件,否则禁止显示Text控件,加宽该Text控件使其正好能够覆盖所有的字段,最好Text的边框能够显示出来,不被字段覆盖;设置所有字段的边框类型以增强显示效果,设置为无边框。
注意,如果字段边框和Text边框设置不当,则显示效果不一定明显。
这种显示风格可以使用户很清楚当前要处理的是哪一行,尤其在处理工作中间有停顿的情况下特别有用。
当然,要观看这种效果,数据窗口中至少应该有一个字段的TabOrder值不为0,否则不能改变当前行,也就无法获得运行效果了。
对上面的方法稍微变通一下,可以直接为所有要显示的字段的Border属性定义表达式。
当前行获得焦点时所有字段是一种边框风格,当失去焦点时又是另外一种风格。
这样也可以实现标识当前行,但是如果字段较多,设置起来就比较烦琐。
比如,可以为所有字段定义如下表达式:
if(currentrow()=getrow(),1,0)
该表达式的含义是当前行字段的边框类型为1(即Shadowbox类型),非当前行则为0(即无边框)。
〓改变背景或者前景
和上面的方法类似,也是利用GetRow和CurrentRow两个函数在数据窗口对象中实现改变背景或前景颜色。
需要为每个字段都规定前景和背景颜色,在每个字段的Background.color属性中都输入表达式:
if(getrow()=currentrow(),rgb(255,0,0),rgb(255,255,255))
然后,在数据窗口控件的ScrollVertical事件中编写和上述作用SelectRow函数中介绍的完全相同的代码即可。
////////////////////////////////
显示指定条件的数据
将符合特定条件的数据全部显示在数据窗口中,在大多数情况下是可以的,这不需要做什么工作。
但是要同时将符合特定条件的和不符合这些条件的数据显示在数据窗口中,以便比较分析,这就需要一定的编程。
关键是使用一定的方法来标识符合条件的数据。
※通过修改前景、背景颜色
要以特殊背景(或前景)颜色显示符合固定条件的数据行时,这种情况比较简单。
可以在数据窗口创建时在字段的属性中把前景和背景颜色赋予固定的表达式。
比如某数据窗口要醒目显示女职工信息,正常显示为黑色前景、灰色背景,醒目显示为红色前景、灰色背景,可输入如下表达式:
BackGroundColor:
If(sex="女",RGB(255,0,0),RGB(0,255,0))
当需要特殊显示背景(或前景)颜色的数据行的条件是由用户动态指定时,就需要做一些编程工作。
在用户改变查询条件的操作中,同时动态修改数据窗口的前景和背景表达式,这样就可以做到背景颜色和条件一起变化。
例如,在窗口w_browse中有两个控件:
下拉列表框ddlb_filter用来列出数据库中所有的职称;数据窗口dw_1显示相应的数据。
当用户在下拉列表框ddlb_filter中选择不同的职称(在数据窗口中职称字段名称为zc)时,数据窗口dw_1中就用特殊背景颜色标识相应职称的职工数据,可在下拉列表框ddlb_filter的SelectionChanged事件中编写如下脚本来实现该功能:
Intli_count,li_index
Stringls_ErrMsg
dw_1.SetRedraw(False)
//首先得到该数据窗口的列数
li_count=Integer(dw_1.Object.DataWindow.Column.Count)
//对每一列的前景、背景表达式进行修改
Forli_index=1Toli_count
ls_ErrMsg=dw_1.ModIfy("#"+String(li_index)+".Background.Mode=0")
Ifls_ErrMsg<>""Then
MessageBox("Status","ChangeToBackgroundModeFailed"+ls_ErrMsg)
Return
EndIf
ls_ErrMsg=dw_1.ModIfy("#"+String(li_index)+".Background.Color=~"16777215~tIf(zc='"+This.Text+"',255,16777215)~"")
Ifls_ErrMsg<>""Then
MessageBox("提示","不能改变字段的背景颜色~r~n"+ls_ErrMsg)
EndIf
Next
dw_1.SetRedraw(True)
※通过修改设置位图
通过修改设置位图显示指定条件的数据时也有查询条件固定和不固定两种情况。
对于固定条件的可以在数据窗口创建时输入位图的Visible表达式,对于条件不固定的可以在用户更换查询条件后使用函数ModIfy()动态地修改数据窗口中位图属性的表达式来实现。
在数据窗口的最左边放置一个位图部件,并修改其Visible属性为一个条件表达式即可。
例如,在显示职工数据的数据窗口对象中放置picture控件后,需要在所有女职工数据行上显示该picture,可以在定义picture的Visible属性中输入如下表达式:
If(sex='女',1,0)
※通过修改边框类型
当查询条件固定时,可以在数据窗口创建时输入边框(Border)表达式。
比如,可以在字段的Border属性中输入如下表达式来标识女职工:
If(sex='女',5,0)
当字段比较多时逐个设置所有的字段比较烦琐。
可以像前面介绍的那样,通过放置一个可以覆盖所有字段的计算域、并为该计算域的Visible属性定义相关的表达式即可。
注意,需要将该计算域的数据颜色和背景颜色设置为相同颜色,并且边框类型设置为和字段反差比较大的类型,比如,当字段都没有边框类型时将该计算域的边框设置为Rasied类型。
这样也可以实现类似的效果。
比如,要标识所有女职工,可以定义计算域的Visible属性为如下表达式:
If(sex='女',1,0)
*这里只能放置计算域,或者放置数据表中其他不需要显示数据的字段,而不能放置其他控件。
因为,需要为每一行创建一个对象,每一行相同的控件的属性是相同的,而不同行的字段或者计算域的属性可以不同。
※通过选中标记来标识符合条件的行
对所有符合特定条件的数据逐行选中,以选中标记来标识符合特定条件的数据。
比如,可以为用户提供一个查询窗口,在该窗口中用户选择了不同的查询条件后,首先使其他所有行处于不选中状态,然后再根据用户条件选中所有符合条件的数据行。
比如下拉列表框ddlb_filter中放的是数据库中所有职工的职称(zc),用户选择不同的职称可以在数据窗口dw_1中用选中标记来标识具有该职称的所有职工的数据。
在下拉列表框的SelectChanged事件中编写如下脚本:
Intli_index
dw_1.SelectRow(0,False)
Forli_index=1Todw_1.RowCount()
Ifdw_1.GetItemString(li_index,"name")=This.TextThen
dw_1.SelectRow(li_index,True)
EndIf
Next
////////////////////////////////
用回车键代替Tab键
创建一用户事件来响应数据窗口的pbm_dwnprocessenter事件,在该事件中加入下面程序:
Send(Handle(this),256,9,long(0,0))//发送处理Tab键的信息
Return1//忽略Enter键的处理
例如,下面的脚本在相应数据窗口的pbm_dwnprocessenter用户事件中编写,用来检查数据窗口中录入数据的各种情况,并执行相应的程序。
(1)当返回负值时
肯定某列存在错误,这时既不处理Enter键也不处理Tab键。
(2)当返回非负值时
a)如果是最后的行列则应该在按回车键时插入一行,并使光标定位到新行的第一列上。
b)如果不是最后行列则应该发送Tab信息,屏蔽Enter键的处理。
ifthis.accepttext()<0then//如果不能正确接受用户的输入信息
return1//则不进行按键处理,直接返回
endif
ifthis.GetColomn()=long(dw_1.object.datawindow.column.count)then
ifthis.GetRow()=this.RowCount()then//如果是最后一列,最后一行
this.insertrow(0)
this.scrolltorow(this.GetRow()+1)
this.setcolumn
(1)
return1
endif
endif
send(handle(this),256,9,long(0,0))//发送处理Tab键的消息
return1//忽略回车键的处理
////////////////////////////////
数据拷贝
〓使用GetItem()和SetItem()函数
在循环中将源数据窗口中的数据逐一读出,每读出一个字段就将其写入到目标数据窗口中的相应字段中,直到将源数据窗口中要拷贝的数据读完为止。
这是经常使用的一种方法,虽然它的效率比较低,但控制比较灵活,允许有选择地拷贝某些字段,并在拷贝后可以进行一定的处理后再进行复制。
这种方法在拷贝内容比较少时经常使用。
〓使用剪贴板
先使用函数SaveAs()将数据保存到剪贴扳上,再输入到另一个数据窗口中。
这种方法适用于拷贝源数据窗口中的所有数据的情况,并且目标数据窗口兼容源数据窗口中对应字段的
数据类型。
dw_source.SaveAs("",Clipboard!
false)//将数据保存到剪贴板,--函数说明见帮助
dw_dest.ImportClipBoard()//将数据从剪贴板拷贝到目标数据窗口
〓使用结构类型的数组进行赋值
将数据从源数据窗口拷贝到结构类型的数组中,然后在从结构数组中将数据拷贝到目标致据窗口中。
不采用下一小节所讲的直接赋值的方法,原因是有可能将提取出的数据有选择
地或者进行一番处理后再给目标数据窗口。
比如,下面定义一个变长的结构类型数组lstr_data,其结构和源数据窗口dw_source的字段构成相同,使用它进行数据拷贝。
脚本如下:
lstr_data=dw_source.objcet.data
dw_dest.object.data=lstr_data
〓直接赋值
当两个数据窗口的对应字段类型相同或兼容时,可以将源数据窗口的数据直接赋给目标数据窗口。
例如,将数据窗口dw_source中的数据全部拷贝到数据窗口dw_dest中,可以使用下面的脚本:
dw_dest.object.data=dw_source.object.data
当需要拷贝数据窗口中的所有数据时,这种方法的执行效率最高。
〓使用行拷贝的方法
以行为单位,可以将数据拷贝到其他数据窗口中,也可以在一个数据窗口内部进行拷贝。
使用函数RowsCopy可以实现数据行的拷贝。
该函数的语法如下:
dw_1.RowsCopy(startrow,endrow,copybuffer,targetdw,beforerow,targetbuffer)
其中,dw_1为数据窗口控件名称;startrow,endrow和copybuffer参数都是对源数据窗口而言的,这三个参数指定源数据窗口copybuffer缓冲区中从startrow开始到endrow结束的数据要拷贝;参数targetdw,beforerow和targetbuffer用来限定要拷贝的数据放置到目标数据窗口的什么位置,即在目标数据窗口targetdw的targetbuffer缓冲区中从beforerow行开始放置拷贝过来的数据。
函数正确执行返回1,否则返回-1,如果有参数为NULL则返回NULL。
另外,缓冲区是一个枚举类型数据,应该取值为Primary!
,Delete!
或者Filter!
。
〓其他
longdwcontrol.ImportString(stringstring{,longstartrow{,longendrow{,longstartcolumn{,longendcolumn{,longdwstartcolumn}}}}})
Description:
InsertsdataintoaDataWindowcontrolorDataStorefromtab-delimiteddatainastring.
longdwcontrol.ImportFile(stringfilename{,longstartrow{,longendrow{,longstartcolumn{,longendcolumn{,longdwstartcolumn}}}}})
Description:
InsertsdataintoaDataWindowcontrolorDataStorefromafile.Thedatacanbetab-delimitedtextordBaseformat2or3.
////////////////////////////////
运用External类型数据窗口
配置选项是指进行其他处理所需要的信息,当这些信息需要用户指定时,开发人员应该提供相应的界面,使用External类型数据窗口是一个很好的选择。
虽然在窗口中放置控件也能实现,但是编程烦琐,要读取各控件,而且功能也不如External类型窗口强大。
使用External类型的数据窗口还可以有效地保证界面的一致,需要同样功能的其他窗口只需简单地放置该数据窗口控件即可。
比如,查询条件构造界面可以使用External类型数据窗口让用户来构造查询条件。
因为使用数据窗口来接受查询条件,只要使用Insert函数就可以增加查询条件,所以用户可以随意指定任意多个查询条件,而如果使用窗口中的下拉列表框或单行编辑器等控件就很难实现任意多个条件的组合。
如果使用这些窗口控件,读取各个控件的值的方法也不统一,不同控件需要不同的读取方法,而使用External类型数据窗口只要用GetItemString一个函数就可以很方便地读出用户输入的条件。
所以,灵活运用External类型数据窗口,不仅编程简洁,而且可以构造出功能强大的程序。
使用External类型的数据窗口取代窗口中的控件,关键在于灵活运用数据窗口对象中的各个控件和字段的编辑风格。
////////////////////////////////
数据保护
可以把数据的保护分为三种情况:
(1)某些字段不论什么条件下用户都不能修改,一般只是用来显示数据的
在什么条件下都不允许修改的字段一般可以通过程序设定,比如系统日期、依赖于其他字段的字段及按次序产生的序号等,这样的字段让用户修改就不容易保证数据的一致性和正确性,并且用户也没有必要修改,可以用以下三种方法将这样的字段设置为用户不可修改的字段:
a.在数据窗口设计时将这些字段的TabOrder值置为0,以使该字段不能获得焦点,用户无法选中和编辑该字段。
b.将字段的DisplayOnly属性设置为True。
该字段可以获得焦点,可以选中该字段,还可以拷贝复制该字段中的内容,但不能编辑该字段中的内容。
c.设置字段的Protect属性。
字段的Protect属性如果设置为“1”,则该字段的TabOrder值即使不是0也不会得到焦点。
使用该属性可以保护一些重要的数据。
多用户下的、值按次序产生的关键字段可设置为不可修改。
因为是关键字段,必须保证其惟一性。
多个用户可能在同时修改该字段,靠前台就很难保证惟一性,只能通过后台修改,所以这样的字段需要设置为不可修改。
在数据窗口画板中选择窗口菜单Rows中的UpdateProperties命令,把需要后台产生的字段在左下角的UpdateableColumns中去掉,并在后台将该字段设置为序列字段即可。
(2)已有数据不让修改,新数据中的部分或全部允许修改
这种情况可通过编程实现。
编程思想是:
判断当前行的状态,如果是新增加的数据行则允许修改,否则不允许修改。
是否可以修改可以通过设置字段的Protect属性来实现,当然还可以有更多的方法。
是否是新增加的数据可以通过使用函数GetItemStatus判断行的状态来得知。
具体编程如下:
a.为了恢复字段的Protect属性,定义一个实例变量,类型为整型变长数组:
Intii_protect[]//保存字段的Protect属性
b.在窗口的Open事件中保存数据窗口所有字段的Protect属性:
Intli_ColumnCount
Longll_index
li_ColumnCount=dw_1.Object.DataWindow.Column.Count
Forll_index=1Toli_ColumnCount
ii_protect[ll_index]=dw_1.Describe("#"+String(ll_index)+".Protect")
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- PB 数据 窗口 其他
![提示](https://static.bingdoc.com/images/bang_tan.gif)