VFP 愛用者社區 首頁 VFP 愛用者社區
本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.
 
 常見問題常見問題   搜尋搜尋   會員列表會員列表   會員群組會員群組   會員註冊會員註冊 
 個人資料個人資料   登入檢查您的私人訊息登入檢查您的私人訊息   登入登入

如何在文本框中實現遞增搜索(轉貼)

 
發表新主題   回覆主題    VFP 愛用者社區 首頁 -> VFP 討論區
上一篇主題 :: 下一篇主題  
發表人 內容
Ruey



註冊時間: 2003-03-12
文章: 1698
來自: tunglo

第 1 樓

發表發表於: 星期四 十一月 20, 2003 10:25 am    文章主題: 如何在文本框中實現遞增搜索(轉貼) 引言回覆

如何在文本框中實現遞增搜索
( 作者: 不詳 )


最後更新日期: April 4, 1997

文號: Q166378

本文資訊適用於:
Microsoft Visual FoxPro for Windows, versions 5.0, 5.0a

概述
下拉式列示方塊具有遞增搜索屬性, 當設置爲 .T. 時, 用各擊鍵搜索下拉式列示方塊的 Control Source. 因此, 如果用戶打入字串 "ABC", 將會在各擊鍵後搜索表, 首先搜索字母 "A", 然後搜索串 "AB", 最後是串 "ABC".

雖然這是一個非常有用的屬性, 搜索的實情是由行動觸發,而不是無行動引發的用戶介面問題--用戶可能不想象他們輸入串一樣搜索串中的字母, 而寧願在整個串都輸入完後搜索整個串. 文本框沒有遞增搜索屬性, 但可以類比該動作, 並在用戶停止輸入後執行搜索, 而不是在用戶正在輸入時.

本文中的代碼創建一個實現了遞增搜索的, 完全的可編輯文本框. 使用一個計時器, 當用戶在一個指定的時間段中沒有按鍵時遞增搜索被觸發.


更多資訊
創建一個新表單, 並從 Samples 目錄下的 Testdata 資料庫中添加 Customer 表到資料環境. 拖動表到表單上創建一個表格. 向表單添加三個自定義屬性: PREVAL, TICKCOUNT 和 HOLDVALUE. 修改 PREVAL 和 HOLDVALUE 的預設值爲空格. 修改 TICKCOUNT 的預設值爲 0.

向表單添加一個名爲 SearchVal 的自定義方法. 添加以下代碼到該方法中:


* 僅在文本框中的值改變時才 seek
IF !(THIS.PREVAL == ALLTRIM(THIS.TEXT1.VALUE))

* 設置早期的值爲當前值
THIS.PREVAL = ALLTRIM(THIS.TEXT1.VALUE)

* Seek 文本值
GO TOP
SEEK THIS.PREVAL

IF FOUND()
* 自定義屬性 holdvalue 用於保存用戶輸入的串.
THISFORM.HOLDVALUE = THIS.PREVAL

* 這設置焦點到表格因此定位的記錄顯示在表格中並且
* RecordMark 是打開的
THISFORM.GRID1.SETFOCUS

* 直接重置焦點到文本框
THIS.TEXT1.SETFOCUS
THIS.TEXT1.VALUE = THISFORM.HOLDVALUE
THIS.TEXT1.SELSTART = LEN(THISFORM.HOLDVALUE)
ENDIF
ENDIF



添加一個計時器到表單, 並設置 Interval 屬性值爲 50. 在計時器控制項的 Timer 事件中添加以下代碼:


THIS.PARENT.TICKCOUNT = THIS.PARENT.TICKCOUNT + 1

IF THIS.PARENT.TICKCOUNT >= 20
THIS.PARENT.TICKCOUNT = 0
THIS.PARENT.SEARCHVAL()
ENDIF



添加一個文本框到表單中. 不要爲它指定 control source. 在表單的 Load 事件中, 輸入以下命令:


SET ORDER TO CUST_ID && 或其他的 cust_id 欄位的索引標識名.



添加以下代碼到文本框的 KeyPress 事件中:


LPARAMETERS nKeyCode, nShiftAltCtrl

* 注意: The SHIFT-方向鍵高亮工作, 介不標準.
* 例如, SHIFT-左箭頭高亮三個右邊的字元, 然後按下右箭頭鍵, 只會
* 增加當前位置一. 在許多編輯器中, 這樣做
* 增加當前位置四. 但是 ,爲了類比該行爲, 需要保存最後的按鍵到一個變數中,
* 然後檢查它來找出最後移動的方向, 然後進行一個計算處理...
* 但這種努力看來似乎沒什麽價值.

LOCAL nPos, nLen, nSel

nPos = THIS.SELSTART && 當前游標位置
nLen = LEN(ALLTRIM(THIS.VALUE)) && 文本框中的文本長度
nSel = THIS.SELLENGTH && 選定的字元數

THIS.PARENT.TICKCOUNT = 0

* 關閉 Keypress 事件中的所有默認處理;
* 要用代碼來處理, 這是必須的
NODEFAULT

