我有一个(设计很差的)数据库,其中包含一个志愿者表。在此表中有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中值的字段名称
将您的第一个代码段更改为以下内容。你总是得到最后一个县的原因是你的循环覆盖了以前的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
在返回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调整代码。