首页 > 解决方案 > 需要遍历 ListBox 以从布尔字段中提取具有真值的记录

问题描述

我有一个(设计不佳的)数据库,其中包含一个志愿者表。此表中有 70 多个是/否字段。每个字段代表每个志愿者可以选择服务的县。每个志愿者可以选择多个县。

我有一份必须允许选择多个县的报告。然后必须将该列表与选择的布尔字段进行比较,保留仅具有 True 值的记录。

如果您查看我最近的一些问题,我也遇到过类似的问题,但不同之处在于将布尔选择显示为报告上的文本。直到现在才发现选择标准代码并没有按照我的想法做......这是到目前为止所做的事情:

Dim s As Variant
Dim ctl As Control
Dim t As TCondition   'this is to compile multiple variables into one large "where" clause to run the report. 3 such variables are coded in this function.
Set ctl = Me.Counties
If ctl.ItemsSelected.Count <> 0 Then
   If t.WhereCondition = "" Then
     For Each s In ctl.ItemsSelected
        t.WhereCondition = (ctl.ItemData(s) & " = -1")
          Next s
Else
     For Each s In ctl.ItemsSelected
       t.WhereCondition = t.WhereCondition & " AND (ctl.ItemData(s) = -1)"
          Next s
  End If
End If

如果有人选择了多个县,这对我来说是个问题。我意识到他们只选择了最后一个县。

例如 - 县:红色、蓝色、银色和绿色只会返回绿色。

志愿者职位也出现了类似的问题。我需要考虑选择多个

所以我发现了以下内容:

Public Function listBoxToString(ByRef theListBox As ListBox, Optional ByVal theDelimiter As String = vbNullString)
  Dim varTemp As Variant

  listBoxToString = vbNullString

  For Each varTemp In theListBox.ItemsSelected
    If listBoxToString <> vbNullString Then listBoxToString = listBoxToString & ","
    listBoxToString = listBoxToString & theDelimiter & theListBox.ItemData(varTemp) & theDelimiter
  Next varTemp
End Function

这将获取 ListBox 的所有选择并制作一个逗号分隔的列表。这适用于职位字段(有多个),因为这些字段值是文本。

我试图将其应用于县,如下所示:

Dim s As String
Dim ctl As Control
Dim t As TCondition 
Set ctl = Me.Counties
If ctl.ItemsSelected.Count <> 0 Then
s = listBoxToString(Me.Counties, Chr(34))
   If t.WhereCondition = "" Then
        t.WhereCondition = (ctl.ItemData(s) & " = -1")
Else
       t.WhereCondition = t.WhereCondition & " AND (ctl.ItemData(s) = -1)"
  End If
End If

它不适用于县,因为 ListBox 返回的文本必须随后与县中的布尔值进行比较。所以,从逻辑上讲,我得到数据类型不匹配错误。

我有一段单独的代码,用于帮助在报告上显示县列表。它在运行时提取记录,获取记录的 ID,将布尔字段的索引归零,并将它们转换为字段的名称:

Public Function MakeListCounties(intID As Integer) As String
Dim rs As DAO.Recordset
Dim strList As String
Dim x As Integer
Set rs = CurrentDb.OpenRecordset("SELECT * FROM Volunteer WHERE ID=" & intID)
For x = 44 To 105
    If rs(x).Type = dbBoolean Then
        If rs(x) = True Then strList = strList & rs(x).Name & ", "
    End If
Next
If strList <> "" Then MakeListCounties = Left(strList, (Len(strList) - 2))
rs.Close
Set rs = Nothing
End Function

有没有办法用这个来得到我想要的?这可能是多余的,如果是这样,道歉并完全忽略那部分。

回顾一下 - 我需要遍历值的 ListBox,将它们与 70+ 个布尔字段的值进行比较,仅保留 Boolean = True 的记录以匹配 ListBox 中的值的字段名称

标签: ms-accessvba

解决方案


在返回 True 或 False 的通用模块中构建函数。使用以下表达式从查询调用:MC: MatchCounties([ID])过滤条件为=True.

假设组合框列出了与是/否字段名称完全匹配的县名,请考虑:

Function MatchCounties(intID As Integer) As Boolean
Dim rs As DAO.Recordset
Dim varItem As Variant
With Forms!formname.Counties
    If .ItemsSelected.Count <> 0 Then
        Set rs = CurrentDb.OpenRecordset("SELECT * FROM Volunteer WHERE ID=" & intID)
        For Each varItem In .ItemsSelected
            If rs(.ItemData(varItem)) Then 'use the listbox value as field name and test for True
                MatchCounties = True
                Exit For 'only need to match 1 yes/no county field to retrieve record
            End If
        Next
        rs.Close
        Set rs = Nothing
    End If
End With
End Function

如果列表框中没有选择任何项目,则不会返回任何记录,因为该函数将返回 False。如果您希望不允许选择并仍返回记录,则可能希望函数在 .ItemsSelected.Count = 0 时返回 True。使用 Else 调整代码。


推荐阅读