DO CASE
* 檢查/捕捉 nKeycode >= 65, <= 122 (限制輸入爲字母
* nKeycode = 32 (允許空格). 要允許
* 輸入數位或其他字元,
* 參考幫助文件中的 INKEY() 主題
* 39 是單引號
CASE (nKeyCode >= 65 AND nKeyCode <= 122) OR nKeyCode = 32;
OR nKeyCode = 44 OR nKeyCode = 45 OR nKeyCode = 39

* 插入新的字元在右邊
THIS.VALUE = UPPER(LEFT(THIS.VALUE, nPos) + ;
CHR(nKeyCode) + RIGHT(THIS.VALUE,;
nLen - (nPos + nSel)))

* 增加我們的位置變數, 這樣我們在後面放入一個新字母
nPos = nPos + 1
nSel = 0

* 檢查/捕捉 SHIFT-左箭頭組合 (左高亮度)
CASE nKeyCode = 52
* 向左邊移動一位, 選定數量加一
IF nPos > 0
nPos = nPos - 1
nSel = nSel + 1
ENDIF

* 檢查/捕捉 SHIFT-右箭頭組合 (右高亮度)
CASE nKeyCode = 54
* 增加選定數一, 如果有更多的選定
IF (nPos + nSel) < nLen
nSel = nSel + 1
ENDIF

* 檢查/捕捉 SHIFT-HOME 組合 (左結束高亮)
CASE nKeyCode = 55
* Set the number of characters selected to the number of
* characters between our current position and the start
* position, then move to the start position
nSel = nSel + nPos
nPos = 0

* 檢查/捕捉 SHIFT-END (右結束高亮)
CASE nKeyCode = 49
* Set the number of characters selected to the number to
* the right of our current position
nSel = nLen - nPos

* 檢查/捕捉 LEFT-ARROW
CASE nKeyCode = 19
* Deselect any selected characters
nSel = 0

* Move left one
IF nPos > 0
nPos = nPos - 1
ENDIF

* 檢查/捕捉 RIGHT-ARROW
CASE nKeyCode = 4
* Deselect any selected characters
nSel = 0

* Move right one
IF nPos < nLen
nPos = nPos + 1
ENDIF

* 檢查/捕捉 HOME
CASE nKeyCode = 1
* Deselect any selected characters
nSel = 0

* Move to the start
nPos = 0

* 檢查/捕捉 END
CASE nKeyCode = 6
* Deselect any selected characters
nSel = 0

* Move to the end
nPos = nLen

* 檢查/捕捉 DELETE
CASE nKeyCode = 7
* If we have not 'highlighted' the letter we want to delete,
* the count of letters to delete will be zero, so we have
* to manually set the letter to remove
IF nSel = 0
nSel = 1
ENDIF

* Rebuild the string without the deleted character(s)
THIS.VALUE = LEFT(THIS.VALUE, nPos) + ;
RIGHT(THIS.VALUE, nLen - (nPos + nSel))

* Deselect any selected characters
nSel = 0

* 檢查/捕捉 BACKSPACE
CASE nKeycode = 127
* If no letters are 'highlighted', just delete the one
* before the cursor and
* move the cursor back one
IF nSel = 0
IF nPos > 0
THIS.VALUE = LEFT(THIS.VALUE, nPos - 1) + ;
RIGHT(THIS.VALUE, nLen - nPos)
nPos = nPos - 1
ENDIF

* If letters are highlighted, remove the block of
* highlighted letters, and don't move the cursor
* (just like hitting DELETE)
ELSE
THIS.VALUE = LEFT(THIS.VALUE, nPos) + ;
RIGHT(THIS.VALUE, nLen - (nPos + nSel))
ENDIF

* Deselect any selected characters
nSel = 0

ENDCASE

* Get rid of whitespace at the end of the entered word
IF nLen != LEN(ALLTRIM(THIS.VALUE))
THIS.MAXLENGTH = LEN(ALLTRIM(THIS.VALUE)) + 1
ENDIF

* This moves the cursor to the current position in the string in the
* text box
THIS.SELSTART = nPos

* And this selects the proper number of characters
THIS.SELLENGTH = nSel


保存並運行表單. 在文本框中打入要查找的欄位. 在短暫的停留後, 任何匹配的欄位將被定位且在表格中顯示出來. 用不同的時間間隔試驗, 直到你找到一個你覺得滿意的值.

一般注意
在該示例中, 假定文本框名爲 Text1. 如果文本框的不同, 修改代碼中的有關部分.
NODEFAULT 命令關閉 KeyPress 事件所有的默認處理, 並允許代碼完全控制按鍵處理. 該命令是必須的.
正象在注釋中注明, 修改模仿並不完美, 但它已經相當接近目的了.

_________________
#############################
快樂媽咪系列幸福宅配,喝十全雞湯~原來幸福那麼簡單!!

學會VFP使用者社區的搜尋,Code才會更有趣~
#############################
回頂端
檢視會員個人資料 發送私人訊息
從之前的文章開始顯示:   
發表新主題   回覆主題    VFP 愛用者社區 首頁 -> VFP 討論區 所有的時間均為 台北時間 (GMT + 8 小時)
1頁(共1頁)

 
前往:  
無法 在這個版面發表文章
無法 在這個版面回覆文章
無法 在這個版面編輯文章
無法 在這個版面刪除文章
無法 在這個版面進行投票
無法 在這個版面附加檔案
無法 在這個版面下載檔案


Powered by phpBB © 2001, 2005 phpBB Group
正體中文語系由 phpbb-tw 維護製作