来自文本框的实时列表框过滤器以进行访问

RealTime Listbox Filter from textbox for Access

我环顾四周,很难找到任何有用的东西,更不用说使用罐装解决方案了。我需要实时过滤一个列表框,这样我的用户就可以在每一行/每一列中搜索一个词。

我的列表框未绑定,我使用驱动逻辑/代码的按钮来调用各种查询,这些查询将填充列表框中的数据。每个按钮都会调用具有不同列数的查询,因此列表框会动态更改以相应地显示此信息。

由于我很难找到有关此问题的任何信息,因此我决定与所有帮助我解决开发问题的好人分享我的解决方案。

请看下面的解决方法

如果您认为我需要修复 post 中的任何内容,请告诉我,我会更新它以更好地解释。

需要指出的一件小事是,我将最初存储在 listBox 中的 UNFILTERED 记录集存储到一个全局变量中在表格上。我将文本框设置为具有 "onChange" 事件触发器并使用它调用下面的函数。我传入了列表框、文本框中的用户字符串以及我为未过滤的记录集创建的全局变量。当字符被删除时,这是取回原始数据所必需的。

此外,此函数不能很好地处理数字列。在使用具有数字数据类型列的查询进行一些测试后,我意识到了这一点。为了解决这个问题,我使用 CStr() 函数将查询设置为 return 作为字符串的数字。对于我们的新手,我只是进入命名查询,找到我的数字列,然后将 Cstr 放在 "field row" 中。因此,例如,我有一个名为 "Customer Impacted" 的数字列。我进入了查询,并在 'field row' 上为 [客户受影响的列] 写了这个:

Customers_Affected:Cstr([受影响的客户])

我想提醒您,如果您的记录集很大,您可能会遇到延迟。我只使用了大约 3000 的大小,它运行得非常好。享受。

Function realTimeFilter(ByVal List As Listbox, ByVal userString As String, ByVal staticRecordSet As DAO.Recordset)

'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
'\\                                                                                \\
'\\        This Function allows the user to input any string to create a           \\
'\\        Filter on a given listbox in realtime.                                  \\
'\\                                                                                \\
'\\        The programmer gives this fucntion the listbox of values to filter,     \\
'\\        The user's input string, and the unfiltered recordset that should be    \\
'\\        held in a global variable on the form.                                  \\
'\\                                                                                \\
'\\        I personally create a global called baseRecord.  Everytime I update     \\
'\\        the records in the listbox with a new unfiltered set,                   \\
'\\        I clone a copy to baseRecord.  This allows                              \\
'\\        the user to delete strings from the filter and regain the old dataset   \\
'\\        without having to query the data to the box again.                      \\
'\\                                                                                \\
'\\        enjoy!                                                                  \\
'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


'declare variables
Dim rs As DAO.Recordset
Dim str() As String
Dim filterStr As String
Dim i As Integer
Dim k As Integer

'adds unfiltered recordset back to listbox and also puts the data into our set for manipulation
Set List.Recordset = staticRecordSet.OpenRecordset
Set rs = List.Recordset


'split the terms
str = Split(userString, ",")

'examine the textbox string after it has been parsed. Determine which set of logic to use:
'first set is for single search criteria.  Second block is for multiple search criteria
If (UBound(str) = 0) Then

            'loop through the column fields
            For i = 0 To rs.Fields.Count - 1

                'if not on last column add an "OR" to the end of the filter string.  Else cap the string
                If ((i < rs.Fields.Count - 2) Or (i = rs.Fields.Count - 2)) Then
                    filterStr = filterStr & " " & rs.Fields(i).Name & " like '" & Trim(str(0)) & "*' OR "
                Else
                    filterStr = filterStr & " " & rs.Fields(i).Name & " like '" & Trim(str(0)) & "*'"
                End If
            Next i

            'set the filter
            rs.Filter = filterStr
    Else
        'start by enclosing the first logical string
        filterStr = "("

        'cycle through each word in the array of Strings
        For i = LBound(str) To UBound(str)

            'cycle through each column name in the recordset
            For k = 0 To rs.Fields.Count - 1

                'if not the final column add an "OR" at the end of the filter
                If ((k < rs.Fields.Count - 2) Or (k = rs.Fields.Count - 2)) Then
                    filterStr = filterStr & " " & rs.Fields(k).Name & " like '" & Trim(str(i)) & "*' OR "

                'if the final column AND string is not the last element add "AND (" to the end of the string to start the next
                'portion of logic in the string
                ElseIf ((i < UBound(str) And k = rs.Fields.Count - 1)) Then
                    filterStr = filterStr & " " & rs.Fields(k).Name & " like '" & Trim(str(i)) & "*') AND ("

                'if last column and last string in the array, cap the filter string
                Else
                    filterStr = filterStr & " " & rs.Fields(k).Name & " like '" & Trim(str(i)) & "*')"
                End If
            Next k

            'add filter
            rs.Filter = filterStr
        Next i
End If


'set recordset and refresh the listbox
Set List.Recordset = rs.OpenRecordset
List.Requery

'housekeeping
rs.Close
Set rs = Nothing
End Function