【问题标题】:Cannot use ListBox values in MS Access 2007 to pass to query无法使用 MS Access 2007 中的 ListBox 值传递给查询
【发布时间】:2018-06-27 21:51:52
【问题描述】:

早上好,

我正在帮助通过 MS Access 中的表单开发界面。我们有一个包含各种用户值的列表框,用户应该能够在 ListBox 中选择多个值,然后按下按钮执行查询,只返回 Car Name 为所选内容的行。

更新 - 感谢这个论坛的一些很好的反馈,主要问题得到了解决。我的次要问题现在无法执行查询。当我尝试时,我收到无法执行查询的错误。

我的按钮代码(作为事件过程)是:

Option Explicit
Private Sub btnSearchCars_Click()
    MsgBox "Starting Sub"
    Call QueryCars.myQuery
    MsgBox "Ending Sub"
End Sub

然后,我的 QueryCars 模块如下所示:

Sub myQuery()
    Dim strWhere As String
    Dim strSQL As String
    Dim varItem As Variant

    For Each varItem in Forms!FormSelect!listCarID.SelectedItems
        strWhere = strWhere & "'" & Forms!FormSelect!listCarID.ItemData(varItem) & "',"
    Next

strWhere = Left(strWhere, Len(strWhere) -1)

    strSQL = "SELECT tblBig.* FROM tblCars INNER JOIN tblBig ON tblCars.Car_ID = tblBig.Car_ID WHERE tblCars.Car_ID IN (" & strWhere & ");"
    DoCmd.RunSQL strSQL

End Sub

我的错误是“A RunSQL requires an argument of an SQL statement”错误。

DoCmd.RunSQL strSQL

如果有人可以提供帮助,我将不胜感激。我要做的就是从用户选择的列表框中获取值,并将它们用作查询中的 WHERE 条件。我整个上午都在搜索各种 SO 和 Access 论坛,但没有找到任何帮助。

谢谢。如果您有任何问题,请告诉我。

【问题讨论】:

  • strWhere 似乎构造得不好,第一个你有两倍的项目添加,第二个你有一个 , 最后需要删除。
  • @VincentG 感谢您的反馈。我做了这些更改,但仍然遇到同样的错误。
  • myForm 声明错误。它应该是As Access.Form 通过在每个模块的顶部使用Option Explicit,您应该能够在编译时选择那些错误..
  • 嗨@KostasK。谢谢您的答复。不幸的是,尽管我已经调整了代码,但这并没有解决我的错误。
  • 如果你不告诉我们,我们怎么知道你“添加了一个额外的功能来删除尾随的','”?

标签: ms-access vba


【解决方案1】:

这不是我希望给您的完美答案 - 但无法弄清楚如何在 IN 命令中使用参数查询。

我假设您的列表框包含两列数据,CarID 值位于第一列。

主函数称为ProcessQuery,并接受对列表框的引用作为参数:
Public Sub ProcessQuery(myList As ListBox)

然后,您可以从列表框上的事件调用您的代码并将其传递给列表框引用。

Private Sub btnSearchCars_Click()
    ProcessQuery Me.listCarID
End Sub  

ProcessQuery 过程然后查看第一列以获取索引号、构造 SQL、打开生成的记录集并从每条记录中提取信息。

Public Sub ProcessQuery(myList As ListBox)

    Dim vItem As Variant
    Dim IDList As String
    Dim qdf As dao.QueryDef
    Dim rst As dao.Recordset

    For Each vItem In myList.ItemsSelected
        'Column 0 is first column in listbox.
        IDList = IDList & "'" & myList.Column(0, vItem) & "',"
    Next vItem
    'Removes the final ,
    IDList = Left(IDList, Len(IDList) - 1)

    'Create a temporary query definition & open the recordset.
    Set qdf = CurrentDb.CreateQueryDef("", _
        "SELECT tblBig.* FROM tblCars INNER JOIN tblBig ON tblCars.Car_ID = tblBig.Car_ID WHERE tblCars.Car_ID IN (" & IDList & ")")
    Set rst = qdf.OpenRecordset

    'Move through the recordset and output the first two fields from each record
    'to the Immediate window.
    With rst
        If Not (.BOF And .EOF) Then
            .MoveFirst
            Do While Not .EOF
                Debug.Print .Fields(0) & " - " & .Fields(1)
                .MoveNext
            Loop
        End If
    End With

End Sub 

要将查询结果显示为数据表,您可以使用以下内容,但我更喜欢使用带有IN 参数的存储查询。我会试着弄清楚这一点。

