dbOpenDynaset - 'Object variable or With block variable not set' - vba

I have a query called 'qryAddressBook'. I want to be able to loop vertically through the records in a specific field called 'Client_Address' and display those records on a single row in a table 'tblClient'.
I have done this in the past with tables using "Set rs = dbs.OpenRecordset("tblAddressBook", dbOpenTable)" with no issues....
...and I followed the syntax showed from Access Database.OpenRecordset method (DAO): https://learn.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/database-openrecordset-method-dao
I continue to get an error that says, 'Object variable or With block variable not set' and it highlights the following text from my code:
Set rs = dbs.OpenRecordset("qrySpecificNCR", dbOpenDynaset)
Here is my total code:
DoCmd.OpenQuery "qryAddressBook"
Dim dbs As DAO.Database
Dim rs As Recordset
Dim SeqNum As Integer
Set dbs = CurrentDb
SeqNum = 1
Set rs = dbs.OpenRecordset("qryAddressBook", dbOpenDynaset)
Do Until rs.EOF
Dim srtAddress As String
srtAddress = rs.Fields("Client_Address").Value
Dim strSQLAddress As String
strSQLAddress = "UPDATE tblClient SET " & SeqNum & " = '" & srtAddress & "' WHERE Record = 1;"
DoCmd.RunSQL strSQLAddress
SeqNum = SeqNum + 1
rs.MoveNext
Loop

I still don't understand the explicit part...but I found the error.
My qryAddressBook had the following line of code:
FROM qryGlobalAddress
WHERE (((qryAddress.Client) = [FORMS]![frmClientAddress]![CmbClientName]));
I was pushing a form parameter from a combo box. When I changed this to a specific client name such as:
FROM qryGlobalAddress
WHERE (qryAddress.Client) = 'Smith, John';
Then the Set rs = dbs.OpenRecordset("qryAddressBook", dbOpenDynaset) worked perfectly.
The problem now is I'll need to figure out a way to push a form parameter to the query. :(

cancatenate the form combo value
"FROM qryGlobalAddress WHERE (((qryAddress.Client) = '" & [FORMS]![frmClientAddress]![CmbClientName] & "'));"

Related

access vba concatenate single column query into a single line result

