Type in text box and amend lstbox in change event

chrisjames25

Registered User.
Local time
Today, 14:12
Joined
Dec 1, 2014
Messages
404
Hi. Im trying to have a form with a text box in and a listbox. As i type in the textbox i want it to filter the lstbox according to what is typed in the textbox. (image of form attached)

Struggling on 2 fronts -

1. I have in the change event of textbox a requery command

Code:
Private Sub Txt_Batch_Change()

Me.Lst_Products.Requery
        
End Sub

But as i change the type in the textbox nothing happens to the lstbox. See attached image of query i am using for recordsource. Have i got the criteria correct?

2. I want the lstbox to be searchable fro each of the columns in it not just the 1 column. Is this achieveble?

Cheers
 

Attachments

  • Form VIew.JPG
    Form VIew.JPG
    42.6 KB · Views: 55
  • Rowsource Query.JPG
    Rowsource Query.JPG
    87.5 KB · Views: 51
In the change event you have to use the .Text property of the textbox, as its value has not yet been updated. I suspect you'll have to do this in code, assigning a new row source.
 
The following code turns any textbox listbox into a Find as you type.

1. Put the following into a CLASS module. NOT a standard module.
2. Call the class module exactly "FindAsYouTypeListBox"

Code:
Option Compare Database
Option Explicit

'Class Module Name: FindAsYouTypeListBox
'Purpose: Turn any Listbox into a "Find As You Type"  listbox
'Created by: MajP

Private WithEvents mListbox As Access.ListBox
Private WithEvents mForm As Access.Form
Private WithEvents mSearchForm As Access.Form
Private WithEvents mTextBox As Access.TextBox
Private mFieldToSearch As String
Private mFilterFromStart As Boolean
Private mRsOriginalList As DAO.Recordset

Private Sub mTextBox_Change()
  Call FilterList
End Sub
Private Sub mListBox_AfterUpdate()
  Call unFilterList
  mTextBox.SetFocus
  mTextBox.Value = Null
End Sub
Private Sub mForm_Current()
  Call unFilterList
End Sub
Private Sub FilterList()
  On Error GoTo errLable
  Dim rsTemp As DAO.Recordset
  Dim strFilter As String
  If Not Trim(mTextBox.Text & " ") = "" Then
    strFilter = getFilter(mTextBox.Text)
  Else
    Call unFilterList
  End If
  Set rsTemp = mRsOriginalList.OpenRecordset
  rsTemp.Filter = strFilter
  Set rsTemp = rsTemp.OpenRecordset
  If rsTemp.RecordCount > 0 Then
    Set mListbox.Recordset = rsTemp
    mListbox.Selected(0) = True
    mListbox.Value = mListbox.Column(0)
  Else
      MsgBox "No records match " & strFilter
  End If
  mTextBox.SelStart = Len(mTextBox.Text)
  Exit Sub
errLable:
  If Err.Number = 3061 Then
    MsgBox "Will not Filter. Verify Field Name is Correct."
  Else
    MsgBox Err.Number & "  " & Err.Description
  End If
End Sub
Private Sub unFilterList()
  On Error GoTo errLable
  Set mListbox.Recordset = mRsOriginalList
   Exit Sub
errLable:
  If Err.Number = 3061 Then
    MsgBox "Will not Filter. Verify Field Name is Correct."
  Else
    MsgBox Err.Number & "  " & Err.Description
  End If
End Sub
Private Sub Class_Terminate()
    Set mForm = Nothing
    Set mListbox = Nothing
    Set mRsOriginalList = Nothing
End Sub
Public Sub Initialize(theListBox As Access.ListBox, theTextBox As Access.TextBox, Optional FieldToSearch As String = "", Optional FilterFromStart = True)
   On Error GoTo errLabel
  If Not theListBox.RowSourceType = "Table/Query" Then
    MsgBox "This class will only work with a ListBox that uses a Table or Query as the Rowsource"
    Exit Sub
  End If
  Set mListbox = theListBox
  Set mForm = theListBox.Parent
  Set mTextBox = theTextBox
  mFieldToSearch = FieldToSearch
  mFilterFromStart = FilterFromStart
  mForm.OnCurrent = "[Event Procedure]"
  mTextBox.OnGotFocus = "[Event Procedure]"
  mTextBox.OnChange = "[Event Procedure]"
  mListbox.AfterUpdate = "[Event Procedure]"
 Set mRsOriginalList = mListbox.Recordset.Clone
 Exit Sub
