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 从表单值更新查询的主要内容,如果未能解决你的问题,请参考以下文章
当未从多个选择框之一中选择项目时,基于 Access 中的多个“多个选择列表框”的 VBA 查询