实时列表框从Access的文本框中过滤

时间:2016-08-26 17:01:44

标签: vba ms-access listbox access-vba ms-access-2010

我环顾四周,很难找到任何有助于单独使用固定解决方案的东西。我需要实时过滤列表框,以便我的用户可以在每个行/列中搜索一个术语。

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

由于我很难找到有关此问题的任何内容,所以我决定与所有帮助我解决开发问题的优秀人员分享我的解决方案。

请参阅下面的解决方案

如果您认为我需要在帖子中修改任何内容,请告诉我,我会更新它以便更好地解释。

1 个答案:

答案 0 :(得分:1)

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

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

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