Access 2007 Error 3151 from DAO.OpenRecordSet. How to fix? - vba

Well this is fascinating. I am using MS-Access 2007 to make a from that will allow users to enter data from lab results.
The from utilizes a VBA code call:
DAO.OpenRecordset("{Sql query}" , DB_OPEN_DYNASET, dbSeeChanges)
This call normally works just fine, but I've noticed that when this form is closed and then re-opened, a 3151 ODBC error is generated.
We are using linked tables through Access 2007 for this form, our SQL-Server 2012 version is as follows.
Microsoft SQL Server Management Studio 11.0.2100.60
Microsoft Analysis Services Client Tools 11.0.2100.60
Microsoft Data Access Components (MDAC) 6.1.7601.17514
Microsoft MSXML 3.0 6.0
Microsoft Internet Explorer 8.0.7601.17514
Microsoft .NET Framework 4.0.30319.237
Operating System 6.1.7601
The DAO.OpenRecordset call is utilized in multiple events. Here is the list.
On_Current , _AfterUpdate , Form_Unload
I have found several reported instances of similar errors on Access 2007 with linked tables to SQL-Server, but none seem to have workable solutions for this issue.
As best I can tell, the 3151 doesn't appear to be affecting the form or data in any negative way. I am able to open the form and everything is where it should be as best I can tell. There are about 20 thousand records on this table, so I may be missing something.
Does anyone have any ideas?
9/14 In response to comments I am adding some additional code.
Here is the call on Form_Unload. It contains the failing line.
Private Sub Form_Unload(Cancel As Integer)
Dim ImportID
Dim rst As DAO.Recordset
Dim db As Database
Set db = CurrentDb
Set ImportID = Me.ImportID
#This is the failing line below.
Set rst = db.OpenRecordset("SELECT [dbo_t_inspect].* FROM [dbo_t_inspect] WHERE [dbo_t_inspect].ImportID= " & ImportID & ";", DB_OPEN_DYNASET, dbSeeChanges)
Here is the call from On_Current. This On_Current call is actually made by a sub-form on the main form.
Private Sub Form_Current()
Dim rst As DAO.Recordset
Dim strImportID As String
If IsNull(Me.ImportID) Then
[Forms]![Inspection Receiving]![LabComplete].Visible = False
[Forms]![Inspection Receiving]![LabPending].Visible = True
Else
strImportID = Me.ImportID
Dim db As Database
Set db = CurrentDb
Set rst = db.OpenRecordset("SELECT [dbo_t_health].*, [dbo_t_health].ImportID FROM [dbo_t_health] WHERE ((([dbo_t_health].ImportID)=" & Me.ImportID & "));", DB_OPEN_DYNASET, dbSeeChanges)
I am not sure where DAO is defined in this solution. I cannot find it's declaration in my folder titled Microsoft Office Access Class Objects I am open to suggestions on where that might be located.
The precise error message is as follows
Failed to connect to {ODBC Connection Name} Error 3151.
I can then select the debug option and the debugger will take me to the line that tried and failed to connect the the ODBC Connection I am using.
The Error is highly reproducible. All I have to do is enable VBA Macros on the Security Alert and then open the form in question. I close out the form after it loads. Once I attempt to reopen the form, I get the error described above. The Form opens anyway after I click Ok on the error.

Related

Can't connect to Access DB, neither with OleDB, DAO, etc

