【问题标题】:Access vba - getting runtime error 3420 (invalid object) when working with recordset in loopAccess vba - 在循环中使用记录集时出现运行时错误 3420(无效对象)
【发布时间】:2018-05-28 08:51:20
【问题描述】:

我遇到了以下问题,我无法通过。 我正在尝试循环创建记录集。想法是在数据库中添加一些与用户表单中用户选择的日期范围相关的条目。当用户只选择一个日期代码工作正常但当用户选择日期范围时,它在第二次循环传递时因上述运行时错误而崩溃 - 无效对象或没有值。 这是我的代码(实际上是其中的一部分,为了显示问题而进行了一些简化):

Dim sql, sql2 As String
Dim x, daty As Integer

Dim dbs As DAO.Database
Set dbs = CurrentDb
Dim qdf As DAO.QueryDef
Dim rs As DAO.Recordset

For x = 0 To 3   '''replaced user selected date ranges with 3 to simplify code
     sql = "INSERT INTO tDzialaniaRejestracja (IdSzkolenia, TerminRozpoczecia) VALUES (" & Me.IdSzkolenia & ", '" & Format((Me.DataRozpoczecia + x), "dd.mm.yyyy")  & "')"
     With dbs
        Set qdf = dbs.CreateQueryDef("", sql)    '''here i get runtine error 3420 on second loop pass
        qdf.Execute dbFailOnError
        sql2 = "SELECT @@IDENTITY"
        Set rs = .OpenRecordset(sql2, dbOpenDynaset)
        lastID = rs.Fields(0)
        rs.Close
        dbs.Close
     End With

     Me.IdDzialania = lastID
     Me.ProwadzacyFirmaZewn.Value = 23

     Set qdf = Nothing
     Set rs = Nothing

Next x

非常感谢任何提示。 非常感谢您。

问候

【问题讨论】:

  • 在错误信息前写上Debug.Print sql。你得到了什么?
  • 并尝试打开dbs,在第一个循环后您将关闭它。或者根本不关闭它。
  • 非常感谢,让数据库保持打开状态就可以了。

标签: vba ms-access recordset


【解决方案1】:

我已经尝试过这个小片段,它在第二个循环中也给了我3420

Sub TestMe()
    Dim dbs As DAO.Database
    Dim qdf As DAO.QueryDef

    Set dbs = CurrentDb
    Dim x As Long

    For x = 0 To 3
        Set qdf = dbs.CreateQueryDef("", "SELECT * FROM TABELLE1")
        dbs.Close
    Next x

End Sub

因此,问题在于您在第一次迭代中关闭了dbs,然后您正在引用它。

【讨论】:

    【解决方案2】:

    不要为每个循环迭代创建一个新查询。只需使用一个查询,并使用参数插入不同的数据。

    正如 Vityata 所指出的,真正的问题是您在第一次迭代时关闭了dbs。我也解决了这个问题。但我就是无法优化这段代码……

    Dim sql, sql2 As String
    Dim x, daty As Integer
    
    Dim dbs As DAO.Database
    Set dbs = CurrentDb
    Dim qdf As DAO.QueryDef
    Dim rs As DAO.Recordset
    sql = "INSERT INTO tDzialaniaRejestracja (IdSzkolenia, TerminRozpoczecia) VALUES (@Param1, @Param2)"
    Set qdf = dbs.CreateQueryDef("", sql)  
    For x = 0 To 3   
         qdf.Parameters("@Param1") = Me.IdSzkolenia
         qdf.Parameters("@Param2") = Format((Me.DataRozpoczecia + x), "dd.mm.yyyy")
         With dbs
            qdf.Execute dbFailOnError
            sql2 = "SELECT @@IDENTITY"
            Set rs = .OpenRecordset(sql2, dbOpenDynaset)
            lastID = rs.Fields(0)
            rs.Close
         End With
    
         Me.IdDzialania = lastID
         Me.ProwadzacyFirmaZewn.Value = 23
         Set rs = Nothing
    Next x
    'Not necessary, no benefit whatsoever in the following code, but it goes here if you want it
    dbs.Close
    Set dbs = Nothing
    Set qdf = Nothing
    

    这还有很多额外的好处,例如允许 Access 只编译一次查询、简化代码、避免可能的 SQL 注入等。

    【讨论】:

      猜你喜欢
      • 2014-01-15
      • 1970-01-01
      • 1970-01-01
      • 2017-06-26
      • 1970-01-01
      • 1970-01-01
      • 2020-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多