I have a new database to help produce documents for order processing.
I have a query set up with only one column of results (Product Codes) determined by the order selected on the main form.
I need to be able to use this information to name my file aka
(Customer) (Product1)+(Product2)+(Product....) (Location)
I have the code to generate the line (Customer) (Product1) (Location) and am trying to get either a concatenate function or a loop function or something to get all the products to line up with a "+" in between each "line".
I have a query (Query1) set up to give me the exact data I need...
SELECT tblREF_Chemical.Abbr
FROM qry_AX_LineItems_DISTINCT INNER JOIN tblREF_Chemical ON
qry_AX_LineItems_DISTINCT.ItemId = tblREF_Chemical.[Item Number]
GROUP BY tblREF_Chemical.Abbr, qry_AX_LineItems_DISTINCT.SALESID,
tblREF_Chemical.[Proper Shipping Name]
HAVING (((qry_AX_LineItems_DISTINCT.SALESID)=[Forms]![frm_SalesOrderEntry]!
[Combo617]) AND ((tblREF_Chemical.[Proper Shipping Name]) Is Not Null));
I have a button set up on my main form to test the data output and then I intend to add the code to my code for DoCmd.Output file name.
So far the only code that has worked is...
Private Sub Command1492_Click()
Dim i As Integer
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim SQL As String
Set db = CurrentDb
SL = [Forms]![frm_SalesOrderEntry]![Combo617]
SQL = "SELECT * FROM ALL_SalesOrderItemsLineDates WHERE
ALL_SalesOrderItemsLineDates.SALESID = '" & SL & "';"
Set rst = db.OpenRecordset(SQL)
For i = 0 To DCount("*", "ALL_SalesOrderItemsLineDates",
"ALL_SalesOrderItemsLineDates.SALESID = '" & [Forms]![frm_SalesOrderEntry]!
[Combo617] & "'") - 1
Debug.Print DLookup("[Abbr]", "[tblREF_Chemical]", "[Item Number]= '" &
rst.Fields("ItemID") & "'")
rst.MoveNext
Next i
rst.Close
End Sub
I can't seem to add additional where statements within this code or use my actual query or the system presents errors at the db.OpenRecordset line of code (Errors 3061 and 3078).
Even ignoring those problems the output is multi-line and I need it to be used in a single string of text for the document name.
UPDATE1:
I am working with the code to use my query directly...
Dim i As Integer
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim SQL As String
Set db = CurrentDb
SL = [Forms]![frm_SalesOrderEntry]![Combo617]
SQL = "SELECT tblREF_Chemical.Abbr "
SQL = SQL & "FROM qry_AX_LineItems_DISTINCT INNER JOIN tblREF_Chemical ON qry_AX_LineItems_DISTINCT.ItemId = tblREF_Chemical.[Item Number] "
SQL = SQL & "GROUP BY tblREF_Chemical.Abbr, qry_AX_LineItems_DISTINCT.SALESID, tblREF_Chemical.[Proper Shipping Name] "
SQL = SQL & "HAVING ((qry_AX_LineItems_DISTINCT.SALESID)='" & SL & "'"
SQL = SQL & "AND ((tblREF_Chemical.[Proper Shipping Name]) Is Not Null)); "
Set rst = db.OpenRecordset(SQL)
Dim s As String
Do While rst(0) Is Not Null
s = s & "+" & rst(0)
rst.MoveNext
Loop
rst.Close
Debug.Print s
Unfortunately I'm now getting a run-time error 3061 - Too few parameters. Expected 1.
I have double checked my spellings and ran the query just to be sure and no matter how many results the query is getting (functioning as expected) I am still getting this error.
UPDATE2:
Through more research I learned that queries can have, for lack of better words, invisible coding. I am updating my code to remove the inner query from my query to simplify the amount of "research" my VBA has to do.
Private Sub Command1492_Click()
Dim i As Integer
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim SQL As String
Set db = CurrentDb
SL = [Forms]![frm_SalesOrderEntry]![Combo617]
SQL = "SELECT tblREF_Chemical.Abbr "
SQL = SQL & "FROM ALL_SalesOrderItemsLineDates INNER JOIN tblREF_Chemical ON ALL_SalesOrderItemsLineDates.ItemId = tblREF_Chemical.[Item Number] "
SQL = SQL & "GROUP BY tblREF_Chemical.Abbr, ALL_SalesOrderItemsLineDates.SALESID, tblREF_Chemical.[Proper Shipping Name]"
SQL = SQL & "HAVING ((ALL_SalesOrderItemsLineDates.SALESID)='" & SL & "'"
SQL = SQL & "AND ((tblREF_Chemical.[Proper Shipping Name]) Is Not Null)); "
Set rst = db.OpenRecordset(SQL)
Dim s As String
Do While rst(0) Is Not Null 'Debug error here!
s = s & "+" & rst(0)
rst.MoveNext
Loop
rst.Close
Debug.Print s
End Sub
Unfortunately I'm still getting a run-time error, but now it is 424 Object required and the debug takes me to the "Do While" line.
I think this is a step forward, but still a little stuck.
Update3:
Since the debug was taking me to the "Do While" line I returned to my functioning code and replaced the loop function with an integer based code.
Thank you #Harassed Dad! Your code was a giant help! Using your idea for a string rather than going straight to a debug.print was genius.
The below replaces my code starting where I was having issues.
Dim s As String
For i = 0 To DCount("*", "ALL_SalesOrderItemsLineDates", "ALL_SalesOrderItemsLineDates.SALESID = '" & SL & "'") - 1
s = s & "+" & rst.Fields("Abbr")
rst.MoveNext
Next i
rst.Close
Debug.Print s
My results are displaying with only one hiccup.
+CHA+DEEA+EEP+MEC+PERC+PM+PROP
There is an extra "+" at the beginning, but I'm sure I can find the solution to this tiny problem.
I hope these notes can help someone in the future. Thank you all for your help!
Private Sub Command1492_Click()
Dim i As Integer
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim SQL As String
Set db = CurrentDb
SL = [Forms]![frm_SalesOrderEntry]![Combo617]
SQL = "SELECT tblREF_Chemical.Abbr "
SQL = SQL & "FROM qry_AX_LineItems_DISTINCT INNER JOIN tblREF_Chemical ON "
SQL = SQL & "qry_AX_LineItems_DISTINCT.ItemId = tblREF_Chemical.[Item Number] "
SQL = SQL & "GROUP BY tblREF_Chemical.Abbr, qry_AX_LineItems_DISTINCT.SALESID, "
SQL = SQL & "tblREF_Chemical.[Proper Shipping Name] "
SQL = SQL & "HAVING (((qry_AX_LineItems_DISTINCT.SALESID)='" & SL & "'" 'edit here
SQL = SQL & "AND ((tblREF_Chemical.[Proper Shipping Name]) Is Not Null)); "
Set rst = db.OpenRecordset(SQL)
Dim s as string
Do While rst(0) is not null
s = s & "+" & rst(0)
rst.MoveNext
Loop
rst.Close
Debug.print s
End Sub
Your main issue is a missing space before the AND in HAVING clause.
For this very reason of readability and maintainability, consider using QueryDefs for parameterized queries (an industry best practice) to run your saved query in VBA for several reasons:
You avoid the need to concatenate or enclose quotes or escape literals by effectively divorcing SQL code from VBA (application layer) code.
MS Access will not allow you to save a query with syntax issues but VBA string queries can have such issues found at runtime.
MS Access's engine compiles and caches saved queries to best execution plan which especially helps for aggregate queries with joins. This is why saved queries are usually more efficient than VBA string queries run on the fly.
SQL (save below as a saved query)
Query now uses table aliases and HAVING conditions are moved to WHERE since no aggregate is being used.
PARAMETERS idparam LONG;
SELECT t.Abbr
FROM qry_AX_LineItems_DISTINCT q
INNER JOIN tblREF_Chemical t ON q.ItemId = t.[Item Number]
WHERE (((q.SALESID) = [idparam])
AND ((t.[Proper Shipping Name]) Is Not Null))
GROUP BY t.Abbr, q.SALESID, t.[Proper Shipping Name];
VBA
Dim db As DAO.Database, qdef AS DAO.QueryDef, rst As DAO.Recordset
Dim SQL As String, s As String
Set db = CurrentDb
' INITIALIZE SAVED QUERY
Set qdef = db.QueryDefs("mySavedQuery")
' BIND PARAMETER
qdef![idparam] = [Forms]![frm_SalesOrderEntry]![Combo617]
' OPEN RECORDSET
Set rst = qdef.OpenRecordset()
Do While rst(0) Is Not Null
s = s & "+" & rst(0)
rst.MoveNext
Loop
rst.Close
Debug.Print s
Set rst = Nothing: Set qdef = Nothing: Set db = Nothing

