PB7.0通用选字段查询窗口的设计
本文介绍一个在PB7.0下实现的通用查询窗口,可实现对任意表的查询,输出字段、排序字段、查询条件都可以随意指定。功能丰富,使用方便、灵活,可挂接到任何PB应用软件中,从而大大提高软件的开发效率。
本文是《PB7.0通用全字段查询技术》(计算机世界周报2000年第3期)的姊妹篇。两篇文章介绍的技术方案不同,做出查询窗口的风格、形式和用法也不同,可同时使用,丰富系统功能。
在PB7.0中,数据库中表的内容通常用数据窗口对象显示输出,而数据窗口对象一般都要事先建立。能不能在程序运行过程中根据用户指定的字段,动态建立数据窗口对象,进一步,再通过用户指定的条件对记录进行过滤,达到查询的目的?回答是肯定的。我们设计了一个窗口,不仅实现了上述功能,而且可以挂接到任何PB应用软件当中,对任意表进行查询、排序和打印,很有实用价值,愿与读者分享。下面介绍实现方法和具体步骤。
一、准备
1.首先建立一个应用程序对象serch,并对其open事件编写如下代码:
SQLCA.DBMS=ProfileString("PB.INI","Database","DBMS","")
SQLCA.DbParm=ProfileString("PB.INI","Database","DbParm","")
CONNECT USING SQLCA;
If sqlca.sqlcode <> 0 Then
MessageBox ("数据库连接失败", sqlca.sqlerrtext)
Halt //终止应用程序
End If
open(w_serch) //打开通用选字段查询窗口
2.建立任意一个数据库(例如,Adaptive Server Anywhere 6.0数据库test.db),配置ODBC、Profile,建立需要的若干个表。如:nhxx(农户信息表)、tjzl(生产信息表)等。可以使用任何已有的数据库和表。
二、窗口设计
通用查询是在窗口中实现的,技术核心都在窗口的控件当中。
首先,建立一个窗口对象w_serch。其中包含一个数据窗口控件dw_1,一个下拉列表ddlb_1,三个命令按钮cb_3、cb_4、cb_5,一个单行编辑框sle_2和一个标签tab_1。
标签tab_1的第一个标签页tabpage_1上放置一个列表框lb_1、一个单行编辑框sle_1和两个命令按钮cb_1、cb_2。
窗口和第一个标签页tabpage_1如下图所示。
为进行窗口各控件之间的数据传递,声明以下四个实例变量:
string s_tn //表名变量
string s_seq="A" //排序方式变量(默认升序)
string s_cn,s_ct,s_cp //字段名、字段类型、比较符变量
string t_c[50,3] //存放表中各“字段名”、“字段类型”和“字段标题”
窗口中下拉列表框ddlb_1的作用是选择不同的表。在它的item属性中设置两项:“农户信息"和“生产信息”,作为表名提示信息。当选择某一项时,通过代码将对应的表名送实例变量s_tn。通过修改和添加item项以及相应代码,即可选择不同的表,从而实现对任意表的查询。这里设置的“农户信息”、“生产信息”是两个例子。
当下拉列表框ddlb_1的选项改变时,产生selectionchanged事件,通过下面程序代码,将选定的表名送变量s_tn,该表的各个字段名、字段类型、字段标题送数组t_c,各字段标题添加到三个标签页上的列表框lb_1、lb_2、lb_3中。其中,数组t_c的第一个下标表示字段序号,第二个下标值1、2、3分别表示字段名、字段类型和字段标题。这里用到了系统表PBcatcol,它的字段PBc_tnam、PBc_cnam、PBc_jtfy和PBc_hdr值分别存储表名、字段名、字段类型和字段标题。
integer i //循环变量(数组下标)
CHOOSE CASE ddlb_1.text //根据表名提示信息,确定相应的表名
CASE "农户信息"
s_tn="nhxx"
CASE "生产信息"
s_tn="tjzl"
END CHOOSE
DECLARE tab_col CURSOR FOR //定义游标
SELECT "PBcatcol"."PBc_tnam", //表名
FROM "PBcatcol"
WHERE "PBcatcol"."PBc_tnam" = :s_tn ;
OPEN tab_col; //打开游标
i=1
//字段名、类型、标题送数组
FETCH tab_col into :s_tn,:t_c[i,1],:t_c[i,2],:t_c[i,3];
DO While SQLCA.SQLCode=0
//设置列表信息(字段标题)
tab_1.tabpage_1.lb_1.AddItem(t_c[i,3])
tab_1.tabpage_2.lb_2.AddItem(t_c[i,3])
tab_1.tabpage_3.lb_3.AddItem(t_c[i,3])
i++
FETCH tab_col into :s_tn,:t_c[i,1],:t_c[i,2],:t_c[i,3];
Loop
CLOSE tab_col; //关闭游标
第一个标签页tabpage_1上列表框lb_1列出当前表各字段的标题,用于确定输出字段。为了能按windows资源管理器方式选择字段,应设置它的multiselect属性。
命令按钮cb_2的作用是将lb_1中选中的字段标题转换为字段名,形成字段表列放到单行编辑框sle_1中。其clicked代码如下:
int k //循环计数器
For k=1 to lb_1.totalitems() //列表项目数
If lb_1.state(k)=1 then //该项被选中
If sle_1.text="" then
//得到字段名
sle_1.text=t_c[k,1]
Else
//拼接列名
sle_1.text=sle_1.text+","+t_c[k,1]
End If
End If
Next
命令按钮cb_1的作用是清除单行编辑框sle_1的内容。clicked代码只有一行:
sle_1.text=""
第二个标签页tabpage_2如下图所示。其中有一个列表框lb_2,一个单行编辑框sle_3,一个命令按钮cb_6,两个单选按钮rb_1和rb_2。
列表框lb_2列出当前表的各字段标题。单击某一项时,产生selectionchanged事件,下面代码得到字段名,添加s_seq变量值(“A"或“D"),形成排序字符串放到单行编辑框sle_3。
integer k //循环计数器
For k=1 to lb_2.totalitems() //列表项目总数
If lb_2.state(k)=1 then //该项被选中
If sle_3.text="" then
//形成排序字符串
sle_3.text=t_c[k,1]+" "+s_seq
Else
//拼接排序字符串
sle_3.text=sle_3.text+","+t_c[k,1]+" "+s_seq
End If
End If
Next
单选按钮rb_1、rb_2用来设置排序方式变量s_seq的值,clicked代码分别为
s_seq="A" (升序)和
s_seq="D" (降序)
命令按钮cb_6的作用是清除单行编辑框sle_3的内容。clicked代码为
sle_3.text=""
第三个标签页tabpage_3如图3所示。它上面放有一个列表框lb_3,一个下拉列表框ddlb_2,两个单行编辑框sle_4和sle_5,两个单选按钮rb_3和rb_4,两个命令按钮cb_8和cb_9。
列表框lb_3列出当前表的各字段标题。单击某一项时,产生selectionchanged事件,通过下面代码将对应的字段名、字段类型分别送实例变量s_cn和s_ct。
int k //循环计数器
For k = 1 to lb_3.totalitems() //列表项目数
If lb_3.state(k)=1 then //该项被选中
s_cn=t_c[k,1] //取出字段名
s_ct=t_c[k,2] //取出字段类型
End If
Next
下拉列表框ddlb_2列出常用关系运算符(比较符)的描述文字,选择某一项后,产生selectionchanged事件,通过下面代码得到相应的关系运算符送实例变量s_cp。
CHOOSE CASE ddlb_2.text
CASE "等于"
s_cp=" = "
......
CASE "含有"
s_cp="in"
END CHOOSE
单行编辑框sle_5用来输入比较内容。
单击按钮cb_8(选中),通过以下代码形成条件表达式字符串送单行编辑框sle_4。
If s_ct="24" THEN
//形成条件表达式字符串(数值类)
sle_4.text=sle_4.text+s_cn+s_cp+sle_5.text
Else
//形成条件表达式字符串(字符类)
If s_cp="in" Then
sle_4.text=sle_4.text+"Pos("+s_cn+",'"+sle_5.text+"')>0"
Else
sle_4.text=sle_4.text+s_cn+s_cp+"'"+sle_5.text+"'"
End If
End If
在形成条件表达式字符串时,要根据字段类型是数值类还是字符类决定是否用引号定界符。字段类型 </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>