Access VBA: Runtime error 3734 - ms-access

Can anyone give me details of
runtime error 3734
in Access vba.
For reference i am getting it from a code in the following thread
How to run a loop of queries in access?
Sub plausibt_check()
Dim rs As DAO.Recordset
Dim rs2 As ADODB.Recordset
Dim db As database
Dim strsql As String
Dim tdf As TableDef
Set db = opendatabase("C:\Codebook.mdb")
Set rs = db.OpenRecordset("querycrit")
Set rs2 = CreateObject("ADODB.Recordset")
rs2.ActiveConnection = CurrentProject.Connection
For Each tdf In CurrentDb.TableDefs ' in this line the error occurs

I don't understand what you're trying to do. Why are you using one DAO recordset and one ADO? This makes no sense at all. If you have saved queries in an Access front end, then even if your back end is, say, SQL Server with ODBC table links, there is really no utility whatsoever in using ADO.
There is no evidence of a loop in your code, so unless your code is being called by a loop, it doesn't seem to me that the KB article explanation would apply.
I don't know what it is you want to do, but the point about opening your database once, rather than in each repetition of your loop, should be pretty obvious to anyone who thinks about it. If you're running a loop and repeatedly opening the same database in each repetition of the loop, it should be obvious that the operation belongs outside the loop.
That would be something like this:
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Set db = CurrentDB()
For Each qdf in db.QueryDef
[do whatever here]
Next qdf
Set qdf = Nothing
Set db = Nothing
In that code, you're using the MDB currently open in the user interface, but it doesn't matter -- whichever database you're opening and looping through its objects should be opened only once, outside the loop.
If you want to have your loop be in a subroutine called from your main code, then pass the database variable as an argument to your subroutine. The subroutine would be something like this:
Public Sub ProcessQueries(db As DAO.Database)
Dim qdf As DAO.QueryDef
For Each qdf in db.QueryDef
[do whatever here]
Next qdf
Set qdf = Nothing
End Sub
And you would call that thus:
Dim db As DAO.Database
Set db = CurrentDB()
Call ProcessQueries(db)
Set db = Nothing
Now, if you insist on getting source data from DAO and then doing something with it via ADO, you'd have a DAO loop and inside it, and ADO loop. Because of that, you'd want to define your ADO connection outside your DAO loop, rather than inside it. The only exception to that would be if the data you're pulling from your DAO loop defines which database you're opening with ADO. As we don't know what you're actually trying to accomplish, it's pretty much impossible to give good advice on exactly what you should change in your code.

It seems that you are using ADO in the current database without saving. You must save before running code that contains ADO.

Related

Invalid Connection String In Pass-Through Query In MS Access VBA

I tried using Pass-Through query to call mysql stored procedure from MS Access VBA. This is the code:
Dim qdf As DAO.QueryDef
Dim rst As DAO.Recordset
Set qdf = CurrentDb.CreateQueryDef("")
qdf.Connect = "DRIVER={MySQL ODBC 5.3 Unicode Driver};SERVER=localhost;PORT=3306;DATABASE=accounting_supp_db;User=xxx;Password=xxx;Option=3"
qdf.SQL = "CALL MyStoredProcedure('10156','2021-03-03','2021-03-10')"
qdf.ReturnsRecords = True
Set rst = qdf.OpenRecordset
rst.Close
Set rst = Nothing
Set qdf = Nothing
But it return error 3305: Invalid Connection String In Pass-Through Query. Is there somothing wrong with the connection string?
thx
Well, one way to figure this out?
Simply use the external data from the ribbon - and link a table from access to MySQL. Get that working - once you do?
Then do this in your code:
dim rst as DAO.RecordSet
With CurrentDB.queryDefs("MyPTQuery")
.Connection = currentdb.tableDefs("The working linked table").Connection
.SQL = "CALL MyStoreProc('10156','2021-03-03','2021-03-10')"
set rst = .OpenRecordSet
End if
You could I suppose add to above .ReturnsRecords = True, but then again?
Well, create that one PT query - set the connection correct. Then you can do this in code:
Dim rst1 as DAO.RecordSet
Dim rst2 as DAO.ReocrdSet
With Currentdb.tableDefs("MyPTQuery")
.SQL = "CALL MyStoredProcedure('10156','2021-03-03','2021-03-10')"
set rst1 = .OpenRecordSet
END with
With Currentdb.tableDefs("MyPTQuery")
.SQL = "CALL MyStoredProcedure('10777','2021-04-03','2021-05-10')"
set rst2 = .OpenRecordSet
End With
Note how we don't mess with creating a query def. And note how we can use the ONE pt query over and over.
And it gets better Say you want that stored procedure for a report? Well base the report on "MyPTQuery"
Then do this:
With Currentdb.tableDefs("MyPTQuery")
.SQL = "CALL MyStoredProcedure('10777','2021-04-03','2021-05-10')"
End With
docmd.OpenReport "rptCustomerProjects", acViewPreview
In fact, you can write the above like this:
Currentdb.tableDefs("MyPTQuery").SQL = "CALL MyStoredProcedure('10777','2021-04-03','2021-05-10')"
docmd.OpenReport "rptCustomerProjects", acViewPreview
So I quite much recommend that you SAVE the connection string in the PT query. That way, your code has no messy connection strings - and such connections are now "out" of your code - you can easy change the connection for the whole database - not change any code.
So, when you run your table re-link code? Have that re-link code ALSO update any PT query. That way you can now re-link and point your application to a test database, or production one, or whatever. So, no connection strings in code are the result of the above.
Regardless of above? Get a linked table working - and then use that "steal" the known connection from the linked table and shove it into the connection for the PT query as per first example above.

