:VFP中多条件数据查询程序的实现

来源:百度文库 编辑:九乡新闻网 时间:2024/04/28 13:28:41
摘要:本文通过具体的实例,介绍了多条件数据查询的设计方法,提供了用于条件输入控件的控制和数据类型匹配的解决方案。

  关键词:数据库,多条件查询,数据匹配
  数据查询是用户使用各种软件来管理数据的目的之一,也是各种数据库程序设计的重点。用户希望能方便有效快速地找到他们所需的信息,为各种事务处理提供有力的支持。所以,数据查询作为信息管理软件设计中要实现的一项重要功能,必须具有良好的数据界面和方便的操作及灵活的查询功能,这也是信息管理软件开发人员所追求的目标。

  1 用VFP系统命令进行查询操作的不便之处

  在Visual FoxPro数据管理系统中,设置了查询命令和查询向导,可以进行数据库表记录的选择、分组查询、多表查询及查询结果数据的输出等功能,能够产生独立的查询文件,通过调用该文件可得到所需要的数据。但这些分散的功能命令和文件不适用于数据库应用程序的查询操作,使用这种方式设计的数据库应用程序,用户必须熟知VFP系统命令、操作、数据类型的匹配方式及各种数据表之间的关系才能有效的查询到自己所需的信息,这给用户进行数据查询操作带来极大的不便。如果能把数据库表文件的选择、查询结果输出字段的选定、不定数量查询条件的输入、条件表达式中数据类型的匹配及查询结果的输出等操作容为一体,设计在一个查询程序中,则查询操作将变得非常方便灵活而且简单。

  2 查询程序的设计

  为了使查询程序具有良好的交互功能和方便操作,可使用如图1所示操作界面。在此查询程序中,查询操作只需要在窗口提供的数据库表中选择所要查询的数据表,在选择字段项的列表框中选定要显示的数据字段,在选择条件项中设置查询的数据条件,最后点击查询按钮,则查询结果数据将按图2所示的表格列出。其中,图1 中选定的字段将作为图2 中的表格标题,图2表格中的数据为图1选定的数据表中符合条件的数据记录。图1中输入的条件为:来款日期为1999年10月以后且来款单位含有"宝钢"的记录,并在图2的表中显示出来款日期、来款单位、来款数和室别。

  2.1 控件设置

  在图1所示查询窗体上设置Option控件、ListBox控件组、条件设置控件组。

  Option控件用于选择当前所要查询的数据库表。

  ListBox控件组分别用于源数据表的字段列表和被选择字段名列表。选择项ListBox控件作为查询数据表中的字段名,被选项ListBox控件作为查询结果显示的字段名,这将作为如图2 所示的查询结果表格标题。
条件设置控件组由ListBox、ComboBox及CommandButton按钮等组成,完成数据表字段选择、关系运算符选择和条件表达式输入等功能,多个条件无逻辑运算符时默认为"AND"操作,否则使用"OR"按钮插入"OR"操作符。TextBox作为条件表达式输入控件,其中的数据类型(字符、数值、日期型数据)都直接输入,不使用定界符,在程序内部进行数据类型转换处理,这样可避免了不同类型数据的定界符输入。

  2.2 条件输入的制作方法

  查询条件项的操作是输入查询的条件表达式。它应满足字段选择和关系操作运算符选择的灵活性和稳定性,即字段名称应是数据表中的字段名,否则进行查询操作时字段名称可能产生不匹配的问题,因此最好使用下拉列表框来控制。基于同样的理由,关系操作运算符也由下拉列表框来控制。



  图1所示的条件输入控制项由ComboBox、TextBox及CommanButton组成。其中两个ComboBox控件分别用作条件变量的字段名和关系运算符(>、<、=、Like、$等)的选择,TextBox控件用作条件表达式中的数值项的输入。每输入完一个查询条件后,单击"插入"按钮将此条件加入ListBox中,作为ListBox的一行显示,同时,条件输入控制项下移一行,等待下一个条件表达式的输入。为了使ListBox控件的选择、修改、插入和删除等操作更为灵活,使用临时数据表itemadd存放条件表达式,一个条件作为一个记录项,并与ListBox绑定。当条件输入完毕后,若单击窗体其他位置,条件输入控制项将隐藏。若要修改某个条件行时,鼠标点击ListBox的该行,条件输入控制组自动移到当前行显示,等待进行数据修改。该操作通过MOVE方法来实现,以下程序段是插入按钮和删除按钮的代码。

  插入新条件:

select itemadd &&插入一个新条件
insert blank
this.parent.listxztj.setfocus &&设置焦点为ListBox
this.parent.listxztj.selected(curec)=.T. &&在插入记录之后选定ListBox中的该项
topToindex=curec-this.parent.listxztj.topindex
if topToindex<=4 &&4为列表区的行数,如果条件项数在4项内
clisthigh=thisform.clistop+topToindex*thisform.rowleng &&行高
this.parent.listxztj.setfocus
this.parent.comBtjzd.move(36,clisthigh)
this.parent.comnot.move(148,clisthigh)
this.parent.comupdn.move(367,clisthigh)
this.parent.combcondit.move(170,clisthigh)
this.parent.textexam.move(263,clisthigh)
*关闭输入方式
this.parent.comnot.visible=.F. &&隐藏输入条件项
this.parent.comupdn.visible=.F.
this.parent.combcondit.visible=.F.
this.parent.textexam.visible=.F.
else &&条件项数超过4项,使ListBox的滚动条上移一行
this.parent.listxztj.setfocus
this.parent.listxztj.selected(recc("itemadd"))=.T.
keyboard "{dnarrow}"
this.parent.comnot.visible=.F.
this.parent.comupdn.visible=.F.
this.parent.combcondit.visible=.F.
this.parent.textexam.visible=.F.
endif
this.parent.combtjzd.setfocus
  删除按钮的代码如下:

curec=recno("itemadd") &&curec为在ListBox中选择的当前记录号
dele
pack
if recc("itemadd")=0 &&当itemadd库中无记录时
insert blank
this.parent.combtjzd.setfocus
this.parent.listxztj.listindex=recno("itemadd")
this.parent.listxztj.selected(recno("itemadd"))=.T.
return
endif
if curec>recc("itemadd")
go recc("itemadd")
else
go curec
endif
this.parent.listxztj.selected(recno("itemadd"))=.T.
topToindex=recno("itemadd")-this.parent.listxztj.topindex
if topToindex<=4 &&4为列表区的行数
clisthigh=thisform.clistop+topToindex*thisform.rowleng
this.parent.listxztj.setfocus
this.parent.comBtjzd.move(36,clisthigh)
this.parent.comnot.move(148,clisthigh)
this.parent.comupdn.move(367,clisthigh)
this.parent.combcondit.move(170,clisthigh)
this.parent.textexam.move(263,clisthigh)
endif
this.parent.listxztj.listindex=recno("itemadd")
this.parent.listxztj.refresh
this.parent.combtjzd.setfocus

 

2.3 数据类型的匹配问题

  Visual FoxPro中,数据常量依其类型不同而使用不同的定界符。输入时,TextBox必须输入相应的数据类型定界符,否则在查询操作过程中将产生数据类型不匹配的错误而得不到所需要的数据。因此,在查询按钮编写如下程序段对数据类型的匹配问题加以解决。

tjtext=dnam+"."+field(nfield) &&nfield为字段名变量,dnam为数据表
zdtype=type(tjtext) &&求条件字段的数据类型
select itemadd
do case &&对不同的数据类型进行不同处理
case zdtype="C" &&数据为字符型,加上定界符[ ]
if alltrim(itemadd.tj)<>'$'
tjtext=tjtext+" "+alltrim(itemadd.tj)+[ ']+alltrim(itemadd.sl)+[']
else
tjtext=[ ']+alltrim(itemadd.sl)+[']+alltrim(itemadd.tj)+tjtext
endif
case zdtype="D" &&数据类型为日期型,使用ctod()转换为日期型
tjtext=tjtext+alltrim(itemadd.tj)+"CTOD(["+alltrim(itemadd.sl)+"])"
case zdtype="N" &&数据类型为数值型,可直接使用
tjtext=tjtext+alltrim(itemadd.tj)+alltrim(itemadd.sl)
endcase
  程序段中,tjtext为字符表达式,存放多个条件项,在以上程序段未尾的SQL语句中作为操作条件:

select &cxtj from &dnam where &tjtext into table cxtemp

  其操作结果就是依tjtext中的条件表达式来选定的查询结果,cxtj为查询结果中要输出的字段列表,即将选择字段控制项中的被选字段用","连接起来的字符串。cxtemp为存放查询结果的临时表,为数据显示提供数据源。

  2.4 查询结果的显示

  一般用户习惯于使用表格形式来显示数据,因此,在查询到数据结果后,使用Grid控件来显示数据较为合式,如图2所示。若采用前期绑定方式将Grid控件预先设置在form中,由于查询数据结果输出的字段名和字段数的不确定性,致使Grid对表中数据的显示出现数据列宽度的不确定,显示后的数据表格需要调整其宽度才能清楚地浏览到所有信息。所以Grid表格的建立放在数据查询已结果产生,且建立了临时表单cxtemp后,采取后期绑定方式,在程序中添加Grid控件,并设置其宽度、高度、显示方式等属性。选定工作区为cxtemp后添加Grid控件,使Grid控件默认的绑定数据源为cxtemp,程序如下:

select cxtemp &&cxtemp为查询结果临时表,由SQL语句生成
go top
thisform.pagfrcx.activepage=2
thisform.pagfrcx.paglist.addobject('gridcx','grid')
thisform.pagfrcx.paglist.gridcx.visible=.t.
thisform.pagfrcx.paglist.gridcx.left=0
thisform.pagfrcx.paglist.gridcx.top=20
thisform.pagfrcx.paglist.gridcx.width=546
thisform.pagfrcx.paglist.gridcx.height=268
thisform.pagfrcx.paglist.gridcx.deletemark=.F.
thisform.show


  3 结语

  本文详细说明了数据表查询程序设计过程中条件输入控件组的设计、数据类型的匹配问题解决及查询结果的输出设计等方法。这些都是从简化查询操作及提高查询的灵活性等要求为出发点进行的设计。当然本文仅对单表查询进行说明,对于多表查询、分组查询及计算没有说明,若要进行复杂操作,还需做进一步的设计。