在PB中调用SetFilter可以用来设置过滤条件,如果要使过滤条件起作用,应再调用Filter函数,这似乎是所有PB开发人员都知道的常识,但是,如果你再细心点,你会发现,对于展示风格为交叉表的数据窗口在调用SetFilter函数虽然成功,但不会更改datawindow.table.filter属性,而其它风格的数据窗口会更改datawindow.table.filter属性。
你想使交叉表数据窗口与其它类型数据窗口在调用SetFilter后发生同样的作用吗?你需要编写额外的代码帮助解决这个问题。方法是先将主缓冲区和过滤缓冲区数据移到删除缓冲区,调用SetFilter后再调用Filter,这时datawindow.table.filter属性被改变,之后再将原本属于主缓冲区、过滤缓冲区数据从删除缓冲区移回,这样移来移去最终目的是保证各缓冲区数据及状态不变。当然,一般情况下,调用了SetFilter后会调用Filter执行过滤,所以大多数情况下,你无需做额外的处理,而如果你在调用SetFilter和Filter之间有提取数据窗口语法或过滤条件动作时,上述补遗就显得很有必要。
以下是笔者自定义的of_setfilter函数,建立在数据窗口祖先中,你可以使用of_setfilter代替PB自带的setfilter函数,你也可以以类似的代码重载setfilter函数。注意,如果函数建立在datastore,你要删除this.setredraw(false)和this.setredraw(true)两行代码。
/*******************************************************************
函数名称:of_setfilter()
参数: as_filterexpr string 过滤表达式
返回值: integer 是否成功(1表示成功,-1表示失败)
功能描述:设置过滤表达式
创建人: 康剑民
创建日期:2007-02-10
版本号: V1.0
备注: 本函数为解决PB-BUG而创建,非交叉表调用setfilter()会改变datawindow.table.filter,
交叉表调用setfilter()成功但语法没变,只有调用filter()才改变语法,
交叉表使用modify修改datawindow.table.filter会执行过滤动作,非交叉表不会执行过滤动作
*******************************************************************/
integer li_return
long i,ll_rowcount,ll_filteredcount,ll_deletedcount
long ll_beginrow_primary,ll_endrow_primary,ll_beginrow_filter,ll_endrow_filter
if this.describe("datawindow.processing") = "4" then//交叉表
this.setredraw(false)
ll_rowcount = this.rowcount( )
ll_filteredcount = this.filteredcount( )
//将主缓冲区数据移到删除缓冲区暂存
if ll_rowcount > 0 then
ll_deletedcount = this.deletedcount( )
ll_beginrow_primary = ll_deletedcount + 1
ll_endrow_primary = ll_deletedcount + ll_rowcount
this.rowsmove(1,ll_rowcount,primary!,this,ll_deletedcount + 1,delete!)
end if
//将过滤缓冲区数据移到删除缓冲区暂存
if ll_filteredcount > 0 then
ll_deletedcount = this.deletedcount( )
ll_beginrow_filter = ll_filteredcount + 1
ll_endrow_filter = ll_filteredcount + ll_filteredcount
this.rowsmove(1,ll_filteredcount,filter!,this,ll_deletedcount + 1,delete!)
end if
li_return = this.setfilter(as_filterexpr)
this.filter()//执行过滤
//将本属于主缓冲区数据一次性从删除缓冲区移回到主缓冲区
if ll_rowcount > 0 then
this.rowsmove(ll_beginrow_primary,ll_endrow_primary,delete!,this,1,primary!)
end if
//将本属于过滤缓冲区数据一次性从删除缓冲区移回到过滤缓冲区
if ll_rowcount > 0 then
this.rowsmove(ll_beginrow_filter,ll_endrow_filter,delete!,this,1,filter!)
end if
this.setredraw(true)
else
li_return = this.setfilter(as_filterexpr)
end if
return li_return
写作日期:2007-02-10
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1508077
-

没有评论:
发表评论