OpenRecordset not recognisng query criteria

I have developed an Access Database query which references an object on a form in order to dynamically filter the data. The criteria upon which the query is filtered is as follows:
[Forms]![frmMain]![NavigationSubform].[Form]![Frame64]
Where [frame64] is where the user chooses one of two options on a form.
Whilst this query runs fine in Access, I want to use this query in a piece of VBA code, but the problem is, when I try to open the record set, VBA won't allow me.
Dim db As Database
Dim rs As Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("qryMergeEzineCompleteMerges", dbOpenDynamic, dbSeeChanges)
Through my research, I have discovered that it is because VBA doesn't recognise the query criteria I have defined as it refers to a form.
Can anyone please show me how I can reference this recordset in VBA so that it filters by the criteria I have stipulated in the query itself?
Many thanks
You need to open the Recordset through a QueryDef.
Sub Whatever()
Dim db As Database
Dim qdf As QueryDef
Dim rs As Recordset
Set db = CurrentDb()
Set qdf = db.QueryDefs("qryMergeEzineCompleteMerges")
'add any parameters here
With qdf
.Parameters("[parameter1]").Value = value1
.Parameters("[parameter2]").Value = value2
End With
Set rs = qdf.OpenRecordset(dbOpenDynaset)
'...
rs.Close
Set rs = Nothing
qdf.Close
Set qdf = Nothing
Set db = Nothing
End Sub
This may sound pretty stupid but the easiest way to solve this is to create two constants for the dbOpenDynamic and dbSeeChanges values and set their values to the right integer values. You can of course also just type the relevant integer values in the OpenRecordset call.

VBA Variables inside DoCmd.RunSQL

