sirbounty
asked on
auto complete
See the accepted answer here: https://www.experts-exchange.com/questions/21210092/Autofill-combo-box.html
My problem with the solution above is that I need to reference the listindex property of these combo boxes for other processing.
Obviously, if a selection is 'typed' instead of clicked, my listindex remains at -1.
I have 'gotten around' this with some of my smaller cbo's by looping through the list data until there is a match to the database entry and then setting the listindex to that integer's value (x).
Any other ideas on how to accomplish this?
My problem with the solution above is that I need to reference the listindex property of these combo boxes for other processing.
Obviously, if a selection is 'typed' instead of clicked, my listindex remains at -1.
I have 'gotten around' this with some of my smaller cbo's by looping through the list data until there is a match to the database entry and then setting the listindex to that integer's value (x).
Any other ideas on how to accomplish this?
if the function in the previous accepted answer doesn't return the listindex (I didn't have the time to analyze it), then i'd loop through comparing the cbo.text property to the cbo.list property to find my match ...
I grabbed the code from the previous question and stepped through it. The listindex is being set, so I'm not sure what the problem is. In the KeyPress event of the cbo add this line of code
Debug.Print Combo1.ListIndex
immediately after
KeyAscii = AutoMatchCBBox(Combo1, KeyAscii)
and you'll see what I mean.
Debug.Print Combo1.ListIndex
immediately after
KeyAscii = AutoMatchCBBox(Combo1, KeyAscii)
and you'll see what I mean.
ASKER
Hmm - okay, perhaps my problem lies somewhere else....closer look tomorrow (code is at work).
Thanx all
Thanx all
ASKER
This is what I witnessed when typing text in my combo...
keyascii listindex
0 -1 --> I suppose this is when I first entered the box
0 69 --> I hit "r"
0 73 --> then "o"
13 -1 --> then <enter> to select "Rochester, NY" (see listindex got set back to -1... ) : (
You don't see anything in that code that is resetting this do you?
keyascii listindex
0 -1 --> I suppose this is when I first entered the box
0 69 --> I hit "r"
0 73 --> then "o"
13 -1 --> then <enter> to select "Rochester, NY" (see listindex got set back to -1... ) : (
You don't see anything in that code that is resetting this do you?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Azra - you mean in place of the other function I was using? I'll give it a shot...thanx.
ASKER
AzraSound - am I missing LockWindowUpdate?
Replacing this one for the prior doesn't seem to be working... :(
Replacing this one for the prior doesn't seem to be working... :(
How about this used in conjunction with Shauli's code?
Dim lngCurrentComboItem As Long
Private Sub Combo1_KeyPress(KeyAscii As Integer)
KeyAscii = AutoMatchCBBox(Combo1, KeyAscii)
lngCurrentComboItem = IIf(Combo1.ListIndex < 0, lngCurrentComboItem, Combo1.ListIndex)
Debug.Print "Current Item: " & Combo1.List(lngCurrentComb oItem) & " (" & lngCurrentComboItem & ")"
End Sub
Dim lngCurrentComboItem As Long
Private Sub Combo1_KeyPress(KeyAscii As Integer)
KeyAscii = AutoMatchCBBox(Combo1, KeyAscii)
lngCurrentComboItem = IIf(Combo1.ListIndex < 0, lngCurrentComboItem, Combo1.ListIndex)
Debug.Print "Current Item: " & Combo1.List(lngCurrentComb
End Sub
Hi sirbounty
If you need the listindex of the selected item from the combo, then add the following to the module:
In declaration area:
Public LineIndex As Integer
In the AutoMatchCBBox function, Add the marked line in the part of the code as below:
If bContinueSearch Then 'need to search
Call VBComBoBoxDroppedDown(cbBo x) 'open dropdown list
lResult = SendMessage(cbBox.hwnd, CB_SELECTSTRING, -1, ByVal strFindThis)
If lResult = CB_ERR Then 'not found
cbBox.Text = strFindThis 'set cbBox as whatever it is
cbBox.SelLength = 0 'no selected char(s) since not found
cbBox.SelStart = Len(cbBox) 'set insertion position @ the end of string
Else
'found string, highlight rest of string for user
cbBox.SelStart = Len(strFindThis)
cbBox.SelLength = Len(cbBox) - cbBox.SelStart
LineIndex = cbBox.ListIndex '<<<<<<<<<<<<<<<<< this is the listindex of the selected item
End If
End If
So now the listindex of the selected item is in variable LineIndex
Hope this is what you were looking for,
S
If you need the listindex of the selected item from the combo, then add the following to the module:
In declaration area:
Public LineIndex As Integer
In the AutoMatchCBBox function, Add the marked line in the part of the code as below:
If bContinueSearch Then 'need to search
Call VBComBoBoxDroppedDown(cbBo
lResult = SendMessage(cbBox.hwnd, CB_SELECTSTRING, -1, ByVal strFindThis)
If lResult = CB_ERR Then 'not found
cbBox.Text = strFindThis 'set cbBox as whatever it is
cbBox.SelLength = 0 'no selected char(s) since not found
cbBox.SelStart = Len(cbBox) 'set insertion position @ the end of string
Else
'found string, highlight rest of string for user
cbBox.SelStart = Len(strFindThis)
cbBox.SelLength = Len(cbBox) - cbBox.SelStart
LineIndex = cbBox.ListIndex '<<<<<<<<<<<<<<<<< this is the listindex of the selected item
End If
End If
So now the listindex of the selected item is in variable LineIndex
Hope this is what you were looking for,
S
As each valid letter is typed, you might consider the following actions:
1. Set the listindex = first listbox item matching the letters typed so far
2. Set the SelStart and SelLength values such that the remainder of the text will be overwritten with the user's next keystroke.
===============
Alternatively, you might trap the Enter key and set the listindex there, based on the best/first/closest match.
1. Set the listindex = first listbox item matching the letters typed so far
2. Set the SelStart and SelLength values such that the remainder of the text will be overwritten with the user's next keystroke.
===============
Alternatively, you might trap the Enter key and set the listindex there, based on the best/first/closest match.
You'll need this declaration plus any others you don't already have. You should be able to find any of them in your API Viewer:
Public Declare Function LockWindowUpdate Lib "user32" Alias "LockWindowUpdate" (ByVal hwndLock As Long) As Long
Public Declare Function LockWindowUpdate Lib "user32" Alias "LockWindowUpdate" (ByVal hwndLock As Long) As Long
ASKER
Shauli - this appears to be working for me to an extent.
However, I seem to be having a problem passing that value back to the appropriate combo box.
At present, I'm setting listindex to lineindex on cboinfo_lostfocus, but since I'm using control arrays, it's sometimes setting the value on the wrong box...
Private Sub cboInfo_LostFocus(Index As Integer)
cboInfo(Index).ListIndex = LineIndex 'breaking at this point, listindex is still -1 : (
If cboInfo(Index).ListIndex > -1 Then
cboInfo_Click (Index)
End If
End Sub
However, I seem to be having a problem passing that value back to the appropriate combo box.
At present, I'm setting listindex to lineindex on cboinfo_lostfocus, but since I'm using control arrays, it's sometimes setting the value on the wrong box...
Private Sub cboInfo_LostFocus(Index As Integer)
cboInfo(Index).ListIndex = LineIndex 'breaking at this point, listindex is still -1 : (
If cboInfo(Index).ListIndex > -1 Then
cboInfo_Click (Index)
End If
End Sub
You should break it one line down, if you want to see if listindex got the value from lineindex.
LineIndex gets its value the minute the entire line was selected, which means the function found a match in the combo list.
However, if you want, you can set the LineIndex as array, and asign the index to the LineIndex, as in LineIndex(thecomboindex).
S
LineIndex gets its value the minute the entire line was selected, which means the function found a match in the combo list.
However, if you want, you can set the LineIndex as array, and asign the index to the LineIndex, as in LineIndex(thecomboindex).
S
ASKER
Well, that's an idea...perhaps I'll try that.
But I'm baffled as to why listindex is getting 'reset' to -1 in the first place...
Any way I can determine more closely 'when' this is happening? I tried adding a watch, but I don't think it worked...
But I'm baffled as to why listindex is getting 'reset' to -1 in the first place...
Any way I can determine more closely 'when' this is happening? I tried adding a watch, but I don't think it worked...
Well, I'm trying to simulate it, so I put two combos on my form, and played with the autoselect, and put this code also:
Private Sub Combo1_LostFocus(Index As Integer)
Combo1(Index).ListIndex = LineIndex
Label1.Caption = Combo1(Index).ListIndex
End Sub
..and the label always shows the correct ListIndex... :( it looks like something else is affecting it.
S
Private Sub Combo1_LostFocus(Index As Integer)
Combo1(Index).ListIndex = LineIndex
Label1.Caption = Combo1(Index).ListIndex
End Sub
..and the label always shows the correct ListIndex... :( it looks like something else is affecting it.
S
ASKER
Hm...I was afraid you'd say that....<sigh>
Okay - hunt and peck game, here I go... :(
Okay - hunt and peck game, here I go... :(
Are you seeing this behavior with a breakpoint somewhere in your code? If so, you might want to test it as compiled code. Windows messages and events can happen in a different order when debugging.
ASKER
Yep - seeing it even when running a full compile... : (
So, Sir, I think I saw another paq of yours, using the combo in a query or something? If that is why you need the listindex, then why not use the LineIndex var directly where you need the index, instead of the listindex? Especially if you are gonna use an array of those LineIndexes, corresponding to the combo index? Or maybe I'm totally off route hear...
S
S
ASKER
Yeah see - I have these combos that when you 'click' them, they perform other functions/routines...
If I 'type' in them, it appears that listindex isn't set...
If I 'type' in them, it appears that listindex isn't set...
Did you try my routine?
ASKER
I'm sorry AzarSound, I 'tried' to, but I suppose I'm not as familiar with it...perhaps if you could elaborate just a bit?
I'll put it back in (commented out for the moment) and let you know where I'm stuck...
I'll put it back in (commented out for the moment) and let you know where I'm stuck...
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
CB_FINDSTRING - variable not defined...how do I declare this?
Cause if I just put
DIM CB_FINDSTRING
then it won't let me type at all... :(
Cause if I just put
DIM CB_FINDSTRING
then it won't let me type at all... :(
I placed it above. It needs to be public in a bas module with the rest of your API declarations.
ASKER
Ok...brb..
ASKER
This is how I'm currently calling it - could my problem be here?
Private Sub cboInfo_KeyPress(Index As Integer, KeyAscii As Integer)
KeyAscii = ComboAutoComplete(cboInfo( Index), cboInfo(Index).ListIndex)
End Sub
Private Sub cboInfo_KeyPress(Index As Integer, KeyAscii As Integer)
KeyAscii = ComboAutoComplete(cboInfo(
End Sub
ASKER
Hmm...it doesn't seem to be allowing any character input and .text is always = "", thus exiting the function...
You declare a variable, as in my example, which will then hold the listindex once the function returns. Also, this should be called from the Change event. Notice I declared the variable "Dim lngListIndex As Long" in my sample above.
If ComboAutoComplete returns True, then it found a match, and lngListIndex will contain the ListIndex of that match. If ComboAutoComplete returns False, then it did not find a match, so the ListIndex should be -1.
If ComboAutoComplete returns True, then it found a match, and lngListIndex will contain the ListIndex of that match. If ComboAutoComplete returns False, then it did not find a match, so the ListIndex should be -1.
ASKER
Okay, some of it is working now...but here's where it's not working...
In my 'small' combos - where the first char would not likely be duplicated in the list, it automatically chooses the correct item.
However in my Office Locations combo, If I want to select Windsor, I type "W" and Waltham is displayed, then I type "i" and Iselin, NJ is displayed, then "n", Nashville, TN, etc...
I suppose it's workable in this manner, but I would rather it bring up the first match and then continue on as each subsequent character is typed...is this possible?
In my 'small' combos - where the first char would not likely be duplicated in the list, it automatically chooses the correct item.
However in my Office Locations combo, If I want to select Windsor, I type "W" and Waltham is displayed, then I type "i" and Iselin, NJ is displayed, then "n", Nashville, TN, etc...
I suppose it's workable in this manner, but I would rather it bring up the first match and then continue on as each subsequent character is typed...is this possible?
ASKER
Oh, and thanx again for all your help! : )
>>I suppose it's workable in this manner, but I would rather it bring up the first match and then continue on as each subsequent character is typed...is this possible?
That's how it should work. How are you using it right now? The way you describe it working is exactly how a combobox behaves when its style is set to DropDown List.
That's how it should work. How are you using it right now? The way you describe it working is exactly how a combobox behaves when its style is set to DropDown List.
ASKER
Firstly, style is dropdown combo - I may need to change that, and I think I do, cause I'm not trapping that as a problem right now...good point.
But, when I used Shauli's code from before, it would react this way:
Type in "W" and a highlighted Waltham, MA would be shown, then type "i" and "Windsor" would be displayed - but on second thought, I've recently removed tabstops, so the user can't 'tab' out to select this, so I think your solution is the one that I will use.
Thanx for your efforts AND patience Azra!
But, when I used Shauli's code from before, it would react this way:
Type in "W" and a highlighted Waltham, MA would be shown, then type "i" and "Windsor" would be displayed - but on second thought, I've recently removed tabstops, so the user can't 'tab' out to select this, so I think your solution is the one that I will use.
Thanx for your efforts AND patience Azra!
>>I may need to change that, and I think I do
Maybe not. This style essentially means a user cannot type in the combobox. AutoComplete functions will not work with this style. However, this style does require a user pick an item from the list.
My code should do the same...matching words using all the letters typed thus far, which is why I ask how you are using it because there may be some changes that need to be made.
Maybe not. This style essentially means a user cannot type in the combobox. AutoComplete functions will not work with this style. However, this style does require a user pick an item from the list.
My code should do the same...matching words using all the letters typed thus far, which is why I ask how you are using it because there may be some changes that need to be made.
ASKER
Ok - well ultimately (poor planning on my part I suppose) I wouldn't "want" them typing their own item in 'most' of the combos...
So, I should make these all dropdown list styles - would you agree?
And then the one or two that I could allow them to type - leave that at dropdown combo...I'll make the change and see where that takes me.
I'll also go ahead and close this and just post a link to a new Q if I need more help...
So, I should make these all dropdown list styles - would you agree?
And then the one or two that I could allow them to type - leave that at dropdown combo...I'll make the change and see where that takes me.
I'll also go ahead and close this and just post a link to a new Q if I need more help...
>>So, I should make these all dropdown list styles - would you agree?
Yes, that would make it automatic. However, if you have combos with thousands of items, it can be difficult for a user to scroll and find what they are looking for, in which case an auto complete feature can be of use.
Yes, that would make it automatic. However, if you have combos with thousands of items, it can be difficult for a user to scroll and find what they are looking for, in which case an auto complete feature can be of use.
ASKER
Okay - all but one (because I have different functions for it) are set to style 2...
The most items in a list, would be my office locations - probably only about 90-100.
But this still only seems to allow selection for the first item in the corresponding list of matches (to the first letter in the item)..hope that makes sense...
The most items in a list, would be my office locations - probably only about 90-100.
But this still only seems to allow selection for the first item in the corresponding list of matches (to the first letter in the item)..hope that makes sense...
Can you post the code for that combo that is giving you problems?
ASKER
Hmm...that's a lot of code...let me try this function on a fresh combo and I'll post the results...
ASKER
Must be something I'm doing then...Combo1 displays the same results...
Is it pehaps the way I'm using it? I 'assumed' that I should set the listindex to lnglistindex...perhaps not?
If ComboAutoComplete(cboInfo( Index), lngListIndex) = True Then
cboInfo(Index).ListIndex = lngListIndex
'lngListIndex contains the current ListIndex of the displayed item
End If
Is it pehaps the way I'm using it? I 'assumed' that I should set the listindex to lnglistindex...perhaps not?
If ComboAutoComplete(cboInfo(
cboInfo(Index).ListIndex = lngListIndex
'lngListIndex contains the current ListIndex of the displayed item
End If
>>I 'assumed' that I should set the listindex to lnglistindex...perhaps not?
No, you don't need to do that. The listindex is returned for your benefit only as it may apply to other things. Otherwise, the function should handle everything else including partial highlighting and selecting the most appopriate item in the list.
No, you don't need to do that. The listindex is returned for your benefit only as it may apply to other things. Otherwise, the function should handle everything else including partial highlighting and selecting the most appopriate item in the list.
ASKER
So, it should just read:
If ComboAutoComplete(cboInfo( Index), lngListIndex) = True Then
End If
??
My 'dummy' combo has:
Cat
Catastrophe
Catatonic
I can't get to the latter two without 'arrowing' down to them, cause as soon as I hit the 'a', it goes back to Apple...but you're saying it should show the others?
If ComboAutoComplete(cboInfo(
End If
??
My 'dummy' combo has:
Cat
Catastrophe
Catatonic
I can't get to the latter two without 'arrowing' down to them, cause as soon as I hit the 'a', it goes back to Apple...but you're saying it should show the others?
This should work:
Private Sub Combo1_Change()
Dim lngListIndex As Long
Call ComboAutoComplete(Combo1, lngListIndex)
End Sub
Private Sub Form_Load()
Combo1.AddItem "Cat"
Combo1.AddItem "Catastrophe"
Combo1.AddItem "Catatonic"
End Sub
Private Sub Combo1_Change()
Dim lngListIndex As Long
Call ComboAutoComplete(Combo1, lngListIndex)
End Sub
Private Sub Form_Load()
Combo1.AddItem "Cat"
Combo1.AddItem "Catastrophe"
Combo1.AddItem "Catatonic"
End Sub
ASKER
Okay - it's something else, because I created a new project and it works as it should...
I'm going to open a new question to see if you and/or anyone else can help me track down what's causing this not work... :(
I'm going to open a new question to see if you and/or anyone else can help me track down what's causing this not work... :(
ASKER
here's another weird thing...for combo1 - if I place a break on combo1_change, and I 'type' in that box, it doesn't stop there....only combo1_click (which I added after)...strange?
ASKER
AzraSound - would you mind helping me with this again? If you're around...
New program - same routine...can't get it working right.
http:Visual_Basic/Q_21273233.html
New program - same routine...can't get it working right.
http:Visual_Basic/Q_21273233.html
ASKER
Sometimes it just helps to post a question...I've got it...well, sort of - about 95% of the way there...
: )
: )
:-)
I came back from lunch and noticed the question was gone. Glad to see you got it straightened out.
I came back from lunch and noticed the question was gone. Glad to see you got it straightened out.
ASKER
Well...sort of...
Still one minor issue.
The new app has similiar two drop-downs for Category & Subcategory.
If a certain Subcat is chosen, a customer dropdown is displayed.
If that dropdown is not displayed, my code sets the focus on the first time-entry (date/time control).
If the customer field is shown, it appears the 'nothing' gets the focus...not sure why.
If I'm still stuck on it tomorrow - I'll post another question for you...thanx for all your help!
Still one minor issue.
The new app has similiar two drop-downs for Category & Subcategory.
If a certain Subcat is chosen, a customer dropdown is displayed.
If that dropdown is not displayed, my code sets the focus on the first time-entry (date/time control).
If the customer field is shown, it appears the 'nothing' gets the focus...not sure why.
If I'm still stuck on it tomorrow - I'll post another question for you...thanx for all your help!