PB]-子数据窗口

来源:互联网 发布:什么是网络教育 编辑:程序博客网 时间:2024/04/27 04:44
**通常的子数据窗口也就是下拉数据窗口。子数据窗口也是普通的数据窗口对象,没有什么特殊的地方,它的创建方法、可以使用的控件、编程时可以使用的函数等,都和普通的数据窗口相同。特殊的地方只是因为它放在了父数据窗口中,需要和父窗口进行配合。

**当为数据窗口中某字段指定为下拉数据窗口编辑风格时,必须提供以下三个属性:
a)子数据窗口名称。
b)显示字段名称:该字段中的内容显示在父数据窗口的字段上,只是显示。
c)数据字段名称:该字段中的内容要赋给父数据窗口的字段,要保存到数据库中。
分别对应数据窗口画板的Edit属性页中的:Eidt Style、Display Column、Data Column。
*子数据窗口不能再包含子数据窗口;父数据窗口可以对其包含的子数据窗口进行插入、删除、检索和保存等操作。

**获取子数据窗口的引用是进行其他操作的前提,使用函数GetChild来获取指定字段的子数据窗口。该函数的语法如下:
dw_1.GetChild(name,dwchildvariable)
其中,dw_1.是数据窗口控件名称;name为字段名称,为string类型;dwchildvariable为datawindowchild类型变量,该变量在函数正确执行后保存对子数据窗口的引用。该函数正确执行则返回1,否则返回-1。
在获取了子数据窗口的引用之后,就可以捡索子数据窗口中的数据了。但是,检索子数据窗口的情况比较多,并且也有多种方法。


**保证子数据窗口中的数据更新
用户使用下拉数据窗口录入数据时,其中的数据并不一定有用户需要的。在某些情况下不允许用户再输入其他值,否则可能造成数据的不一致性,这时就可以不再编写其他的脚本。但在允许用户录入时,就需要把用户录入的数据保存在子数据窗口对应的数据表中,以便以后数据录入时不再重复输入该数据。这时就应该编写脚本保存该数据了。


**检索子数据窗口
在应用中,对子数据窗口的编程不是检索数据,就是更新其中的数据。检索数据时,如果只显示子数据窗口中同父数据窗口中某字段取值对应的数据,这时子数据窗口的定义就应该有检索参数。根据检索和更新数据这两个因素,可以将检索数据的情况划分成以下三种:
    a)没有条件限制,并且不允许更新。
    b)没有条件限制,并且允许更新。
    c)有条件限制,不管是否可以更新。
    检索子数据窗口有两个时机,一个是在子数据窗口下拉时,另一个是在父数据窗口检索时。在子数据窗口打开时进行数据检索,每次录入该字段时都要进行,所以可以保证子数据窗口中的数据是最新的,所以这样的检索是在数据可以更新的情况下才使用。而不允许更新时,子数据窗口中的数据总是和父数据窗口检索时相同,如果不根据其他字段取值检索数据,就没有必要每次录入时都进行检索,只要在窗口打开时进行检索就可以了;当要根据其他字段取值检索数据时,还得在每次下拉子数据窗口时进行检索。
*和父数据窗口共享事务对象
在和父数据窗口共享事务对象的情况下的编程最简单。因为子数据窗口可以和父数据窗
口共享事务对象,只是简单地对父数据窗口进行检索,即可将子数据窗口中的所有数据自动检索出来。一般在窗口的open事件中编写如下脚本:
dw_1.settransobject(sqlca)
dw_1.retrieve()
一种特殊的情况需要注意。当A、B两个数据窗口共享数据时,如果其中B有子数据窗口,A设置事务对象而B没有设置,当A使用函数Retrieve检索数据后,B因为共享数据也会自动获得数据,但是B中的下拉子数据窗口的字段只能显示编码而不能显示对应的汉字,即使该下拉子数据窗口的属性中显示列、数据列都设置正确也是如此。只有当数据窗口B设置了事务对象才能在A检索数据之后正确显示下拉子数据窗口Display Value中指定的字段数据。
*检索子数据窗口的数据
因为用户随时都有可能录入了新数据,为了保证子数据窗口中显示最新数据,每次打开子数据窗口时都重新进行数据检索。用户在打开子数据窗口之前一般有鼠标点击动作,所以可以在数据窗口控件的clicked事件中编写脚本。例如,在一个进行工资人事管理的软件中,人事信息保存在employee库中,录入工资的数据窗口要选择职工时可以使用下拉数据窗口。子数据窗口至少包含职工姓名name和职工身份证号no。下面是完整脚本:
datawindowchild ldwc_data
if dw_1.getchild("name",ldwc_data) <> -1 then
ldwc_data.settransobject(sqlca)
ldwc_data.retrieve()
end if
在很多书籍和讲座中,都使用上面的编程方法进行子数据窗口的数据检索。(*可以在单击事件中先判断是否是下拉的字段列,再进行检索子数据窗口)实际上,还有更为合理的解决办法。因为上面的方法不管用户点击的是否是下拉数据窗口,都要执行脚本,并且用户选择下拉数据窗口中的数据之前也并不总是首先点击鼠标,还可能通过键盘来操作,不仅这样做的程序执行效率不高,而且逻辑上也不是很严格。如果有这样一个事件,该事件只有当用户使用下拉数据窗口时才触发,这样脚本的执行效率就会高了。另外,上面的解决方法,在一个数据窗口中有多个子数据窗口时也比较麻烦,必须书写多个类似上面的脚本,对每个有下拉数据窗口的字段都进行判断,烦琐的很;并且一旦字段的名字发生变化时,脚本也必须加以修改,通用性也很差。下面再介绍一种方法。
首先定义一个自定义事件ue_dropdown,映射pbm_dwndropdown。该事件只有用户下拉数据窗口要打开时触发,所以执行效率比较高。然后在该事件中编写如下脚本:
datawindowchild ldwc_data
getchild(getcolumnname(),ldwc_data)
ldwc_data.settransobject(sqlca)
ldwc_data.retrieve()
这样,就可以很好地解决上面提到的烦琐和不通用的问题。
    第二种需要检索数据的情况,是当用户录入了某个宇段时,该字段可以决定其他字段的取值范围,这时就要检索铁决定的字段的子数据窗口中的数据。
