Access - 使用多选列表框 VBA 从表单值更新查询

Posted

技术标签:

【中文标题】Access - 使用多选列表框 VBA 从表单值更新查询【英文标题】:Access - Update Query from Form Values with Multiselect Listbox VBA 【发布时间】:2016-06-08 20:30:03 【问题描述】:

我有一个问题,我觉得我快要解决了,但我错过了一些东西。我有一个包含五个对象的未绑定表单。

'SSN' 是标准文本框。 “约会状态”是启用了多选的列表框。源是一个名为 States 的表。 'Carrier' 是一个组合框。 “约会状态”是一个组合框。 “Appt Request Date”是一个日期字段。

一旦值在所有五个对象中,我就有一个运行下面代码的按钮。我想将值传递给更新查询以用作条件。

正在更新的字段是“约会状态”和“约会请求日期”。其他字段用于选择正确的记录。

当前代码运行,更新查询接收大部分条件。唯一没有正确填充的字段是“约会状态”,我认为它会从 strCriteria 中提取。

当代码运行时,它会要求用户在需要从“约会状态”列表框中拉取时填充 strCriteria 值。

我从一个网站上找到了代码,该代码告诉如何从多选列表框中获取值,然后为一个条件选择查询创建 SQL。我已经尽我所能去适应它。主要区别在于 SQL 构建。当我使用原版时,它可以工作。

我修改后的代码来操作更新查询:

Private Sub Command35_Click()

Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim varItem As Variant
Dim strCriteria As String
Dim strSQL As String
Set db = CurrentDb()
Set qdf = db.QueryDefs("Appointment Update Query")

If Me![Appointment State].ItemsSelected.Count > 0 Then
  For Each varItem In Me![Appointment State].ItemsSelected
     strCriteria = strCriteria & "States.States = " & Chr(34) _
                   & Me![Appointment State].ItemData(varItem) & Chr(34) &  " OR "
  Next varItem
  strCriteria = Left(strCriteria, Len(strCriteria) - 3)
Else
  strCriteria = "States.States Like '*'"
End If
strSQL = "UPDATE [Appointment Query]" _
& " SET [Appointment Query].[Appointment Status] = [Forms].[Appointment Update].[Appointment Status], [Appointment Query].[Appt Request Date] = [Forms]![Appointment Update].[Appt Request Date]" _
& " WHERE ((([Appointment Query].SSN)=[Forms]![Appointment Update].[SSN]) AND (([Appointment Query].[Appointment State])=" & strCriteria & ") AND (([Appointment Query].Carrier)=[Forms]![Appointment Update].[Carrier]));"

qdf.SQL = strSQL
qdf.Close  

DoCmd.OpenQuery "Appointment Update Query"

Set db = Nothing
Set qdf = Nothing

End Sub

原代码:

    Private Sub cmdOK_Click()
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim varItem As Variant
Dim strCriteria As String
Dim strSQL As String
Set db = CurrentDb()
Set qdf = db.QueryDefs("qryMultiSelect")
If Me!lstRegions.ItemsSelected.Count > 0 Then
  For Each varItem In Me!lstRegions.ItemsSelected
     strCriteria = strCriteria & "tblData.Region = " & Chr(34) _
                   & Me!lstRegions.ItemData(varItem) & Chr(34) & "OR "
  Next varItem
  strCriteria = Left(strCriteria, Len(strCriteria) - 3)
Else
  strCriteria = "tblData.Region Like '*'"
End If
strSQL = "SELECT * FROM tblData " & _
        "WHERE " & strCriteria & ";"
qdf.SQL = strSQL
DoCmd.OpenQuery "qryMultiSelect"
Set db = Nothing
Set qdf = Nothing
End Sub

关于如何让它正常工作的任何想法?

Debug.Print strSQL:

    UPDATE [Appointment Query] SET [Appointment Query].[Appointment Status] = [Forms].[Appointment Update].[Appointment Status], [Appointment Query].[Appt Request Date] = [Forms]![Appointment Update].[Appt Request Date] WHERE ((([Appointment Query].SSN)=[Forms]![Appointment Update].[SSN]) AND (([Appointment Query].[Appointment State])=States.States = "AL" OR States.States = "AZ") AND (([Appointment Query].Carrier)=[Forms]![Appointment Update].[Carrier]));

Debug.Print strCriteria:

    States.States = "AL" OR States.States = "AZ"

States是州缩写所在的表名,第二个States是字段名。

【问题讨论】:

【参考方案1】:

您应该向我们展示您查询中的 SQL - 我看不出您尝试使用 States.State 的原因,所以我建议进行此更改,但现在真的很难提供更多帮助

If Me![Appointment State].ItemsSelected.Count > 0 Then
  strCriteria = "IN ("
  For Each varItem In Me![Appointment State].ItemsSelected
     strCriteria = strCriteria & Chr(34) _
                   & Me![Appointment State].ItemData(varItem) & Chr(34) &  ","
  Next varItem
  strCriteria = Left$(strCriteria, Len(strCriteria)-1) & ")" ' Remove last comma
