电竞比分网-中国电竞赛事及体育赛事平台

分享

VFP中多條件數(shù)據(jù)查詢程序的實(shí)現(xiàn)

 悟靜 2009-04-25
摘要:本文通過(guò)具體的實(shí)例,介紹了多條件數(shù)據(jù)查詢的設(shè)計(jì)方法,提供了用于條件輸入控件的控制和數(shù)據(jù)類型匹配的解決方案。

  關(guān)鍵詞:數(shù)據(jù)庫(kù),多條件查詢,數(shù)據(jù)匹配
  數(shù)據(jù)查詢是用戶使用各種軟件來(lái)管理數(shù)據(jù)的目的之一,也是各種數(shù)據(jù)庫(kù)程序設(shè)計(jì)的重點(diǎn)。用戶希望能方便有效快速地找到他們所需的信息,為各種事務(wù)處理提供有力的支持。所以,數(shù)據(jù)查詢作為信息管理軟件設(shè)計(jì)中要實(shí)現(xiàn)的一項(xiàng)重要功能,必須具有良好的數(shù)據(jù)界面和方便的操作及靈活的查詢功能,這也是信息管理軟件開(kāi)發(fā)人員所追求的目標(biāo)。

  1 用VFP系統(tǒng)命令進(jìn)行查詢操作的不便之處

  在Visual FoxPro數(shù)據(jù)管理系統(tǒng)中,設(shè)置了查詢命令和查詢向?qū)?,可以進(jìn)行數(shù)據(jù)庫(kù)表記錄的選擇、分組查詢、多表查詢及查詢結(jié)果數(shù)據(jù)的輸出等功能,能夠產(chǎn)生獨(dú)立的查詢文件,通過(guò)調(diào)用該文件可得到所需要的數(shù)據(jù)。但這些分散的功能命令和文件不適用于數(shù)據(jù)庫(kù)應(yīng)用程序的查詢操作,使用這種方式設(shè)計(jì)的數(shù)據(jù)庫(kù)應(yīng)用程序,用戶必須熟知VFP系統(tǒng)命令、操作、數(shù)據(jù)類型的匹配方式及各種數(shù)據(jù)表之間的關(guān)系才能有效的查詢到自己所需的信息,這給用戶進(jìn)行數(shù)據(jù)查詢操作帶來(lái)極大的不便。如果能把數(shù)據(jù)庫(kù)表文件的選擇、查詢結(jié)果輸出字段的選定、不定數(shù)量查詢條件的輸入、條件表達(dá)式中數(shù)據(jù)類型的匹配及查詢結(jié)果的輸出等操作容為一體,設(shè)計(jì)在一個(gè)查詢程序中,則查詢操作將變得非常方便靈活而且簡(jiǎn)單。

  2 查詢程序的設(shè)計(jì)

  為了使查詢程序具有良好的交互功能和方便操作,可使用如圖1所示操作界面。在此查詢程序中,查詢操作只需要在窗口提供的數(shù)據(jù)庫(kù)表中選擇所要查詢的數(shù)據(jù)表,在選擇字段項(xiàng)的列表框中選定要顯示的數(shù)據(jù)字段,在選擇條件項(xiàng)中設(shè)置查詢的數(shù)據(jù)條件,最后點(diǎn)擊查詢按鈕,則查詢結(jié)果數(shù)據(jù)將按圖2所示的表格列出。其中,圖1 中選定的字段將作為圖2 中的表格標(biāo)題,圖2表格中的數(shù)據(jù)為圖1選定的數(shù)據(jù)表中符合條件的數(shù)據(jù)記錄。圖1中輸入的條件為:來(lái)款日期為1999年10月以后且來(lái)款單位含有"寶鋼"的記錄,并在圖2的表中顯示出來(lái)款日期、來(lái)款單位、來(lái)款數(shù)和室別。

  2.1 控件設(shè)置

  在圖1所示查詢窗體上設(shè)置Option控件、ListBox控件組、條件設(shè)置控件組。

  Option控件用于選擇當(dāng)前所要查詢的數(shù)據(jù)庫(kù)表。

  ListBox控件組分別用于源數(shù)據(jù)表的字段列表和被選擇字段名列表。選擇項(xiàng)ListBox控件作為查詢數(shù)據(jù)表中的字段名,被選項(xiàng)ListBox控件作為查詢結(jié)果顯示的字段名,這將作為如圖2 所示的查詢結(jié)果表格標(biāo)題。
