VBA - Access 03 - 遍历列表框,使用 if 语句进行评估

Posted

技术标签:

【中文标题】VBA - Access 03 - 遍历列表框,使用 if 语句进行评估【英文标题】:VBA - Access 03 - Iterating through a list box, with an if statement to evaluate 【发布时间】:2010-05-31 17:35:44 【问题描述】:

所以我有一个列表框,其中包含 DeptA、DeptB、DeptC 和 DeptD 等值。如果它们适用,我有一种方法可以使它们自动填充到此列表框中。换句话说,如果它们填充在此列表框中,我希望结果逻辑在表中的布尔字段中说它们是“是”。

因此,为了实现这一点,我首先尝试使用这个迭代示例来循环遍历列表框,并且效果很好:

dim i as integer
dim myval as string

For i = o to me.lstResults.listcount - 1
   myVal = lstResults.itemdata(i)
Next i

如果我 debug.print myval,我会从列表框中获取我想要的数据项列表。所以现在我正在尝试评估该列表,以便我可以根据需要使用 UPDATE SQL 语句来更新表。

所以,我知道这是一个错误,但这是我试图做的(举个例子,这样你就可以看到我想要到达的地方)

dim sql as string
dim i as integer
dim myval as string
dim db as database

sql = "UPDATE tblMain SET "

for i = 0 to me.lstResults.listcount - 1
  myval = lstResults.itemdata(i)

    If MyVal = "DeptA" Then
        sql = sql & "DeptA = Yes"
    ElseIF myval = "DeptB" Then
        sql = sql & "DeptB = Yes"
    ElseIf MyVal = "DeptC" Then
        sql = sql & "DeptC = Yes"
    ElseIf MyVal = "DeptD" Then
        sql = sql & "DeptD = Yes"
    End If
Next i

    debug.print (sql)

    sql = sql & ";"
    set db= currentdb
    db.execute(sql)

    msgbox "Good Luck!"

所以你可以看到为什么这会导致问题,因为这些值(DeptA、DeptB 等)自动填充到的列表框是动态的......列表框中很少有一个值,而值列表每个 OrderID 的变化(我使用它的表单首先填充信息;唯一实例)。

我正在寻找可以一次评估这个列表的东西(即遍历值列表,并查找“DeptA”,如果找到,则在 SQL 字符串中添加“是”,如果没有添加对 SQL 字符串不,然后继续进行下一次迭代)。尽管列表框动态填充值,但它们是设置值,这意味着我知道最终会出现什么。

感谢您的帮助, 贾斯汀

【问题讨论】:

列表框的行源和行源类型是什么? 听起来你没有遵循在这个问题中给出的建议,***.com/questions/2921454/… - 你接受了答案,但在我看来,你又一次试图当你应该使用子表单时使用列表框。 @Remou:Type = ValueList,Row Source = "" 如果 row source="",那么您必须在代码中构建它,这意味着您可以使用这些值。您可能想考虑发布填充列表框的代码。 @Remou rowsource="DeptA";"DeptB";"DeptC";"DeptD" 【参考方案1】:

我不明白你想要完成什么。但是,我怀疑您的 UPDATE 语句需要 WHERE 子句。 ('WHERE OrderID = X',其中 X 替换为您正在编辑的行的 OrderID)

我想您可以创建一个字典对象,其值最初设置为 False。

Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
dict.Add "DeptA", False
dict.Add "DeptB", False
' .. etc.    '

然后浏览列表框中的项目,将 dict 值更改为 True。

dict(myval) = True

最后,根据字典值构建您的 UPDATE 语句。

但这一切对我来说似乎工作量太大了。所以现在我想知道你的表结构。 tblMain 设置是不是类似这样?:

OrderID DeptA DeptB DeptC DeptD
------- ----- ----- ----- -----
127     True  False False True

如果是这样,请考虑一个相关的部门信息表。

OrderID Which_Department
------- ----------------
127     DeptA
127     DeptD

管理这一点的经验法则是“列很昂贵;行很便宜”。

编辑:在我看来你有两组项目: SetA 是所有可能的项目; SetB 是 SetA 的子集。您想为 SetB 中的每个项目生成一个 True,并为不在 SetB 中的每个 SetA 项目生成一个 False。当您将 dict (字典对象)替换为 SetA 并将 lstResults 替换为 SetB 时,这是否正确?

我试图建议的是使用所有可能的“DeptX”键加载 dict 并将它们分配为 False。然后迭代您的 lstResults 并将其中的每一个(在 dict 中)更改为 True。然后,从 dict 构建您的 SQL 语句。

Dim varKeys As Variant
Dim i As Integer
Dim strFragment As String

varKeys = dict.keys()
For i = LBound(varKeys) To UBound(varKeys)
    strFragment = strFragment & ", " & varKeys(i) & " = " & dict(varKeys(i))
Next i
strFragment = Mid(strFragment, 3)
sql = sql & strFragment & "WHERECLAUSE"

【讨论】:

我询问行源的原因是我从之前的问题中怀疑这个列表框是用这些值构建的,所以简单地捕获行源应该很容易,特别是如果 dept 表就像你的例子:WHERE which_department IN (" & Replace(Replace(x.RowSource,";",","),"""","'") & ")" 或者那里。 @Remou AFAICT 列表框包含要更新为 True 的部门。如果 DeptA 为 True,但现在不在列表框中,则应将其设置为 False。我喜欢您的 RowSource 方法,但我怀疑它仍然会涉及太多工作。 OTOH,我怀疑我不明白贾斯汀的想法...... @Both 家伙....不是我认为你有它。是的,我正在使用上一个问题中的技术,但是因为我想学习如何做到这一点。不是因为我认为这是最好的方法(我真的不知道)......所以当你们告诉我这个时,我相信你们,我只是仍然想知道如何去做(不是我要使用它生产中)。 @Hans...我不知道最后一点关于列昂贵而行很便宜...但是一旦您考虑一下,它就很有意义。 我只是想知道如果您想遍历一个值列表框并一次评估每个值,您必须遵循的基本概念。如果我使用上面的例子(假设只有列表框中有一个 DeptA),那么我会得到“DeptA = Yes DeptA = No DeptA = No DeptA = No WHERE ...”所以我只是想知道你怎么能完成从列表中查找单个值...我想我正在考虑每个部门的 4 次迭代语句的语法...???我不知道 一如既往地感谢大家!!我知道有时这些问题可能没有意义(因为我一直在学习这个 Access/VBA 的东西),但我特别从你们三个那里学到了很多东西,所以我很感激! :)

以上是关于VBA - Access 03 - 遍历列表框,使用 if 语句进行评估的主要内容,如果未能解决你的问题,请参考以下文章

Access 2007 VBA:构建一个列表框,其中包含来自另一个列表框的选择选项

Access VBA:比较两个列表框

在列表框 ms-access 2013 VBA 中将多个不同的字段作为列表项返回

如何在 vba(access) 中将变量设置为我的表单列表框之一?

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

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