Object variable or With block variable not set Access vba [duplicate] - ms-access

This question already has answers here:
Vba Access error 91
(2 answers)
Closed 5 years ago.
I'm working with a couple tables, CTOL and CTOL_Asbuilt in Access. I'm trying to run a query to join these two tables together using VBA code. I ran the query in Access and it works. I'm using DAO for the database library to retrieve data from the local Access database (code is in the same database project as the database), and I'm new to VBA Access scripting.
SELECT CTOL.ID, CTOL.BOM_PART_NAME, CTOL.CII, CTOL.[PART FIND NO], CTOL.CSN,
CTOL.AFS, CTOL.EQP_POS_CD, CTOL.LCN, CTOL.POS_CT, CTOL.SERIAL_NO,
CTOL.PART_NO_LLP, [CTOL_Asbuilt].[PART-SN], [CTOL_Asbuilt].[PART-ATA-NO],
[CTOL_PW-E750207_Asbuilt].[PW-PART-NO]
FROM CTOL LEFT JOIN [CTOL_Asbuilt] ON CTOL.[PART FIND NO] = [CTOL_Asbuilt].[PART-ATA-NO];
This is the code below:
Option Compare Database
Option Explicit
'Const adOpenStatic = 3
'Const adLockOptimistic = 3
Function queryDatabase()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim rsQuery As DAO.Recordset
Dim part_find_no() As String
Dim eqp_pos() As Integer
'Dim strSQL As String
Dim i As Integer
Dim j As Integer
'Set objConnection = CurrentDb.OpenRecordset("CTOL")
Set db = CurrentDb
Set rsQuery = db.OpenRecordset("SicrProcess", dbOpenDynaset)
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
End Function
I'm getting the following error when I run this code with a macro that calls the function:
Run time error '91':
Object variable or With block variable not set
I'm trying to use the code with the query to loop through two fields and increment the value of the EQP_POS_CD field when the PART FIND NO entry matches the last (else, it just moves to the next record until it reaches the end of the result set). I want to test-run this query to make sure that the code retrieves the result that is output by running the query manually in Access.
Can you help me in fixing this error so I can run my code to retrieve the data? Thanks!

rs.Close
You cannot close something that is not open. Perhaps you meant it to be rsQuery.Close?

Open a recordset and loop through records.
Sub queryDatabase()
On Error GoTo ErrProc
Dim db As DAO.Database
Set db = CurrentDb
Dim qdf As DAO.QueryDef
Set qdf = db.QueryDefs("SicrProcess") 'set your query name here
Dim rs As DAO.Recordset
Set rs = qdf.OpenRecordset(dbOpenDynaset)
Dim part_find_no() As String
Dim eqp_pos() As Integer, i As Integer
If rs.EOF Then GoTo Leave
rs.MoveLast
rs.MoveFirst
For i = 1 To rs.RecordCount
'...
'Do work here
'...
rs.MoveNext
Next i
Leave:
On Error Resume Next
rs.Close
Set rs = Nothing
qdf.Close
Set qdf = Nothing
Set db = Nothing
On Error GoTo 0
Exit Sub
ErrProc:
MsgBox Err.Description, vbCritical
Resume Leave
End Sub

Related

Read only recordset "local" update