microsoft access 2010 vba dao recordset findfirst

I have a table named QB that has a field name Item. I'm trying to use find first on it with
Dim curDatabase As DAO.Database
Set curDatabase = CurrentDb
Set rsQB = curDatabase.OpenRecordset("QB", dbOpenDynaset)
'This works and equals the value for Item in the first record of the table
msgbox (rsQB("Item").Value)
'Item_No.Value is a string. The following all do not work:
rsQB.FindFirst "[Item] = " & Item_No.Value
rsQB.FindFirst ("[Item] = " & Item_No.Value)
rsQB.FindFirst "[Item] = '" & Item_No.Value &"'"
rsQB.Close

SetFocus is getting ignored - Why?

I have 2 fields - txtTR1_Unit and cmbTR2_Unit. Together, these 2 fields represent the total UNIT.
cmbTR2_Unit has a list of unique values that when selected - txtTR1_Unit automatically gets the related value.
I've created a function called Tier1from2 - that accepts a 'string' and returns the related Tier1 value.
So when I update cmbTR2_Unit in my After_Update event, I'd like to automatically tab to the next field. - Another combo box. I figured that I shouldn't need to set any focus, because it would automatically go to the next field after updating.
txtTR1 gets updated just as expected from my Function, but then it just sits there and won't go to the next field. So I have attempted to 'SetFocus' to the next field after the update.
Still no go. What did I miss??
Private Sub cmbTR2_UNIT_AfterUpdate()
If Len(Me.cmbTR2_UNIT.Value) <> 0 Then
Me.txtTR1_UNIT.Value = Tier1From2(Me.cmbTR2_UNIT.Text)
'cmb_CostCenter.setfocus - 'this doesn't seem necessary - but it doesn't work anyway.
End If
End Sub
As a test I tried removing the function "Tier1From2(Me.cmbTR2_UNIT.text)" simply hard coding the word 'RESULT' in txtTR1_UNIT and it works without a hitch. I know I used to write a more simple function but I haven't touched VBA in awhile - How can I simplify this function:
Private Function Tier1From2(strTier2 As String) As String
Dim qdf As DAO.QueryDef
Dim db As DAO.Database
Dim strQry As String
Dim rs As Recordset
Set db = CurrentDb
Set qdf = db.QueryDefs("qUNIT_HUB")
strQry = "SELECT Tier1_Unit, Tier2_Unit " & _
" FROM LTBL_Cost_Collector " & _
" GROUP BY Tier1_Unit, Tier2_Unit " & _
" HAVING (((Tier2_Unit) = '" & strTier2 & "'));"
qdf.SQL = strQry
db.QueryDefs.Refresh
Set rs = db.OpenRecordset(strQry)
Tier1From2 = rs![Tier1_Unit]
Set db = Nothing
Set qdf = Nothing
Set Recordset = Nothing
End Function
It turns out that something in this function was causing the field and form to loose focus. db.QueryDefs.refresh perhaps? The solution was to update my Function as follows
Private Function Tier1From2(strTier2 As String) As String
Dim rs As DAO.Recordset
Dim db As DAO.Database
Dim strSQL As String
Dim strTier1 As String
Set db = CurrentDb
strSQL = "SELECT Tier1_Unit, Tier2_Unit " & _
" FROM LTBL_Cost_Collector " & _
" GROUP BY Tier1_Unit, Tier2_Unit " & _
" HAVING (((Tier2_Unit) = '" & strTier2 & "'));"
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
strTier1 = rs!Tier1_Unit
Set rs = Nothing
Set db = Nothing
Tier1From2 = strTier1
End Function
This worked without a hitch.

