Userform Textbox Autocomplete
I’m working on a project where the user types some stuff into a textbox. A good portion of the time, what the user will type will match one of the last few things he typed. I wanted the textbox to autocomplete if there was a match to a list. Pretty simple, I think. For purposes of this demonstration, I’m going to match to a list of random sentences in a listbox.

Private mbEventsDisabled As Boolean
Private Sub TextBox1_Change()
Dim vaRecent As Variant
Dim i As Long
Dim sEntered As String
If Not mbEventsDisabled Then
sEntered = Me.TextBox1.Text
If Len(sEntered) <= 5 Then
vaRecent = Me.ListBox1.List
For i = LBound(vaRecent, 1) To UBound(vaRecent, 1)
If Left$(vaRecent(i, 0), Len(sEntered)) = sEntered Then
mbEventsDisabled = True
With Me.TextBox1
.Text = vaRecent(i, 0)
.SelStart = Len(sEntered)
.SelLength = Len(vaRecent(i, 0))
End With
mbEventsDisabled = False
Exit For
End If
Next i
End If
End If
End Sub
I had to use that old disable events in a userform trick otherwise setting the .Text property would call the change event again.
I only look at the first five characters. After that, you just have to type what you want. If there’s a match, I set the .Text property to the matching sentence and set the selection so that the user can continue typing. It all worked very nicely except for backspacing. In the above screenshot, I’ve typed He but the textbox contains the whole sentence. If I hit backspace in this situation, I delete the highlighted portion and I’m left with He. Backspace does nothing.
I was hoping to find a simple and elegant solution. Instead, I did this.
Private bBackSpace As Boolean
Private mbEventsDisabled As Boolean
Private Sub TextBox1_Change()
Dim vaRecent As Variant
Dim i As Long
Dim sEntered As String
If Not mbEventsDisabled Then
sEntered = Me.TextBox1.Text
If bBackSpace And Len(sEntered) > 0 Then sEntered = Left$(sEntered, Len(sEntered) - 1)
If Len(sEntered) < 5 Then
vaRecent = Me.ListBox1.List
For i = LBound(vaRecent, 1) To UBound(vaRecent, 1)
If Left$(vaRecent(i, 0), Len(sEntered)) = sEntered Then
mbEventsDisabled = True
With Me.TextBox1
.Text = vaRecent(i, 0)
.SelStart = Len(sEntered)
.SelLength = Len(vaRecent(i, 0))
End With
mbEventsDisabled = False
Exit For
End If
Next i
End If
End If
End Sub
Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
bBackSpace = KeyCode = 8
End Sub
I’m using a module-level variable to determine if the backspace was pressed while in the textbox. If it was and there’s still at least one character, I simply shorten the sEntered variable by one character. That leaves the whole SelStart and SelLength mechanism working as expected.