Public Sub ProcessQuery(myList As ListBox)

    Dim vItem As Variant
    Dim IDList As String
    Dim qdf As dao.QueryDef
    Dim rst As dao.Recordset

    For Each vItem In myList.ItemsSelected
        'Column 0 is first column in listbox.
        IDList = IDList & "'" & myList.Column(0, vItem) & "',"
    Next vItem
    'Removes the final ,
    IDList = Left(IDList, Len(IDList) - 1)

    'Create a temporary query definition & open the recordset.
    Set qdf = CurrentDb.CreateQueryDef("TempQDF", _
        "SELECT tblBig.* FROM tblCars INNER JOIN tblBig ON tblCars.Car_ID = tblBig.Car_ID WHERE tblCars.Car_ID IN (" & IDList & ")")

    DoCmd.OpenQuery "TempQDF", acViewNormal

End Sub

【讨论】:

  • 嗨@Darren Bartrup-Cook,非常感谢您的回复!我只是继续前进并花了最后 30 分钟来实现您的想法,并尝试了解您在做什么以及在谷歌上搜索我不熟悉的术语。我确实有一个问题。它运行良好,没有错误,但是,什么也没有发生......这意味着没有任何记录返回任何地方。我已经添加了一些 MsgBoxs 以显示该函数运行,它确实可以运行,但实际上没有填充任何内容。你有什么建议吗?
  • 需要检查的几件事 - 1. 使用 F8 逐步执行代码。它是否执行If Not (.BOF And .EOF) Then 块内的代码 - 如果不是,那么这是查询没有返回任何内容的好兆头。 2. 在IDList = Left(IDList, Len(IDList) - 1) 之后暂停代码,打开立即窗口(@98​​7654333@ 在 VBE 中打开)并输入?"SELECT tblBig.* FROM tblCars INNER JOIN tblBig ON tblCars.Car_ID = tblBig.Car_ID WHERE tblCars.Car_ID IN (" & IDList & ")"。使用 SQL 创建一个查询并查看它是否返回任何内容。
  • 3.打开 Locals 窗口并在您逐步执行代码时密切关注变量 - IDList 是否填充了正确的值?
  • 嗨@Darren Batrup-Cook。非常感谢你的帮助。不幸的是,我无法单步执行代码。按 F8 没有任何作用,当我单击“运行 -> 步入”时,Access 会提示我查找宏并将其保存为模块。你会建议我创建一个正式的宏吗?
  • 嗨@Darren Bartrup-Cook。再次感谢您对我如此耐心。我觉得我一直生活在 SO 和 UtterAccess 上,试图配置这个东西。我单步执行了代码,IDList 变量被正确填写,If Not Then 块也被正确循环。我还听取了您的建议,并从 VBE 中复制了 SQL,当我这样做时,它运行良好。 (仅供参考 - 它在 VBE 中的引号中,我需要删除引号......它应该在 VBE 中到底是如何运行的?)
【解决方案2】:

我建议首先查看正在生成的实际 WHERE 子句...保留一个单独的字符串变量来存储它,然后在生成时将其转储到即时窗口。

我还建议创建一个单独的函数以将列表框中选择的值作为数组返回。比如:

Public Function getListBoxSelection(ctl As Access.ListBox) As Variant
   Dim arr() As Variant
   Dim varItem As Variant, i As Long

   If ctl.ItemsSelected.Count > 0 Then
      ReDim arr(0 To ctl.ItemsSelected.Count - 1)
      i = 0

      For Each varItem In ctl.ItemsSelected
         arr(i) = ctl.ItemData(varItem)
         i = i + 1
      Next varItem

   End If

   getListBoxSelection = arr
End Function

然后,您将在 SQL 生成中调用它。像

whereClause = join(getListBoxSelection(me.listCarID), " AND ")
debug.Print whereClause

qdf.SQL = _
    "select tblBig.* " & _
    "from tblCars " & _
    "inner join tblBig on tblCars.Cat_ID = tblBig.Car_ID " & _
    "where tblCars.Card_ID in (" & whereClause & ")"

【讨论】:

  • 嘿@Zack。我可以继续进行这些更改。谢谢你的建议。我目前的问题是,即使我运行 Debug.Print 或运行 DoCmd.OpenQuery,实际上也没有弹出或发生任何事情......尽管我没有收到任何错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
  • 1970-01-01
  • 1970-01-01
  • 2015-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多