Else
  strCriteria = "= """ & Me![Appointment State] & """"
End If

编辑:用双引号更新 SQL 语句

strSQL = "UPDATE [Appointment Query]" _
& " SET [Appointment Query].[Appointment Status] = [Forms].[Appointment Update].[Appointment Status], [Appointment Query].[Appt Request Date] = [Forms]![Appointment Update].[Appt Request Date]" _
& " WHERE ((([Appointment Query].SSN)=""" & [Forms]![Appointment Update].[SSN] & """) AND (([Appointment Query].[Appointment State]) " & strCriteria & _
") AND (([Appointment Query].Carrier)=""" & [Forms]![Appointment Update].[Carrier] & """));"

【讨论】:

我尝试插入您的代码,但没有成功。我玩弄它并让它输出 strCriteria 为:“AL”或“AZ”:If Me![Appointment State].ItemsSelected.Count > 0 Then For Each varItem In Me![Appointment State].ItemsSelected strCriteria = strCriteria & Chr(34) _ & Me![Appointment State].ItemData(varItem) & Chr(34) & " OR " Next varItem strCriteria = Left(strCriteria, Len(strCriteria) - 3) Else strCriteria = "= """ & Me![Appointment State] & """" End If 我为混乱的混乱道歉,试图弄清楚如何正确格式化 cmets... 到目前为止的编辑,代码确实运行并将字段传递给查询条件。但是有一个问题,因为它没有更新正确的行数。如果选择了一个状态值,则似乎提取了正确的记录。如果使用两个,则它会提取比应有的更多记录。我假设它与没有引号的文本字段有关?我不确定如何将它们与带括号的字段集成...我尝试了几种不同的方法,但每次都会出错。 每当您进行更改时更新您的代码和上面生成的调试,以便我们可以看到发生了什么。我将在上一个答案中用双引号更新 strSQL 语句 这是我现在得到的,分别是 strCriteria 和 strSQL:"AL" Or "AZ" UPDATE [Appointment Query] SET [Appointment Query].[Appointment Status] ="Pending", [Appointment Query].[Appt Request Date] =[Forms]![Appointment Update].[Appt Request Date] WHERE ((([Appointment Query].SSN)="999999999") AND (([Appointment Query].[Appointment State])="AL" Or "AZ" ) AND (([Appointment Query].Carrier)="ASI")); 当以单一状态运行时,它正确地拉取 1 条记录进行更新。选择两个状态时,拉取31条记录,只有2条。 如果您的 strCriteria 中仍然出现“OR”,那么您没有使用我使用“IN”子句的新代码 - 我还更新了 strSQL 子句以在 Appointment 后删除“=”。状态【参考方案2】:

我认为它与不使用变量strCriteria有关,您使用的是文字。

你现在拥有的:

"WHERE ((([Appointment Query].SSN)=[Forms]![Appointment Update].[SSN]) AND (([Appointment Query].[Appointment State])=strCriteria) AND (([Appointment Query].Carrier)=[Forms]![Appointment Update].[Carrier]));"

要使用变量内容,您需要将其转义作为查询的一部分,如下所示:

"WHERE ((([Appointment Query].SSN)=[Forms]![Appointment Update].[SSN]) AND (([Appointment Query].[Appointment State])=" & strCriteria & ") AND (([Appointment Query].Carrier)=[Forms]![Appointment Update].[Carrier]));"

此外,正如 dbmitch 注意到的,您可能还需要在 WHERE 之前留一个空格。

【讨论】:

我根据您和 dbmitch 的建议更改了代码。当我现在运行代码时,它要求我输入 States.States 的参数。除此之外,我没有收到任何实际错误。 能否对sql语句进行debug.print?也许看到要执行的查询将有助于澄清事情。 我已将其添加到问题的底部。【参考方案3】:

首先,您需要在 SQL 中连接的字符串之间使用空格 - 我只是在 SET 和 WHERE 之前添加了一个空格。您收到错误消息吗?

你能 Debug.print strSQL 吗?

strSQL = "UPDATE [Appointment Query]" _
& " SET [Appointment Query].[Appointment Status] = [Forms].[Appointment Update].[Appointment Status], [Appointment Query].[Appt Request Date] = [Forms]![Appointment Update].[Appt Request Date]" _
& " WHERE ((([Appointment Query].SSN)=[Forms]![Appointment Update].[SSN]) AND (([Appointment Query].[Appointment State])=strCriteria) AND (([Appointment Query].Carrier)=[Forms]![Appointment Update].[Carrier]));"

而且看起来您在更新 SQL 之前没有关闭 qdf。

qdf.SQL = strSQL
qdf.Close
DoCmd.OpenQuery "Appointment Update Query"

这也将破坏您如何构建 strCriteria 的查询

(([Appointment Query].[Appointment State])=strCriteria) 

如果您的任何单个字段是文本字段,您需要将它们用转义双引号括起来

【讨论】:

您能否在使用前调试.Print strCriteria - 并将其作为编辑发布在您的上述帖子中(对 strSQL 执行相同操作) 我进行了您建议的编辑并在上面的代码中更新了它们。我还添加了您要求的 debug.print。 开始 - 将& "OR "更改为& " OR " 这是一个问题[Appointment Query].[Appointment State])=States.States - 你想比较什么 - States.States 表/字段来自哪里?这是您想在标准中使用的 - 还是您正在使用 [Appointment State] 字段? 我只是按照我发布的第二个代码中的示例进行操作,这是我找到并编辑的那个。 States.States 是包含 [Appointment State] 引用的状态的表和字段名称。我需要在该列表框中选择的值等于 [Appointment Query].[Appointment State] 中的值。

以上是关于Access - 使用多选列表框 VBA 从表单值更新查询的主要内容,如果未能解决你的问题,请参考以下文章

如何更新 ms access vba 中的多值组合框?

从列表框中删除项目(MS Access VBA)

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

MS Access VBA - 在表单上提取列表框值(使用表单名称。)

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

access中一个表单中选中一个复选框其余的也会选中怎么解决