條件設(shè)置控件組由ListBox、ComboBox及CommandButton按鈕等組成,完成數(shù)據(jù)表字段選擇、關(guān)系運(yùn)算符選擇和條件表達(dá)式輸入等功能,多個(gè)條件無(wú)邏輯運(yùn)算符時(shí)默認(rèn)為"AND"操作,否則使用"OR"按鈕插入"OR"操作符。TextBox作為條件表達(dá)式輸入控件,其中的數(shù)據(jù)類型(字符、數(shù)值、日期型數(shù)據(jù))都直接輸入,不使用定界符,在程序內(nèi)部進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換處理,這樣可避免了不同類型數(shù)據(jù)的定界符輸入。

  2.2 條件輸入的制作方法

  查詢條件項(xiàng)的操作是輸入查詢的條件表達(dá)式。它應(yīng)滿足字段選擇和關(guān)系操作運(yùn)算符選擇的靈活性和穩(wěn)定性,即字段名稱應(yīng)是數(shù)據(jù)表中的字段名,否則進(jìn)行查詢操作時(shí)字段名稱可能產(chǎn)生不匹配的問(wèn)題,因此最好使用下拉列表框來(lái)控制。基于同樣的理由,關(guān)系操作運(yùn)算符也由下拉列表框來(lái)控制。



  圖1所示的條件輸入控制項(xiàng)由ComboBox、TextBox及CommanButton組成。其中兩個(gè)ComboBox控件分別用作條件變量的字段名和關(guān)系運(yùn)算符(>、<、=、Like、$等)的選擇,TextBox控件用作條件表達(dá)式中的數(shù)值項(xiàng)的輸入。每輸入完一個(gè)查詢條件后,單擊"插入"按鈕將此條件加入ListBox中,作為L(zhǎng)istBox的一行顯示,同時(shí),條件輸入控制項(xiàng)下移一行,等待下一個(gè)條件表達(dá)式的輸入。為了使ListBox控件的選擇、修改、插入和刪除等操作更為靈活,使用臨時(shí)數(shù)據(jù)表itemadd存放條件表達(dá)式,一個(gè)條件作為一個(gè)記錄項(xiàng),并與ListBox綁定。當(dāng)條件輸入完畢后,若單擊窗體其他位置,條件輸入控制項(xiàng)將隱藏。若要修改某個(gè)條件行時(shí),鼠標(biāo)點(diǎn)擊ListBox的該行,條件輸入控制組自動(dòng)移到當(dāng)前行顯示,等待進(jìn)行數(shù)據(jù)修改。該操作通過(guò)MOVE方法來(lái)實(shí)現(xiàn),以下程序段是插入按鈕和刪除按鈕的代碼。

  插入新條件:

select itemadd &&插入一個(gè)新條件
insert blank
this.parent.listxztj.setfocus &&設(shè)置焦點(diǎn)為L(zhǎng)istBox
this.parent.listxztj.selected(curec)=.T. &&在插入記錄之后選定ListBox中的該項(xiàng)
topToindex=curec-this.parent.listxztj.topindex
if topToindex<=4 &&4為列表區(qū)的行數(shù),如果條件項(xiàng)數(shù)在4項(xiàng)內(nèi)
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)
*關(guān)閉輸入方式
this.parent.comnot.visible=.F. &&隱藏輸入條件項(xiàng)
this.parent.comupdn.visible=.F.
this.parent.combcondit.visible=.F.
this.parent.textexam.visible=.F.
else &&條件項(xiàng)數(shù)超過(guò)4項(xiàng),使ListBox的滾動(dòng)條上移一行
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中選擇的當(dāng)前記錄號(hào)
dele
pack
if recc("itemadd")=0 &&當(dāng)itemadd庫(kù)中無(wú)記錄時(shí)
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為列表區(qū)的行數(shù)
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 數(shù)據(jù)類型的匹配問(wèn)題

  Visual FoxPro中,數(shù)據(jù)常量依其類型不同而使用不同的定界符。輸入時(shí),TextBox必須輸入相應(yīng)的數(shù)據(jù)類型定界符,否則在查詢操作過(guò)程中將產(chǎn)生數(shù)據(jù)類型不匹配的錯(cuò)誤而得不到所需要的數(shù)據(jù)。因此,在查詢按鈕編寫(xiě)如下程序段對(duì)數(shù)據(jù)類型的匹配問(wèn)題加以解決。

