通用程序巧排序——PB数据窗口中多关键字排序的实现

编程爱好者

编者按:用PB进行项目开发时,数据窗口的排序是必然要解决的问题。要实现对任意数据窗口按多关键字排序,可以用一个通用的方法,今天我们就向大家介绍这种方法。

用PB进行项目开发时,数据窗口的排序是必然要解决的问题。常用的处理方法是在数据窗口控件的Clicked事件中添加代码,当用户点击数据窗口列标题时,按其进行升序或降序排列。此种方法需要为每个数据窗口控件逐一添加代码,且只能依据一个关键字排序。为了实现对任意数据窗口按多关键字排序,可以添加一个专用于排序的功能窗口,通过多个下拉列表框控件显示指定数据窗口对象的数据列名称,供用户选择各自的升降序,并向调用窗口返回排序表达式。具体实现步骤如下(以按两个关键字排序为例):

一、设置全局变量

我们可以添加一个全局字符型变量,用于传递数据窗口对象名称及排序表达式。

//用于向排序窗口传递需要排序的数据窗口对象,并从排序窗口带回排序表达式

String px_datawindow

二、创建排序窗口

新建一个用于根据指定数据窗口对象生成排序表达式的response!类型的窗口(除包含图中可见控件外,还包含一个隐藏的数据窗口控件dw_1[Visible属性设为False]),保存为W_PX,以供工作窗口调用,外观如图。

1.在窗口的Open事件中添加如下代码:

//将工作窗口传递过来的数据窗口对象填入本窗口的数据窗口控件中,用于读取列标题

dw_1.dataobject=px_datawindow

dw_1.settransobject(sqlca)

dw_1.retrieve()

//从第一列开始读取列标题

int l_zs=1

//读取的列标题先存入此变量

string l_name

//通过setcolumn()函数先定位到某列,返回-1表示失败

do while (dw_1.setcolumn(l_zs))<>-1

//通过getcolumnname()函数读取列名

l_name=dw_1.getcolumnname()

//列名加_t就是列标题控件的名称(必须遵守这一规则)

l_name=l_name+'_t.text'

50-g15-1.jpg

//通过describe()函数获取指定属性的值,此处获取的是text属性,即列标题上显示的列名称

l_name=string(dw_1.describe(l_name))

//将获得的列标题名称加入到ddlb_1,ddlb_2中,供用户选择

ddlb_1.additem(l_name)

ddlb_2.additem(l_name)

//准备获取下一列的列名

l_zs++

loop

//ddlb_3,ddlb_4用于控制升降序,让其默认选择第一项

ddlb_3.selectitem(1)

ddlb_4.selectitem(1)

2.下拉列表框控件ddlb_1用于选择第一排序关键字,将Sorted属性设为False(不自动排序),在selectionchanged事件中添加如下代码:

//如果选择了第一个关键字,第二个关键字变为可选

if len(trim(ddlb_1.text))>0 then ddlb_2.enabled=true

3.下拉列表框控件ddlb_2用于选择第二排序关键字,将属性Enabled设为False(不可选),将Sorted属性设为False(不自动排序),当用户选择了第一关键字后才能选择第二关键字。

4.下拉列表框ddlb_3、ddlb_4用于控制选定关键字的升降序,在其Items属性中加入“升序”、“降序”两项,将Sorted属性设为False(不自动排序)。

5.按钮控件pb_1用于按选定关键字及升降序要求生成排序表达式,在Text属性中填入“排序 Enter”,将Default属性设为True(按回车键执行此按钮的Clicked事件),在Clicked事件中添加如下代码:

int x1

//如果选择了第一关键字

if len(trim(ddlb_1.text))>0 then

//查找选择的是第几项

x1=ddlb_1.finditem(ddlb_1.text,0)

//选择的是第几项就定位到数据窗口的第几列

dw_1.setcolumn(x1)

//获取列名,用于组成排序表达式

px_datawindow=dw_1.getcolumnname()

//确定升降序

if ddlb_3.text='升序' then

px_datawindow=px_datawindow+' a'

else

px_datawindow=px_datawindow+' d'

end if

//选择了第二关键字,且与第一关键字不同

if ddlb_2.text<>ddlb_1.text and len(trim(ddlb_2.text))>0 then

x1=ddlb_2.finditem(ddlb_2.text,0)

dw_1.setcolumn(x1)

px_datawindow=px_datawindow+','+dw_1.getcolumnname()

if ddlb_4.text='升序' then

px_datawindow=px_datawindow+' a'

else

px_datawindow=px_datawindow+' d'

end if

//如果需要第三、第四关键字,在窗体中添加类似控件,在此处添加代码

end if

//生成完毕,关闭此窗口,返回工作窗口

close(parent)

else

messagebox('错误', '请选择排序关键字!',stopsign!)

end if

6.按钮控件pb_2用于取消执行排序功能,在Text属性中填入“返回 Esc”,将Cancel属性设为True(按Esc键执行此按钮的Clicked事件),在Clicked事件中添加如下代码:

//设置排序不成功标记

px_datawindow='-1'

//关闭排序窗口,返回工作窗口

Close(parent)

三、执行预排序

在工作窗口中添加一个按钮(点击此按钮调用排序窗口,对指定的数据窗口排序),并在Clicked事件中添加如下代码:

//将数据窗口控件连接的数据窗口对象存放在px_datawindow中,传递到排序窗口

px_datawindow=dw_1.dataobject

//调用排序窗口

open(w_px)

//得到正确的排序表达式

if px_datawindow<>'-1' then

//按返回的排序表达式设定工作窗口中数据窗口控件的排序

dw_1.setsort(px_datawindow)

//执行排序

dw_1.sort()

end if

需要注意的是:

1.数据窗口对象中显示数据内容的控件与列标题控件的命名应遵守一定规则:列标题控件的名字是在显示数据内容的控件的名字后加_t,即如果显示数据内容的控件的名字为cpbh,对应列标题控件的名字就应为cpbh_t;

2.数据窗口对象中各显示数据内容的控件的Tab Order属性不能为0,应通过Format菜单下的Tab Order功能逐个顺号设置Tab order属性。

注:以上代码在PB9.0+Sql Server2000、WinXP SP2环境下调试通过。