How to set controlsource of a textbox from SQL

I have a subform bound to a SQL statement. Inside the subform, I have a few text boxes bound to the fields of this SQL. However, I have another text box that needs to be bound to a field from a different SQL statement with criteria from the first one. My code looks like below:
Dim subform As Object
Dim formFilter As String
formFilter = "SELECT * FROM my_table_1"
Set subform = Me!my_subform.Form
subform.RecordSource = formFilter
subform.field1.ControlSource = "tb1f1"
subform.field2.ControlSource = "tb1f2"
...
subform.f3.ControlSource = "= SELECT TOP 1 tb2f3 FROM my_table_2 WHERE tb2f1 = '" & [tb1f1] & "' AND tb2f2 = '" & [tb1f2] "' ORDER BY tb2f4"
I cannot use a DLOOKUP function here directly, because I need to sort the table result.
Thanks in advance for your help.
I think I would simply create a little function to go get the result you want. It would probably be best to simply rework DLookup in your own function and add sort but I won't do that here.
First the form code. Notice I am not setting the recordsource, just the value which may not be what you want.
subform.f3 = fGet_tb2f3([tb1f1], [tb1f2])
Then the function code (put in your own error handling)
Public Function fGet_tb2f3(tblf1 as String,tblf2 as String) as String
Dim rst as dao.recordset
Dim db as database
set db = currentdb
set rst = db.openrecordset("SELECT TOP 1 tb2f3 FROM my_table_2 WHERE tb2f1 = '" & tb1f1 & "' AND tb2f2 = '" & tb1f2 "' ORDER BY tb2f4",dbopensnapshot
if not rst is nothing then
if not rst.eof then fGet_tb2f3 = rst!tb2f3
rst.close
set rst = nothing
end if
db.close
set db = nothing
end Function
You can't bind controls on the same form to 2 different recordsets. The only thing you could do is pull data from 2 different recordsets, but that's probably not the best way to do anything.
In order to do that, you'd have to create a second recordset and grab that value in it. Something like:
Dim db as Database
Dim rec as Recordset
Set db = CurrentDB
Set rec = db.OpenRecordset("SELECT TOP 1 tb2f3 FROM my_table_2 WHERE tb2f1 = '" & [tb1f1] & "' AND tb2f2 = '" & [tb1f2] "' ORDER BY tb2f4")
Me.MyControlName = rec(0)

How do I open an Access recordset using a value from another recordset

This should be obvious, but I am stumped.
I am in Access 2007, and I am looping through records. I want to filter the second recordset on the first.
The code is as follows:
Dim db as Database
Dim rst1 as DAO.Recordset, rst2 as DAO.Recordset
Set rst1 = db.OpenRecordset("TABLE1", dbOpenDynaset)
rst1.MoveFirst
Do Until rst1.EOF
rst1.Edit
set rst2 = db.OpenRecordset("SELECT * FROM TABLE2 WHERE ID = 'rst1![ID]';")
....
This does not open a recordset filtered on ID. However, the following code runs without error (where ID = 0001) and I get an appropriately filtered recordset.
set rst2 = db.OpenRecordset("SELECT * FROM TABLE2 WHERE ID = '0001';")
I have tested to make sure that rst1![ID] = 0001. I have placed 0001 in a variable and placed the variable in the statement, also without luck. I did notice that using the rst("ID") syntax causes an immediate error. I also tried building the SQL in the query editor and copying and pasting.
What am I missing?
try something like:
sSql = "SELECT * FROM TABLE2 WHERE ID = '" & rst1!ID & "'"
set rst2 = db.OpenRecordset(sSql)
Change the line to
set rst2 = db.OpenRecordset("SELECT * FROM TABLE2 WHERE ID = '" & rst1![ID] & "';")