需要迭代ListBox以从布尔字段中提取具有True值的记录

问题描述 投票:0回答:2

我有一个(设计很差的)数据库,其中包含一个志愿者表。在此表中有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的所有选择,并以逗号分隔它们的列表。这对于Positions字段有效(有多个),因为这些字段值是TEXT。

我试着将它应用于县,如下:

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

它不适用于Counties,因为ListBox返回TEXT,然后必须将其与县中BOOLEAN的值进行比较。所以,从逻辑上讲,我得到数据类型不匹配错误。

我有一段单独的代码,用于帮助显示报告中的县名单。它在运行时提取记录,获取记录的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-access access-vba
2个回答
1
投票

将您的第一个代码段更改为以下内容。你总是得到最后一个县的原因是你的循环覆盖了以前的WHERE子句值。

Dim s As Variant
Dim ctl As Control
Dim t As TCondition
Set ctl = Me.Counties
If ctl.ItemsSelected.Count <> 0 Then
    For Each s In ctl.ItemsSelected
        t.WhereCondition = t.whereCondition & ctl.ItemData(s) & " = -1 OR"
    Next s
    ' trim trailing " OR"
    t.WhereCondition = Left(t.WhereCondition, Len(t.WhereCondition)-3)
End If

2
投票

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

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

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调整代码。

© www.soinside.com 2019 - 2024. All rights reserved.