tjtext=dnam+"."+field(nfield) &&nfield為字段名變量,dnam為數(shù)據(jù)表
zdtype=type(tjtext) &&求條件字段的數(shù)據(jù)類型
select itemadd
do case &&對(duì)不同的數(shù)據(jù)類型進(jìn)行不同處理
case zdtype="C" &&數(shù)據(jù)為字符型,加上定界符[ ]
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" &&數(shù)據(jù)類型為日期型,使用ctod()轉(zhuǎn)換為日期型
tjtext=tjtext+alltrim(itemadd.tj)+"CTOD(["+alltrim(itemadd.sl)+"])"
case zdtype="N" &&數(shù)據(jù)類型為數(shù)值型,可直接使用
tjtext=tjtext+alltrim(itemadd.tj)+alltrim(itemadd.sl)
endcase

  程序段中,tjtext為字符表達(dá)式,存放多個(gè)條件項(xiàng),在以上程序段未尾的SQL語(yǔ)句中作為操作條件:

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

  其操作結(jié)果就是依tjtext中的條件表達(dá)式來(lái)選定的查詢結(jié)果,cxtj為查詢結(jié)果中要輸出的字段列表,即將選擇字段控制項(xiàng)中的被選字段用","連接起來(lái)的字符串。cxtemp為存放查詢結(jié)果的臨時(shí)表,為數(shù)據(jù)顯示提供數(shù)據(jù)源。

  2.4 查詢結(jié)果的顯示

  一般用戶習(xí)慣于使用表格形式來(lái)顯示數(shù)據(jù),因此,在查詢到數(shù)據(jù)結(jié)果后,使用Grid控件來(lái)顯示數(shù)據(jù)較為合式,如圖2所示。若采用前期綁定方式將Grid控件預(yù)先設(shè)置在form中,由于查詢數(shù)據(jù)結(jié)果輸出的字段名和字段數(shù)的不確定性,致使Grid對(duì)表中數(shù)據(jù)的顯示出現(xiàn)數(shù)據(jù)列寬度的不確定,顯示后的數(shù)據(jù)表格需要調(diào)整其寬度才能清楚地瀏覽到所有信息。所以Grid表格的建立放在數(shù)據(jù)查詢已結(jié)果產(chǎn)生,且建立了臨時(shí)表單cxtemp后,采取后期綁定方式,在程序中添加Grid控件,并設(shè)置其寬度、高度、顯示方式等屬性。選定工作區(qū)為cxtemp后添加Grid控件,使Grid控件默認(rèn)的綁定數(shù)據(jù)源為cxtemp,程序如下:

select cxtemp &&cxtemp為查詢結(jié)果臨時(shí)表,由SQL語(yǔ)句生成
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 結(jié)語(yǔ)

  本文詳細(xì)說(shuō)明了數(shù)據(jù)表查詢程序設(shè)計(jì)過(guò)程中條件輸入控件組的設(shè)計(jì)、數(shù)據(jù)類型的匹配問(wèn)題解決及查詢結(jié)果的輸出設(shè)計(jì)等方法。這些都是從簡(jiǎn)化查詢操作及提高查詢的靈活性等要求為出發(fā)點(diǎn)進(jìn)行的設(shè)計(jì)。當(dāng)然本文僅對(duì)單表查詢進(jìn)行說(shuō)明,對(duì)于多表查詢、分組查詢及計(jì)算沒(méi)有說(shuō)明,若要進(jìn)行復(fù)雜操作,還需做進(jìn)一步的設(shè)計(jì)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多