Access VBA 如何根据多选列表框中的选择过滤记录集?

Posted

技术标签:

【中文标题】Access VBA 如何根据多选列表框中的选择过滤记录集?【英文标题】:Access VBA How can I filter a recordset based on the selections in a multi select list box? 【发布时间】:2015-04-24 00:37:33 【问题描述】:

我正在尝试使用 OpenForm 函数根据多选列表框中的选择进行过滤。什么是正确的语法,或者有更好的方法吗?举个例子,让我们说:

列表框有 Ken、Mike 和 Sandy 选项。

Car 有 Car1、Car2 和 Car 3 选项。所有汽车都由该列表框中的 1 个或多个人拥有。

如果选择了列表框中的某个人,我想打开一个表单,其中包含这些人所拥有的汽车。

谢谢!

【问题讨论】:

那么汽车表/表格是否只有每辆车有一条记录?如果是这样,是否所有所有者都列在同一字段中?如果不了解您要打开的表单的结构,就不可能回答您的问题。 我们需要您的数据方案! Car 表每辆车和每辆车都有一个记录,并且可以有多个 People(来自 People 表)连接到它。该表单有一个用于“人员”的多选列表框和另一个用于双击的文本框,这将打开一个过滤后的“汽车”表单,其中只有被选中的人拥有的汽车。如果您需要更多信息,请告诉我,谢谢! 好的,所以我找到了解决方案并将其发布在下面。谢谢! 【参考方案1】:

好的,所以我想出了一个办法:

    创建一个字符串来保存查询 使用 For 循环根据所选的每个项目填充字符串 将该字符串作为过滤器放入 OpenForm 命令中。

这是我习惯使用的具体代码。我在原始帖子中的示例使用了 Cars and People,但我的实际上下文不同:Estimators 和 Division of Work 是过滤器。如果您是有同样问题的人,请告诉我,如果您对此有任何疑问!因为如果不知道更多关于我到底想要完成什么,它可能会令人困惑。

Dim strQuery As String
Dim varItem As Variant
'query filtering for estimators and division list box selections
strQuery = ""
If Me.EstimatorList.ItemsSelected.Count + Me.DivisionList.ItemsSelected.Count > 0 Then
    For Each varItem In Me.EstimatorList.ItemsSelected
        strQuery = strQuery + "[EstimatorID]=" & varItem + 1 & " OR "
    Next varItem
    If Me.EstimatorList.ItemsSelected.Count > 0 And Me.DivisionList.ItemsSelected.Count > 0 Then
        strQuery = Left(strQuery, Len(strQuery) - 4)
        strQuery = strQuery + " AND "
    End If
    For Each varItem In Me.DivisionList.ItemsSelected
        strQuery = strQuery + "[DivisionID]=" & varItem + 1 & " OR "
    Next varItem
    strQuery = Left(strQuery, Len(strQuery) - 4)
End If

【讨论】:

【参考方案2】:

使用 JOIN 函数获得更简洁、更安全的代码

当您发现自己使用“、”“AND”“OR”等分隔符重复构建增量 SQL 字符串时,可以方便地集中生成数组数据,然后使用 VBA Join(array, delimiter) 函数。

如果感兴趣的键位于数组中,则用户从多选列表框中选择为表单过滤器属性构建 SQL WHERE 片段可能如下所示:

Private Sub lbYear_AfterUpdate()
    Dim strFilter As String

    Dim selction As Variant
    selction = ListboxSelectionArray(lbYear, lbYear.BoundColumn)

    If Not IsEmpty(selction) Then
        strFilter = "[Year] IN (" & Join(selction, ",") & ")"
    End If

    Me.Filter = strFilter
    If Not Me.FilterOn Then Me.FilterOn = True 
End Sub

从选定的 lisbok 行中选择任何列数据的通用函数可能如下所示:

'Returns array of single column data of selected listbox rows
'Column index 1..n
'If no items selected array will be vbEmpty
Function ListboxSelectionArray(lisbox As ListBox, Optional columnindex As Integer = 1) As Variant
    With lisbox
        If .ItemsSelected.Count > 0 Then
            Dim str() As String: ReDim str(.ItemsSelected.Count - 1)
            Dim j As Integer
            For j = 0 To .ItemsSelected.Count - 1
                str(j) = CStr(.Column(columnindex - 1, .ItemsSelected(j)))
            Next
            ListboxSelectionArray = str
        Else
            ListboxSelectionArray = vbEmpty
        End If
    End With
End Function

应用程序库中的一些数组构建器可以使编码看起来更像VB.NET

【讨论】:

以上是关于Access VBA 如何根据多选列表框中的选择过滤记录集?的主要内容,如果未能解决你的问题,请参考以下文章

组合框多选以在 Access 2016 中的文本框中显示所选项目

当未从多个选择框之一中选择项目时,基于 Access 中的多个“多个选择列表框”的 VBA 查询

ACCESS VBA 从列表框中选择多个值并执行查询名称

如何确定在 Access VBA 中键入组合框和从下拉列表中选择之间的区别?

根据 Access 列表框中的选择打开子表单

Access 2007 使用 VBA/SQL 语句中列表框中的 ID 值