I have DAO recordset that is generated with pass-through query to postgresql stored function. I use it to fill out combobox in my form. What I need is additional item in combobox with "AllItems" description. But the recordset is read-only (that's normal in this case). So I cannot just add new row to it. Can I do any kind of in memory recordset clone, copy or anything like that to make addition possible? I don't want to update recordsource. And I don't want to hardcode this option in to the pgsql function as well.
Public Sub fillCboAssortmentType()
Dim rs As DAO.Recordset
If (lngViewContext = acMyItems) Then
Set rs = getAssortmentTypesByDAO(TempVars!loggedUser)
Else (lngViewContext = acAllItems) Then
Set rs = getAssortmentTypesByDAO
End If
' It wont work, because the rs is RO
With rs
.AddNew
!type_id = 0
!type_name = "***AllItems***"
End With
' It wont work neither, because cboTypeFilter rowsource is Table/Query
Set Me.cboTypeFilter.Recordset = rs
Me.cboTypeFilter.AddItem "0;***AllItems***"
End Sub
Any suggestions?
TY All.
I think you are asking for a "In Memory" Recordset. Let's assume you have a table which looks like this
Then the following code will read the values from the table and copy it to a in memory recordset and add a new value but only in memory
Option Compare Database
Option Explicit
Sub inMemory()
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
With rs.Fields
.Append "val", adVarChar, 64
End With
Dim sourceRs As DAO.Recordset
Dim db As DAO.Database
Set db = CurrentDb
Set sourceRs = db.OpenRecordset("SELECT * FROM tbl")
Dim i As Long
rs.Open
Do Until sourceRs.EOF
rs.AddNew
rs.Fields(0).Value = sourceRs.Fields(0).Value
rs.Update
sourceRs.MoveNext
Loop
rs.AddNew
rs.Fields(0).Value = "Cancel"
rs.Update
' let's print the list just for testing
rs.MoveFirst
Do Until rs.EOF
Debug.Print rs.Fields(0).Value
rs.MoveNext
Loop
End Sub

Setting a query to a recordset

I am trying to set a recordset that keeps giving me the error message - "Runtime Error 3061 Too few parameters. Expected 1".
The query checks to see what value is in a combo box and then returns two fields. This is the VBA code I tried -
Dim db As Database
Dim rst As Recordset2
Dim field As field
Dim n As Integer
Dim Qno As Integer
Dim sqlstr As String
Set db = DBEngine(0)(0)
Set rst = db.OpenRecordset("Get_Questions", dbOpenDynaset)
This is the SQL behind the Get_Questions Query -
SELECT Question_Lt.Qnumber, Question_Lt.Questions, Question_Lt.Freq
FROM Question_Lt
WHERE (((Question_Lt.ClientCd)=[Forms]![TestForm]![CmClient]));
Use your query as a QueryDef object, supply the parameter value, and then use its OpenRecordset method to populate your recordset.
'Set rst = db.OpenRecordset("Get_Questions", dbOpenDynaset)
Dim qdf As DAO.QueryDef
Set qdf = db.QueryDefs("Get_Questions")
qdf.Parameters(0).Value = [Forms]![TestForm]![CmClient]
Set rst = qdf.OpenRecordset(dbOpenDynaset)
i ve to few reputation points to comment your question. But what ist the SQL Statement exactly. It seems to me that your ' ' are not set but i don' t know
Im Just guessing: Sql Script for Get_Questions should be something like that. I don' t know the parameter "Get_Questions" is it a query-name?
sqlStr =
"SELECT...
FROM Question_LT
WHERE Client.Cd = " & [Forms]![TestForm]![CmClient]

how to fill a recordset in vba in a module behind a db

I have tried many ways to get the job done. I am inexperienced with the
Access VBA.
I think the problem is how to set the current database. The code is in a module from another db as the current db. I have paste the code here in a module behind the
currentdb that also gives the same error. I have looked after very much questions.
It must be simple. But I don't see the answer.
Private Sub project()
Dim projectnamen As DAO.Database
Dim strSQL As String
Dim rs As DAO.Recordset
Dim strdbName As String
Dim strMyPath As String
Dim strdb As String
Dim accapp As Object
Path = "c:\GedeeldeMappen\programma en bestanden stiko"
strdbName="projektnamen.accdb"
strMyPath = Path
strdb = strMyPath & "\" & strdbName
'make the db "projectnamen"current. Perhaps this is possible with set??
Set accapp = CreateObject("Access.Application")
accapp.OpenCurrentDatabase (strdb)
'fieldname is naam_van_het_project
'tablename is projectnaam
strSQL = "SELECT All naam_van_het_project FROM projectnaam;"
'here i get an error "can't find the object Select All naam_van_het_project
'FROM projectnaam" error 3011
Set rs = CurrentDb.OpenRecordset(strSQL, dbOpenTable)
rs.MoveFirst
Do While Not rs.EOF
MsgBox (rs)
rs.MoveNext
Loop
End Sub
I think you want to run that query against the db which you opened in the new Access session, accapp.
The CurrentDb method is a member of Application. So qualify CurrentDb with the object variable name of that other application session.
'Set rs = CurrentDb.OpenRecordset(strSQL, dbOpenTable)
Set rs = accapp.CurrentDb.OpenRecordset(strSQL, dbOpenSnapshot)
Note OpenRecordset won't let you use dbOpenTable with a query. So I arbitrarily chose dbOpenSnapshot instead. If that's not what you want, substitute a different constant from the RecordsetTypeEnum Enumeration (see Access help topic for details).

openrecordset only showing one result

When I use a recordset to read from a table everything works fine and the recordcount function shows me the correct amount, but when I use this simple query or any query I always get 1 as a recordcount.
Here's whats working
Option Compare Database
Option Explicit
Public Sub LoadQ2()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("test")'test is the name of my table which contains 13 rows
With rs
Debug.Print .RecordCount
.Close
End With
Set db = Nothing
Set rs = Nothing
End Sub
and here's whats not working
Option Compare Database
Option Explicit
Public Sub LoadQ2()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL As String
strSQL = "SELECT test.number_id FROM test"
Set db = CurrentDb
Set rs = db.OpenRecordset(strSQL)
With rs
Debug.Print .RecordCount
.Close
End With
Set db = Nothing
Set rs = Nothing
End Sub
I should get the same result with both recordcount right?? Also I'd like to see the line I have in the recordset in the debug is it possible to print the content of the recordset in the debug window??
To print the contents of the recordset, you can do one of these two options..
debug.print rs.fields(0) & ", " & rs.fields(1)
or
debug.print rs("ColumnNameHere") & ", " & rs("AnotherColumnName")
.... found the answer
before doing the Debug.Print .RecourdCount i added .MoveLast and got the right number of recordcount
Looks like recordcount just means at what record that he is not how many records
Just to complement as you already found the answer yourself :)
The Dynaset data type (default for DAO recordset) doesn't fully populate until you go through all its records - since the need to do a .MoveLast before checking how many records it actually has.
I presume that DAO just returns 1 for the recordcount as an easy way to check beforehand if the recordset is empty or not (e.g. recordcount > 0) without having to go through the hassle of moving between records.