I want to read and write data from a CATIA macro to and from an Access DataBase. I've got Windows 10 and Office 2013 on it (64bit Windows).
Unfortunately I can't connect to that Access DataBase from VBA. (From VB.NET works fine)
I tried it all:
Various connection strings (JET.4.0, ACE.12.0) etc with ADODB
-> Error that Provider cant be found
Connection via DAO
-> Various other errors
Any idea why I cant connect?
I referenced all DLLs possible to reference, etc.
Only idea I have that theres a problem with Access 2013 32bit and the 64 bit Windows?
I tried from Excel with the following code (source), it works like a charm.
Sub test()
Dim cnn As ADODB.Connection 'Requieres reference to the Microsoft
Dim rs As ADODB.Recordset 'ActiveX Data Objects Library
Set cnn = CreateObject("adodb.Connection")
cnn.Open "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\Users\someFolder\myDb.accdb;"
Set rs = cnn.Execute("SELECT * FROM versions")
While Not rs.EOF
Debug.Print rs(1), rs(2), rs(3)
rs.MoveNext
Wend
rs.Close
End Sub
if that doesn't work, the client PC may lack a piece of software ?

Access VBA Module cannot get data from Form

OK, so my database was originally designed in Access 2003. On one of the machines I am using a Access 2007 Runtime as the machine does not have Office of any flavor. I am trying to find a solution using the latest version of Access in Office 365. I cannot directly access either the live version running on either Access 2003 or Access 2007 Runtime. I cannot change the versions on the other machines as these are located in a prison and have no internet. This works without issue running in 2003, only the 2007 is the issue. As I am not there and only have 365, I need a solution that will work for all versions.
The functions being used are in separate modules and are not on the actual form. The form is set to have module as that is required to access the objects. The function is to add an session for an inmate to attend the library. This must be verified to make sure there is room at the time and day of week selected, as well as individual session limits.
The issue I am dealing with is the 2007 and 365 versions are unable to get the selected data from a list box (time as a string) and option group (DayofWeek as number) to complete a SQL query instead it inserts nothing and the SQL fails claiming there is an extra ) in my code. The SQL is then used to create a DAO recordset. This is part of a verification of data to ensure limits are not reached.
I have triple checked the string sent to CO_GetSessionDetail to ensure I do not have an extra ). It thinks it does as there is nothing on the right side of my = in the string. I checked the reference to the form and the unbound fields and they all match. It compiles no problem.
THERE IS NO ISSUE IN 2003 ...
The code is posted below.
Function CO_NewCallout() As Boolean
...
' Get Session ID --------------------------------- '
With Form_f_COs_IM
iSession = CO_GetSessionDetail( _
"SessionID", _
"(((t_CO_Sess.DayOfWeek) = " & .CO_Add_DayOfWeek & ") AND " & _
"((t_CO_Sess.tSession) = '" & .CO_Add_tSession & "'))" _
)
If iSession = 0 Then
GoTo CO_NewCallout_Exit
End If
End With
...
End Function
Function CO_GetSessionDetail(stfield As String, stwhere As String) As Variant
'On Error Resume Next
' Variable Declerations -------------------------- '
Dim db As Database
Dim rst As DAO.Recordset
Dim stSQL As String
' Set Variables ---------------------------------- '
Set db = CurrentDb
If stwhere <> "" Then
stwhere = "WHERE " & stwhere
End If
stSQL = _
"SELECT * " & _
"FROM t_CO_Sess " & stwhere
Set rst = db.OpenRecordset(stSQL, dbOpenDynaset)
' Get Session ID --------------------------------- '
With rst
If Not .EOF Then
CO_GetSessionDetail = .Fields(stfield)
Else
CO_GetSessionDetail = 0
End If
End With
' Close Recordset t_CO_Sess ---------------------- '
rst.Close
Set rst = Nothing
End Function
Access 2003 - I get the unique ID of the Session
Access 2007 and 365 - cannot complete function
Let me know if more code would help.
An Access application compiled using Office 365 will not be compatible with the Access 2007 runtime or Access 2003. You must compile on a version earlier or equal to the runtime you choose. Unfortunately, it is hard to get the Access 2003 runtime because it is not freely downloadable. The 2007 runtime is freely available (which probably explains why you chose to install the later version).
Your code looks OK, and I assume it compiles and all that. Despite the fact that your 2003 database should work with the Access 2007 runtime, the fact that it doesn't says to me that you have an incompatibility you need to resolve.
Your best bet: upgrade your app to 2007 or later, ensure it works in the new version, and install the matching runtime on your client's machines.
References:
General discussion of Access version compatibility:
Access 2016/2010 Compatibility, Access 2016
Article on getting the Access 2003 Runtime:
MS Access Runtime 2003