errLabel:
 MsgBox Err.Number & " " & Err.Description
End Sub

Private Function getFilter(theText As String) As String
   'To make this work well convert all field in the listbox to string
   'Example:  strDateDue: cstr(dtmDueDate)
   Dim fld As DAO.Field
   Dim rs As DAO.Recordset
   Dim strFilter As String
   Dim strLike As String
   theText = Replace(theText, "'", "''")
   If mFilterFromStart Then
     strLike = " like '"
   Else
     strLike = " like '*"
   End If
   Set rs = mListbox.Recordset
   If mFieldToSearch = "" Then
      For Each fld In rs.Fields
        If fld.Type = dbMemo Or fld.Type = dbText Then
          If strFilter = "" Then
             strFilter = fld.Name & strLike & theText & "*'"
          Else
             strFilter = strFilter & " OR " & fld.Name & strLike & theText & "*'"
          End If
        End If
      Next fld
   Else
      strFilter = mFieldToSearch & strLike & theText & "*'"
   End If
   getFilter = strFilter
End Function
Public Property Get FilterFromStart() As Boolean
  FilterFromStart = mFilterFromStart
End Property
Public Property Let FilterFromStart(ByVal blnFilterFromStart As Boolean)
  mFilterFromStart = blnFilterFromStart
End Property
Public Property Get FieldToSearch() As String
  FieldToSearch = mFieldToSearch
End Property
Public Property Let FieldToSearch(ByVal theFieldToSearch As String)
  mFieldToSearch = theFieldToSearch
End Property
Public Sub SearchAllFields()
  mFieldToSearch = ""
End Sub

Public Sub SortList(SortString As String)
  Dim rs As DAO.Recordset
  Set rs = mListbox.Recordset
  rs.Sort = SortString
  Set mListbox.Recordset = rs.OpenRecordset
  Set rs = mRsOriginalList
  rs.Sort = SortString
  Set mRsOriginalList = rs.OpenRecordset
End Sub

On your form you use it as follows

Code:
Option Compare Database
Option Explicit
Public faytLst As New FindAsYouTypeListBox

Private Sub Form_Load()
  faytLst.Initialize Me.lstSearch, Me.txtSearch, "ProductName", False
  'where lstSearch is the name of your listbox
  'txtSearch is the name of your textbox
  'ProductName is the name of the field to filter
  'True or false if you want it to filter from the start of the string or anywhere in the string
End Sub
 
If you want to filter against all fields do not pass in a field name.
faytLst.Initialize Me.lstSearch, Me.txtSearch, , False
 
Hi MajP

Not quite as straight forward as i thought!!! Look forward to seeing if you find that other class for all the fields.

Cheers
 
Hi PBaldy.

Sorry to sound thicker than thicker but when you say use the .text property do you mean in the query design itself itself.

Use your method for all my comboboxes and they work fine but cant seem to refine this one. Am i struggling becuase i have 4 columns in the lstbox?
 
I meant in the code:

Txt_Batch.Text

I've never tried using it in a query. You'd have to post your code to help resolve why it isn't working. You'd need to include the 4 columns (fields) in your SQL.
 
Hi MajP

Not quite as straight forward as i thought!!! Look forward to seeing if you find that other class for all the fields.
Sorry if I was not clear. It already does just that, I just originally forgot that I put that feature in. Either you pass in a field to filter or leave it blank and it filters on all fields.

Code:
It doesn't have to be that complicated. It's similar to cascading combos, but using the .Text property of the textbox and the first method here:

Sorry, it is not complicated to use, that the whole point about writing real code. I wrote a single class module that captures all events and requires a single line of code to instantiate. What is complicated about writing one line of code. You write it once and reuse it many times.
 
Didn't say it was complicated to use. ;)
 
Hi MAjP

Like PBaldy said, didnt mean was complicated to use, just meant for a novice like me was complicated to follow the code all the way through.

THank you for your help on this though it is much appreciated.
 

Users who are viewing this thread

Back
Top Bottom