Code To Loop Through and Edit Recordsets

I have found how to loop through recordsets with the following link:
Code to loop through all records in MS Access
However, I want to know if it is possible if I can remove a record from the recordset if it doesn't meet criteria that I specify in the loop.
EDIT
I am now getting an error with the following code:
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("fieldHistory", dbOpenTable)
where fieldHistory is the name of the query recordset I want to open. Why am I getting this error? The last line of code there is the source of the error and Access simply states "Invalid operation"
Yes, you can use the DAO recordset's Delete method to delete the current record. This example will delete rows where the fname value is "xxx".
Public Sub DeleteRecordsetRow()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("tblDiscardMe", dbOpenTable)
Do While Not rs.EOF
If rs!fname = "xxx" Then
rs.Delete
'* the next line would trigger *'
'* error 3167: "Record is deleted." *'
''Debug.Print rs!fname
End If
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
Notice that immediately after rs.Delete (i.e. before MoveNext), the deleted row is still "current", but you can't access its values. You can uncomment the Debug.Print line to examine this further.
Edit:
Since your record source is a query rather than a table, try this to narrow down the reason you're getting an error with OpenRecordset.
Public Sub foo20110527a()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("fieldHistory")
If Not (rs.BOF And rs.EOF) Then
rs.MoveLast
MsgBox "RecordCount: " & rs.RecordCount
Else
MsgBox "No records"
End If
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
Since you used English (rather than English-like technical terms), your intent isn't very clear. You ask if you can "...remove a record...", which can mean either that you want to Delete it (in which case you already have a good answer form HansUp), or that you want to filter it out so that you don't see it, while leaving it in the underlying database.
If your intent is the latter (filtering), you have two choices:
Use a SQL statement with a WHERE clause in the original OpenRecordset call.
Use the Recordset's .Filter property before you enter the loop.
Access comes with adequate (if not stellar) Help on either topic.