*使用带参数检索
在检索受其他字段录入影响的字段数据的情况下,子数据窗口的设计应该是带有检索参数的,在适当的事件中使用带参数检索。比如,当用户录入了部门名称后,应该让“职工”,字段的子数据窗口只显示该部门的职工姓名。可以在该数据窗口控件的ue_dropdown(映射pbm_dwndropdown事件)事件中编写如下脚本:
    …… //首先获取子数据窗口的引用。
    child.retrieve(getitemstring(getrow(),"department"))
当然上面的脚本也可以在数据窗口控件的Clicked事件中编写。
    如果子数据窗口的检索条件总取决于某个固定的字段,可以使用上面的带参数检索。如果取决于多个字段,可以使用过滤来实现。


**共享子数据窗口
当同时打开多个包含相同字段的子数据窗口时,有必要保证这些子数据窗口之间的数据同步,这是一个比较重要的问题。因为,如果有一个子数据窗口中,用户输入了新数据并且
该子数据窗口正确保存,其他子数据宙口如果不能同步反映出来,就会造成很多问题。如果其他用户没有重新输入该数据,这时的情况还好一些,如果又重新输入了该数据,保存会出现错误信息,用户会感觉到莫名其妙。所以,一定要重视这时的同步问题。
    对于同一个客户端同时打开的多个子数据窗口,使用数据共享可以很好地解决它们之间的同步问题。比如,在工资、人事管理软件中,可能同时打开工资和奖金发放窗口,这两个窗口中的数据窗口都有包含身份证号的子数据窗口。下面介绍如何进行同步。
    假设两个窗口的打开有一定的顺序。比如,在工资发放窗口中双击数据窗口时打开人事维护窗口w_rs。在窗口w_gz的数据窗口的dubleClicked事件中编写如下脚本:
datawindowchild ldwc_data
if getchild("no",ldwc_data) = -1 then return
if w_rs.dw_1.sharedata(ldwc_data) = -1 then
beep(1)
if messagebox("错误","发生意外错误,是否继续?",yesno,2) = 1 then
   open(w_jj)
end if
end if
上面的脚本保证了对奖金窗口w_jj上数据窗口dw_1中主缓冲区所做的任何更新操作都
将在子数据窗口child中得到反映。
    当要打开的窗口之间没有顺序,并且打开哪些窗口也不确定时,可以通过定义全局变量来实现。比如,在物资管理系统中,物资名称和对应的代码使用一个数据表来保存。很多数据窗口录入物资时部使用该子数据窗口。可以在该系统中定义全局变量,语句如下:
datawindowchild gdwc_data
然后在用到该子数据窗口的窗口open事件中都编写如下脚本:
datawindowchild ldwc_data
if getchild("no",ldwc_data) = -1 then return
if ldwc_data.sharedata(gdwc_data) = -1 then
ldwc_data.settansobject(sqlca)
ldwc_data.retrieve()
end if
这样,每个数据窗口中的数据更新都可以自动反映到其他的数据窗口中。


PB数据窗口中字段下拉窗口的setfilter

DatawindowChild idwc_child

dw_1.GetChild("字段名",idwc_child)

idwc_child.SetTransObject(sqlca)
idwc_child.Retrieve()
//messagebox("(dept = '"+ycr_user.user_dept+"' AND usr_right = '3'",ycr_user.user_dept)
//if(ycr_user.user_zt ='02' or ycr_user.user_zt  = '04') then
if (ycr_user.user_dept = '21' or ycr_user.user_dept = '22') then
idwc_child.setfilter("dept = '"+ycr_user.user_dept+"' AND usr_right = '3'")
else
idwc_child.setfilter('(dept = "'+ycr_user.user_dept+'" AND usr_id <> "'+ycr_user.zh_czry+'") OR usr_right = "4"')
end if
idwc_child.filter( )
0 0