This is crude when compared to Jim's example and is also much more data dependent but it illustrates another approach. The basic idea is to narrow a data search using a pre-built index. In the example data is extracted from a larger file and the index is created on the fly to make it 'copy-and-pasteable' from the forum. These tasks could be done before hand and the dialog script would then only need to load the data and keys from files.
;;============================================================
;; Data dependent processing of a flat file containing
;; known items already is sort order.
;;
;; This example uses a one character key array but the length
;; can be adjusted to match the data for best performance.
aRaw = ArrayFileGet( DirHome():"wil.aqh" )
nMaxRaw = ArrInfo(aRaw, 1) -1
nMaxData = nMaxRaw/3
aData = ArrDimension(nMaxData+1)
aKey = ArrDimension(27,2)
;; Set first key array element
aKey[0,0] = StrUpper(StrSub(aRaw[0],1,1))
aKey[0,1] = 0
nMaxKey = 0
nIndex = 0
;; Extract the sorted data from the raw input file
;; and build a first character key array based
;; on the extracted data.
for i = 0 to nMaxRaw by 3
aData[nIndex] = aRaw[i]
strFirst = StrUpper(StrSub(aData[nIndex],1,1))
if strFirst != aKey[nMaxKey,0]
nMaxKey += 1
aKey[nMaxKey,0] = strFirst
aKey[nMaxKey,1] = nIndex
endif
nIndex += 1
next
; End of data key row.
nMaxKey += 1
aKey[nMaxKey, 0] = '[' ; First character past 'Z' (maintains sort order for searching)
aKey[nMaxKey, 1] = nMaxData
if nMaxKey < 26 then ArrayRedim(aKey, nMaxKey+1, 2) ; Remove blank elements to aid binary searching.
;; Initialize the ITEMBOX Variable.
ibVariable1 = ArrayItemize(aData)
;; Callback that implements a kind of autocomplete functionality.
#DefineSubroutine AutoComExCb(AutoComEx_Handle,AutoComEx_Event,AutoComEx_Name,AutoComEx_EventInfo,AutoComEx_ChangeInfo)
switch AutoComEx_Event ; Switch based on Dialog Message type
case @deInit ; Standard Initialization message
DialogProcOptions(AutoComEx_Handle,@deEdText,@TRUE)
DialogProcOptions(AutoComEx_Handle,@deIbSelect,@TRUE)
return(@retDefault)
case @deEdText ; ID "EditBox_1" ebVariable1 Edit 1
strUser = StrTrim(DialogControlGet(AutoComEx_Handle, "EditBox_1", @dcText))
;; Find the starting and ending data array indices.
nKey = Arraysearch(aKey,StrUpper(StrSub(strUser,1,1)),@Stringsort)
if nKey >= 0 && nKey < nMaxKey
nUser = StrLen(strUser)
nLast = aKey[nKey+1, 1] - 1
;; Find the first data array element that matches to the end of the user input.
for i = aKey[nKey, 1] to nLast
if Stricmp(strUser, StrSub(aData[i], 1, nUser)) == 0
;; Scroll the first matching data element to the top of the ITEMBOX.
;; Many other things could be done here. For example, displaying
;; only matching items and resizing to match the number of items
;; in the partial list.
DialogControlSet(AutoComEx_Handle, "ItemBox_1", @dcScroll, i+1)
break
endif
next
endif
return(@retDefault)
case @deIbSelect ; ID "ItemBox_1" ibVariable1
; Process selection here.
return(@retDefault)
endswitch ; AutoComEx_Event
return(@retDefault)
#EndSubroutine ; End of Dialog Callback AutoComExCallbackProc
AutoComExFormat=`WWWDLGED,6.2`
AutoComExCaption=`AutoCompleteEx`
AutoComExX=181
AutoComExY=126
AutoComExWidth=210
AutoComExHeight=160
AutoComExNumControls=004
AutoComExProcedure=`AutoComExCb`
AutoComExFont=`DEFAULT`
AutoComExTextColor=`DEFAULT`
AutoComExBackground=`DEFAULT,DEFAULT`
AutoComExConfig=0
AutoComEx001=`057,145,032,010,PUSHBUTTON,"PushButton_OK",DEFAULT,"OK",1,10,@csDefButton,DEFAULT,DEFAULT,DEFAULT`
AutoComEx002=`133,145,034,010,PUSHBUTTON,"PushButton_Cancel",DEFAULT,"Cancel",0,20,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
AutoComEx003=`095,013,088,122,ITEMBOX,"ItemBox_1",ibVariable1,DEFAULT,DEFAULT,30,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
AutoComEx004=`011,015,066,014,EDITBOX,"EditBox_1",ebVariable1,DEFAULT,DEFAULT,40,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
ButtonPushed=Dialog("AutoComEx")