Reputation: 21
I got following problem I cannot get pass. I am trying to create recordset in loop. Idea is to add to database some entries related to user selected date ranges in user form. When user selects just one date code works fine but when user selects date ranges it crashes with above runtime error on second loop pass - invalid object or has no values. Here is my code (part of it in fact, a bit simplified to show the problem):
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
Any tips greatly appreciated. Thank you very much in advance.
regards
Upvotes: 2
Views: 1796
Reputation: 32632
Don't create a new query for every loop iteration. Just use one query, and use parameters to insert different data.
The real problem, as Vityata pointed out, is that you're closing dbs
on the first iteration. I've fixed that as well. But I just couldn't not optimize this code...
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
This has many additional advantages, such as allowing Access to compile the query only once, simplifying your code, avoiding possible SQL injection, etc.
Upvotes: 2
Reputation: 43575
I have tried this small piece and it gave me 3420
on the second loop as well.
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
Thus, the problem is that you are closing the dbs
in the first iteration and then you are refering against to it.
Upvotes: 3