Use DBEngine with Run-time Access

i try to connect my xls with access database. Below code work greate when i have installed full access program on my machine. Problem is when i try tu use it on machine what have only installed Run-time version of access.
I have use this references:
Visual Basic For Applications
Microsoft Excel 14.0 Object Library
OLE Automation
Microsoft Office 14.0 Object Library
Microsoft Forms 2.0 Object Library
When i try to run below code i get error: ActiveX component can't create object or return reference to this object (Error 429)
Sub mcGetPromoFromDB()
Application.ScreenUpdating = False
Dim daoDB As DAO.Database
Dim daoQueryDef As DAO.QueryDef
Dim daoRcd As DAO.Recordset
'Error on line below
Set daoDB = Application.DBEngine.OpenDatabase("K:\DR04\Groups\Functional\DC_Magazyn\Sekcja_Kontroli_Magazynu\Layout\dbDDPiZ.accdb")
Set daoRcd = daoDB.OpenRecordset("kwPromoIDX", dbOpenDynaset)
Dim tempTab() As Variant
For Each Article In collecArticle
daoRcd.FindNext "IDX = " & Article.Index
Article.PromoName = daoRcd.Fields(1).Value
Article.PromoEnd = "T" & Format(daoRcd.Fields(2).Value, "ww", vbMonday, vbUseSystem)
Next
Application.ScreenUpdating = True
End Sub
Is IDX an indexed field?
Is kwPromoIDX optimized for this specific purpose? I mean does it only contain the fields required for this update, or are you pulling extra useless fields? Perhaps something like "SELECT IDX, [Field1Name], [Field2Name] FROM kwPromoIDX" would be more efficient.
Since you are only reading the table records, and don't seem to need to actually edit them instead of dbOpenDynaset, use dbOpenSnapshot.
Just throwing out an idea here, you'd have to test to see if it made any difference, but perhaps you could try to reverse your logic. Loop through the recordset 1 by 1 and locate the IDX within your worksheet.
Another thing I've done in the past is use .CopyFromRecordset and copied the entire recordset into a temporary worksheet and done the juggling back and forth entirely within Excel, to eliminate the back and forth.
Lastly, another approach can be to quickly loop through the entire recordset and populate an array, collection, ... and then work with it instead of Access. This way the data is all virtual and you reduce the back and forth with Access.
You'll need to do some testing to see what works best in your situation.

Are Access 2010 databases not accessible with Excel if password protected using default encryption (High Security)?

