Access vba - получение ошибки времени выполнения 3420 (недопустимый объект) при работе с набором записей в цикле - PullRequest
0 голосов
/ 28 мая 2018

У меня следующая проблема, я не могу пройти.Я пытаюсь создать набор записей в цикле.Идея состоит в том, чтобы добавить в базу данных несколько записей, связанных с выбранными пользователем диапазонами дат в форме пользователя.Когда пользователь выбирает только один код даты, он работает нормально, но когда пользователь выбирает диапазоны дат, он вылетает с указанной выше ошибкой времени выполнения на втором проходе цикла - недопустимый объект или не имеет значений.Вот мой код (часть его на самом деле немного упрощена, чтобы показать проблему):

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

Любые советы с благодарностью.Большое спасибо заранее.

С уважением

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

Не создавайте новый запрос для каждой итерации цикла.Просто используйте один запрос и используйте параметры для вставки разных данных.

Реальная проблема, как указал Витя, в том, что вы закрываете 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 и т. Д.

0 голосов
/ 28 мая 2018

Я попробовал этот маленький кусочек, и он также дал мне 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 в первой итерации, а затем ссылаетесь на него.

...