How do I capture the value being typed into a MS Access Form's textBox control as it's being edited? I'd like to show results of a search (in a listbox) that's updated with each new character added to the textBox used for the search? The query is in place, the events are in place, the only thing that's missing is where is the typed value stored, because it's not in the control's .Value property during "typing" events.
-
2I am wondering what is the reason you choose to have the separate TextBox. Couldn't you use only Combo as I use all the time? See here https://stackoverflow.com/a/59990955/7526564 – Vlado Jan 31 '20 at 14:16
-
Well, it's not an appropriate display scenario for a combo box -- sorry, I didn't give enough information in the question. The approved answer is useful and answers the basic question, but it didn't apply to my situation. I needed to display many multi-columned rows based on entry (results were ListBox shaped, so to speak) and the use scenario was one of review in general. It isn't an autocomplete situation, it's an active filtering of results situation. Again, I did a poor job of fleshing out the situation in my question. I did use a combo box as you describe elsewhere in the app. – Matt Murphy Feb 01 '20 at 22:06
-
Actually, I like your programatic approach better than the one I took on my combo boxes. Nice! – Matt Murphy Feb 01 '20 at 22:12
2 Answers
The key to achieving this is using the OnChange
event of the text box, which fires for every keystroke which changes the content of the text box.
As such, you can easily change the content of the list box by referencing the Text
property of the text box within the event handler for the OnChange
event.
Here is a very basic demonstration searching a list of animal names:

- 15,615
- 6
- 32
- 80
-
This answers the question as asked. Unfortunately, my question was artificially simple. Mia culpa. – Matt Murphy Jan 29 '20 at 21:56
Notice, many of my attempts to read state below (and in previous edits) are garbage. I have this query building function that is executed at a variety of times (not listed in the question, mia culpa). I'm now passing in state as a parameter for said query function rather than trying to read it actively. I'm leaving this up as a caution to anyone who goes down a similar path. I apologize if I've steered anyone wrong thus far.
The 'Value' property of a textBox isn't updated on change or keyup events, as one might expect. If you wish to capture the contents typed into a textBox as they're being typed, you'll need to look for the 'Text' property, as in:
Me.txtSearchBox.Text
Unfortunately, this property isn't accessible unless the textBox is active, so if you're reading .Text while interacting with a different control you'll want to test that the textBox is active, which it won't be, and fail over to checking 'Value' instead, as in:
' assuming you've already dim'd the strSearchBox as String here...
If Screen.ActiveControl.Name = txtSearchBox.Name Then
' the control is active, so for the moment, Text is accessible
strSearchBox = Trim(txtSearchBox.Text & vbNullString)
Else
' textBox failover:
' Value is always accessible
strSearchBox = Trim(txtSearchBox.Value & vbNullString)
End If
' strSearchBox now has the contents of txtSearchBox, one way or the other
Yes, I'm a compulsive Trim()er. Yes, I cast to string by appending "" (corrected to vbNullString per @ComputerVersteher -- many thanks). Please do shout at me if that's horrible. The point is, .Value can be null on form load, and assigning null value to a string variable is breaking.
Unfortunately, if you're going to run this code while in going in and out of debug or loading the form Screen.ActiveControl.Name isn't going to be callable. You may resolve this by testing that the form in question is actually loaded, like so:
If not CurrentProject.AllForms(Me.Name).IsLoaded Then
' activeform failover:
' Value is always accessible
strSearchBox = Trim(txtSearchBox.Value & vbNullString)
Else
' there's an Form loaded, so there is an ActiveControl Name to test
If Screen.ActiveControl.Name = txtSearchBox.Name Then
' the control is active, so for the moment, Text is accessible
strSearchBox = Trim(txtSearchBox.Text & vbNullString)
Else
' textBox failover:
' Value is always accessible
strSearchBox = Trim(txtSearchBox.Value & vbNullString)
End If
End If
I hope this saves a few folks out there a little time. Maybe it will save you time if you read it and don't follow my advice. Check out the edits to see other bad ideas about reading state of a VB form and bad assumptions about control names being unique, etc...

- 331
- 2
- 11
-
1Nothing wrong with concat an empty string to avoid NULL. Iprefer that too as`Nz`is a build inMs Access function, not useable by other vba hosts, but I use [vbNullString](https://www.aivosto.com/articles/stringopt2.html#empty) as empty string, as it is typosafe (compiler won't complain on an accidential char inside of`""`) and safes you 6 bytes mem! – ComputerVersteher Jan 30 '20 at 16:11
-
1If form not loaded, you can't access a control inside! Don't compare names, compare objects as two forms can have controls with same name (open a form twice). And each opened form can have an active control, wich .Text property is accessible`If Me.ActiveControl is Me.txtSearchBox`is sufficent. – ComputerVersteher Jan 30 '20 at 16:13
-
@ComputerVersteher , (1) thanks for vbNullString: It's been too damn long since I've worked in Access. I've forgotten too much. (2) can't access a control when not loaded: Yes, and I've been experiencing the glorious variety of related errors I can trigger. I have to re-edit above to get to my final less-stupid solution. Part of my problem is that I was doing my initial query (to populated default search results in my listBox) via call from formLoad when I should have preferred formCurrent. – Matt Murphy Jan 30 '20 at 19:42