I am currently supporting an Excel 2010 spreadsheet and Access 2010 database that were written by business users. One of the requirements of the Access database is that it be encrypted. It was encrypted with the default encryption settings "Use default encryption(Higher security)" which can be set in Options -> Client Settings.
Now that the database is password protected and encrypted, I am unable to connect to the database through Excel. My testing revolves around importing data into Excel, but what I really need to do is create a row in a log table. I am trying both to import directly to the sheet using the "Data" tab and "From Access" selection and through VBA code. Using the Excel interface, the password dialog box comes up and will never accept the correct password. Using VBA and ADO, the Open statement throws a "not a valid password" error. Both methods work fine if I encrypt the database using the "Use legacy encryption" setting.
I thought it also may be my setup, I'm using Windows 7 32-bit and Office 2010. I have also tried with Windows 8.1 64-bit using Office 2013 with the same results. It works with legacy encryption, but not with default encryption. I didn't try anything earlier. The default higher security encryption was introduced with Office 2010 and Windows 7.
My research has led me to this Technet thread and this Stackoverflow question, both suggesting that Excel cannot interact with Access using the default encryption method. I haven't found a whole lot more discussing this exact issue.
My question to you is does password protecting an Access 2010 database using the default settings really prevent Excel 2010 from importing data (when using the password)? Something about that doesn't sound right to me since sharing data between the two applications is a pretty basic function. I also think that if it were an issue, Google would have turned up more information about it. My guess at this point is that Excel and Access are using the Next Generation encryption engine by default, but that the ADO library has not been updated to use it.
I've attached the connection code for review. For testing I am doing a simple Now() command and emitting the results. The connection fails on the open with a "not a valid password" error even when using the correct password. Works with legacy encryption, not with default encryption.
Sub ADOCNGConnect()
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim ds As String
'setting up connection
Set cn = New ADODB.Connection
With cn
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source='FILEPATH'" & _
";Jet OLEDB:Database Password=password"
.Open
End With
'setup recordset object
Set rs = New ADODB.Recordset
'retrieve new number
rs.Open "SELECT Now() AS qryTest", cn, adOpenKeyset
MsgBox rs!qryTest
rs.MoveLast
'close ADO object vars
rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing
End Sub
According to ConnectionStrings.com, the ACE provider doesn't work with the new stronger Access 2010 db encryption:
"Note! Reports say that a database encrypted using Access 2010 - 2013 default encryption scheme does not work with this connection string. In Access; try options and choose 2007 encryption method instead. That should make it work. We do not know of any other solution."
However, that doesn't tell the whole story. Your code worked as an Access VBA procedure and successfully connected to another ACCDB which had the stronger Access 2010 encryption. But I could not find any way to make similar code work as an Excel VBA procedure.
Eventually I abandoned that effort. Since your goal seems to be to make an ADO recordset containing Access data available to Excel, I decided to automate Access and use its CurrentProject.Connection.Execute method to load the recordset.
This may seem kind of clunky, but it works ...
Const cstrPath As String = "C:\Users\hans\Documents\a2010_DbPass_foo.accdb"
Const cstrPwd As String = "foo"
Dim objAccess As Object ' Access.Application
Dim rs As Object ' ADODB.Recordset
Dim strSelect As String
Set objAccess = CreateObject("Access.Application")
objAccess.Visible = True
objAccess.OpenCurrentDatabase cstrPath, , cstrPwd
'strSelect = "SELECT Now() AS qryTest"
strSelect = "SELECT some_text AS qryTest FROM tblFoo"
Set rs = objAccess.CurrentProject.Connection.Execute(strSelect)
MsgBox rs!qryTest
rs.Close
Set rs = Nothing
objAccess.Quit
Set objAccess = Nothing
Note when I used "SELECT Now() AS qryTest" for strSelect, Access crashed at .Quit I don't understand why that happened. But the code worked trouble-free in Excel 2010 as written.

calling Access query from Excel macro

I have a VBA macro in Excel that calls a query in an Access database (.mdb). However, the Access has been updated to a .accdb file and I don't know how to change up the macro (and/or include any libraries as I don't truly understand that part yet) so that the code will work.
Here is the current "header" code:
'Step 1: Declare your variables
Dim MyDatabase As DAO.Database
Dim MyQueryDef As DAO.QueryDef
Dim MyRecordset As DAO.Recordset
'Step 2: Identify the database and query
Set MyDatabase = DBEngine.OpenDatabase("C:\Users\Ben\Google Drive\Database\Production\FOREAL PROD.mdb")
If you are getting an "unrecognizable database format" error then your Excel project may be using an older DAO (Data Access Objects) reference that does not know how to deal with .accdb files.
In the VBA window, choose Tools > References.... If you see an old DAO reference like...
"Microsoft DAO 3.6 Object Library"
...then that could explain the problem.
You'll want to upgrade that old DAO reference to this one...
"Microsoft Office 14.0 Access Database Engine Object Library"
...and to do that you'll need to download and install the Microsoft Access Database Engine 2010 Redistributable from here.