Just a question. Situation is as follows:
I have 15 make table queries that pulls data for a different submission clarification code that was used on a claim; i.e. Pull all claims where submission clarification code 5. As of right now I have a macro that will run all 15 queries, but each time I am required to type in the region I am filtering for due to the [What Region?] prompt I had put in the criteria field.
My question is:
Is it possible to use VBA to run all 15 queries using the DoCmd.RunSQL where I only have to type in the region number once and it will apply it to all queries?
My initial thoughts were I would have VBA prompt me for what region I'm filtering for, store that in a variable, and then use that variable in the SQL statement. But I'm not even sure if you can do that? Thanks in advance for any advice that may be given!
Update: So after reading a few threads, I created a mock database to try out some of the concepts and I think I might be on the right track?
Private Sub btnTest_Click()
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim SQLString As String
SQLString = "SELECT tblEmployees.ID, tblEmployees.Last_Name, tblEmployees.First_Name, tblEmployees.SS_ID INTO Test" _
& "FROM tblEmployees" _
& "WHERE (((tblEmployees.ID)=[What number]));"
Set qdf = CurrentDb.QueryDefs("Query1")
qdf.Parameters(0).Value = InputBox("What is the ID Number")
qdf.Execute
qdf.Close
Set db = Nothing
Set qdf = Nothing
End Sub
So to apply this to the 15 queries I would just Dim other variables as DAO.QueryDef right? I'm note really sure i need the SQLString part either? Also, I noticed that when running this mock code it took quite a while for it to create the new table. Is this normal? Also also, the code will not run if the table it is creating already exists. Is there a way to just have the code replace the existing table with the new one? Kind of new to this VBA so thanks for your patience.
Short answer is yes, this is possible. Some keywords you want to familiarize yourself with are "parameters" which are the variables with the prompt and "Querydef" or query definition.
There are quite a few articles detailing how to pass parameter values to a query programmatically. Check out this page for a solid overview of how to accomplish this. Most notably, the last example uses an inputbox to prompt the user to provide the parameter value, which gets you close to what you need. (ie. cmd.Parameters(0).Value = InputBox("Enter a country name"))
Modified to your design, it might be best to create a string variable and ask for the parameter first, then use the variable in declaring the parameters individually, which would permit a single parameter submission that gets applied to all queries.
EDIT
I have adjusted your code to show you how to go about it. You will have to repeat the block for each query.
Private Sub btnTest_Click()
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim strParamter As String
Set db = CurrentDb
strParamter = InputBox("What is the ID Number")
Set qdf = db.QueryDefs("Query1")
qdf.Parameters(0).Value = strParameter
qdf.Execute
qdf.Close
'Now move to next query
Set qdf = db.QueryDefs("Query2")
qdf.Parameters(0).Value = strParameter
qdf.Execute
qdf.Close
'...etc.
Set qdf = Nothing
Set db = Nothing
End Sub

Recordsource vs Recordset for Unbound Forms

I am creating a application which uses Access ADP (Access Data Project). as the front-end and SQL Server as the back end. I am using ADODB for the connection. I have been doing some research as to whether to use the RecordSource property or Recordset property for forms. My goal is to create an unbound application.
I haven't been able to get a clear answer on which one to use. So far, what I have been able to do is set the recordsource to the stored procedure like this
strSQL = "exec STOREDPROCEDURE "
Me.Form.RecordSource = strSQL
I can also open the same SQL str as a recordset, set the forms recordset then close the recordset like this
Dim Cmd As New ADODB.Command
Dim rs As New ADODB.Recordset
Set rs = New ADODB.Recordset
strSQL = "exec STOREDPROCEDURE"
rs.Open strSQL, CurrentProject.Connection
Set Me.Recordset = rs
rs.Close
Can someone explain to me what the differences are between the 2 and which is the preferred method? The way I see it, the data is getting filtered on SQL Server before being passed back to the application, so I am not seeing the difference between using Recordset or Recordsource.
With an .adp, you will use record source, not recordset, though you may depending on what version of access you are running, need also to set the input parameters property as well.
Me.RecordSource = "EXEC schema.storedprocedue [arguments]"
will work fine for forms.
One comment I would make however is - why an .adp? MS Access 2013 & Later will not run an adp, and Access 2010 is likely to become unsupported in another couple of years.

Connection string for Access to call SQL Server stored procedure

Using Access 2007, I want to call a stored procedure with one input parameter that returns a recordset.
Using ADODB, this is pretty straightforward except for the connection string. I want to be able to derive the server and database names from a particular table, which always points to the correct server and database. (I reconnect to development dbs from time to time for testing by relinking the 100 or so linked tables.)
Is there a way to get the server and database name from the tabledef without parsing the whole thing out? Is there a property? I haven't found one yet....
Final query is pretty simple: EXEC sp_DeleteProjects N'12,24,54' deletes projects 12, 24, and 54, and returns a recordset (single row) with the deleted record counts of the various child table entries.
If you already have an Access linked table pointing to the SQL Server database then you can simply use its .Connect string with a DAO.QueryDef object to execute the Stored Procedure, as illustrated by the following VBA code:
Sub CallSP()
Dim qdf As DAO.QueryDef, rst As DAO.Recordset
Set qdf = CurrentDb.CreateQueryDef("")
qdf.Connect = CurrentDb.TableDefs("dbo_MyTable").Connect
qdf.SQL = "EXEC dbo.MyStoredProcedure"
qdf.ReturnsRecords = True
Set rst = qdf.OpenRecordset(dbOpenSnapshot)
Debug.Print rst(0).Value
rst.Close
Set rst = Nothing
Set qdf = Nothing
End Sub