From MS Excel VBA, create a Standard Module in MS Access - excel

From VBA in Excel (2013), I need to create a standard module in a MS Access (2013) database. I am open to any and all ideas - Thanks!

OK, I have it working, but I am sure there are aspects that could/should be done differently. As a reminder, the code below is in MS Excel. Here is the code:
'REQUIRES: MS Access 12.0 Object Library
Dim ObjAccess As Access.Application
Dim strPath As String
strPath = "C:\Temp\MyDB_DEV_1.MDB"
Set ObjAccess = New Access.Application
With ObjAccess
.OpenCurrentDatabase strPath, True
.DoCmd.RunCommand acCmdNewObjectModule
.DoCmd.Save acModule, "Module1"
.DoCmd.Rename "MyCodedModule", acModule, "Module1"
.CloseCurrentDatabase
.Quit
End With
Set ObjAccess = Nothing`

The natural evolution of the previous solution is to want to add code to the new module. I decided to take an alternate route and "import" an existing standard module into the remote MS Access db. A final step in the evolution is to remotely run a procedure that is within the standard module that was imported into the remote db. Again, this code is located in Excel VBA. The code that accomplishes these two tasks are as follows:
'FROM EXCEL, REMOTELY INSTRUCT A MS ACCESS db
'IMPORTS .BAS FILE INTO db
'EXECUTE THE 'RoutineWithinModule1' THAT IS WITHIN MODULE1 OF THE REMOTE db
Dim appAccess As Access.Application
Set appAccess = New Access.Application
With appAccess
.OpenCurrentDatabase "C:\Temp\MyDB_DEV_1.mdb"
.VBE.ActiveVBProject.VBComponents.Import "C:\Module1.bas"
.DoCmd.Save acModule, "Module1"
.Run "RoutineWithinModule1"
.CloseCurrentDatabase
.Quit
End With
Set appAccess = Nothing

Related

Run-Time Error 7866 with OpenCurrentDatabase

When I run the code below I get Run-Time Error 7866:
Microsoft Access can't open the database because it is missing or opened exclusively by another user, or it is not an ADP file.
The error is thrown on this line
db.OpenCurrentDatabase "C:\Users\QE9142\Desktop\VES Mgmt Reports ONLY.mdb"
I am trying to open an Access database that is saved on my desktop through Excel.
Sub Task()
Dim db As Access.Application
Dim strDB As String
Set db = New Access.Application
db.OpenCurrentDatabase "C:\Users\QE9142\Desktop\VES Mgmt Reports ONLY.mdb"
db.Application.Visible = True
End Sub
I can't replicate this error, but when the code exits, so does Access.
Insert a STOP or other event that will hold the code:
Sub Task()
Dim db As Access.Application
Dim strDB As String
Set db = New Access.Application
db.OpenCurrentDatabase "C:\Users\QE9142\Desktop\VES Mgmt Reports ONLY.mdb"
db.Application.Visible = True
Stop
End Sub
As for the error, try opening the mdb in Access and save it as an accdb file (Access 2007 format).
If user should take control of database once opened, don't see need for connection object. Use Shell command to simply open database file. Then user can do whatever they want with it.
Shell "cmd /c " & Chr(34) & "C:\Users\QE9142\Desktop\VES Mgmt Reports ONLY.mdb" & Chr(34)

Excel VBA procedure crashes when opening a Access database connection/using Access Runtime

When executing a VBA procedure from Excel to connect to an Access database using Microsoft Access Runtime 2016 on my second laptop, the VBA procedure seems to freeze processing for a few seconds, crashes and closes the Excel application without triggering the error handler in my code so there is no error message for me to decipher. What can be the issue or how can I trap the error?
This VBA application works fine on my first laptop which has the full version of Access with no issues. The second laptop was working before I loaded Microsoft Access Runtime 2016. I was using a database application called "MDB Plus" which reads Access database files but now that doesn't work anymore.
I'm using the following:
OS: Windows 10,
MS Office: 2007,
MS Access Runtime 2007-2016,
Excel VBA 2007
To try to resolve this I: 1.) Uninstalled MS Access Runtime 2016 and the Excel application still crashed, 2.) Install MS Access Runtime 2007 and the Excel application still crashes.
Here is my code:
Sub TestGetTblPrimKey()
Dim oDBConn As ADODB.Connection
Dim sDBConnString As String
Dim moDBTblRecordSet As ADODB.Recordset
Const sDBTableLocPath As String _
= "C:\Users\kmass\AppData\Roaming\InvestManager\"
'
On Error GoTo ERROR_HANDLER
'
'Create Database connection
Set oDBConn = New ADODB.Connection
'Create Table Record-Set
Set moDBTblRecordSet = New ADODB.Recordset
'Build DB connection string
sDBConnString = _
"Provider=" & "Microsoft.ACE.OLEDB.12.0" & ";" _
& "Data Source='" _
& sDBTableLocPath _
& "tMeta_Table_Master.accdb" & "'"
'Open Database Table and Record-Set
oDBConn.Open sDBConnString '* <--CRASHES HERE
'
' Call ... the rest of the code to get record key
'
TestGetTblPrimKeyExit:
oDBConn.Close
'Release Table Objects
Set moDBTblRecordSet = Nothing
Set oDBConn = Nothing
Exit Sub
'
ERROR_HANDLER:
Debug.Print Err.Number & vbCrLf & Err.Description
Resume TestGetTblPrimKeyExit
'
End Sub
I expected the code to connect to the Access Database.
You can easily control Access from Excel, and do all kinds of things within the Access object, from Excel. Here are three simple demos of what you can do.
1)
'Open MS Access Form, from Excel
Global oApp As Object
Sub OpenAccess()
Dim LPath As String
Dim LCategoryID As Long
'Path to Access database
LPath = "C:\your_path_here\Northwind.mdb"
'Open Access and make visible
Set oApp = CreateObject("Access.Application")
oApp.Visible = True
'Open Access database as defined by LPath variable
oApp.OpenCurrentDatabase LPath
'Open form of interest
oApp.DoCmd.OpenForm "Form1"
End Sub
2)
'RUN MS ACCESS MACRO FROM EXCEL:
Sub AccessTest1()
Dim A As Object
Set A = CreateObject("Access.Application")
A.Visible = False
A.OpenCurrentDatabase ("C:\your_path_here\Northwind.mdb")
A.Application.Run "ExportToExcelTest"
End Sub
3)
' Run a delete query in MS Access, from Excel
Sub OpDaHus01()
Dim strDatabasePath As String
Dim appAccess As Access.Application
Dim strSQL As String
strDatabasePath = "C:\your_path_here\Northwind_2012.mdb"
strSQL = "DELETE tblTest.* FROM tblTest;"
Set appAccess = New Access.Application
With appAccess
.OpenCurrentDatabase strDatabasePath
.DoCmd.RunSQL strSQL
.Quit
End With
Set appAccess = Nothing
End Sub
If you need to run the code from a Macro, it needs to be a Public Function (rather than Sub), and it needs to be in a standard module (not a Form, Report or Class module).

How to export data from Excel to Access via Excel Macro when multiple instances of Excel are open

I am using an Excel macro to define a data range in Excel and then call "objAccess.DoCmd.TransferSpreadsheet" to import the data from this range into an Access table. This import does not work all of the time.
I have come to the conclusion that the macro works fine when there is only one instance of Excel open. However, the data import fails when another instance is already open. In the latter case the Access database opens up and the Excel file from which I run the macro is being reopened (in read-only mode) in the other Excel instance. There is no actual error but the desired import is not being carried out. Why does this happen?
Sub Excel_2_Access()
Dim strPath As String
Dim strwbPath As String
Dim strRange As String
Dim objAccess As Access.Application
Dim wbActive As Workbook
'get database path
strPath = Worksheets("error").Range("Access_DB_Path").Value & "\" & Worksheets("error").Range("Access_DB").Value
'open database
Set objAccess = New Access.Application
Call objAccess.OpenCurrentDatabase(strPath)
objAccess.Visible = True
'access import
Worksheets("error").Columns("P:P").Calculate
Set wbActive = ActiveWorkbook
strwbPath = Application.ActiveWorkbook.FullName
strRange = "error!M2:M" & (Worksheets("error").Range("WKN_count").Value + 2)
Call objAccess.DoCmd.TransferSpreadsheet(acImport, 8, "WKN_Mapping", strwbPath, True, strRange)
objAccess.Forms("MX_Import").Refresh
End Sub
As the macro is fairly short I have included the entire code for your reference. However, I don't think the way the range is specified or names are provided is really relevant to the question.
The desired outcome would be to have an Excel macro in place that carries out the transfer from Excel to Access no matter if there are other instances of Excel open or not.
Is there such a thing as the primary instance of Excel (the first one that was opened) which has a special status? Is there a way to provide the specific Excel instance the workbook is in when calling the Access function from Excel? Or is there a more reliable way to transfer the data which generally avoids this problem with multiple instances?
I tested approach that opens Access db and runs TransferSreadsheet. Don't need to set a workbook object (your code sets but then doesn't even utilize). It ran without error every time. I tried setting the Access object Visible but the database appears and immediately closes anyway, although the data import does happen. Set reference libarary: Microsoft Access x.x Object Library.
Sub test()
Dim ac As Access.Application, strRange As String
Set ac = New Access.Application
strRange = "Sheet1!A1:E3"
ac.OpenCurrentDatabase "C:\Users\June\LL\Umpires.accdb"
ac.DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, "Rates", ThisWorkbook.FullName, True, strRange
End Sub
Example Excel VBA code that exports all rows of worksheet to existing table in Access without opening Access file. Setting an ADODB connection makes the Execute method available. This approach runs faster. Set reference library: Microsoft ActiveX Data Objects x.x Library.
Sub test()
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 8.0"
cn.Execute "INSERT INTO Rates(RateLevel, Rate, Pos, EffDate) IN 'C:\Users\June\LL\Umpires.accdb' " & _
"SELECT RateLevel,Rate,Pos,EffDate FROM [Sheet1$];"
cn.Close
Set cn = Nothing
End Sub

Transfer Excel data to Access

I'm following the instructions here http://software-solutions-online.com/excel-vba-export-worksheet-to-existing-access-table/ to transfer data from an Excel spreadsheet to an Access database. The script I have adapted is:
Sub MailMerge2()
Dim strPath As String
Dim objAccess As Access.Application
Dim strExcelPath As String
strPath = "C:...Documents\MailMerge2"
strExcelPath = Application.ActiveWorkbook.FullName
Set objAccess = New Access.Application
Call objAccess.OpenCurrentDatabase(strPath)
objAccess.Visible = True
Call objAccess.DoCmd.TransferSpreadsheet(acImport, _
acSpreadsheetTypeExcel8, "MyTable1", strExcelPath, _
True, "A1:D11")
End Sub
However, running this gives me an error saying:
Run-time error: 7866, Microsoft Access can't open the database
because it is missing, or opened exclusively by another user, or it is
not an ADP file.
Any suggestions on which of these the problem is? I'm fairly new to Access, and haven't quite got the hang of the terminology yet.
Found the problem. I left out .accdb in my Access db file names.

Open an Access database and run one of its Macros from Excel

From Excel, I need to open an Access database and run one of the database's macros.
I'm using Excel and Access 2007. Here is my code in Excel:
Sub accessMacro()
Dim appAccess As New Access.Application
Set appAccess = Access.Application
appAccess.OpenCurrentDatabase "C:\blah.mdb"
appAccess.Visible = True
appAccess.DoCmd.RunMacro "RunQueries.RunQueries"
appAccess.CloseCurrentDatabase
End Sub
In the Access database, there is a procedure named RunQueries in a module named RunQueries.
I get:
Runtime error '2485':
Microsoft Access Office can't find the object 'RunQueries.'
I also tried
appAccess.DoCmd.RunMacro "RunQueries"
and I get the same errors message.
I argued against it, and I have to do it this way (meaning, I have to use Excel as a frontend to open several Access dbs and run their macros).
What about this syntax ?
appAccess.run "RunQueries.RunQueries"
By the way, I always avoid naming a module like a procedure. This is looking for trouble.
Sub accessMacro()
Dim appAccess As Access.Application
Set appAccess = New Access.Application
appAccess.OpenCurrentDatabase "C:\blah.mdb"
appAccess.Visible = True
appAccess.DoCmd.RunMacro "Macro Name" '<-- As it appears in the Macro Group in the Access Interface.
appAccess.CloseCurrentDatabase
End Sub
How about this:
appAccess.Modules.Application.Run "macro_name"
The macro name doesn't need the Module name to function for me.
The msdn site didn't shed too much light, but I have a feeling that their disclaimer applies here. Here's what they mentioned:
If you run Visual Basic code containing the RunMacro method in a
library database, Microsoft Access looks for the macro with this name
in the library database and doesn't look for it in the current
database.
Of course they don't mention how exactly to remedy this issue! But after reviewing the answers above I think it would be helpful to post a full answer:
Sub accessMacro()
Dim appAccess As New Access.Application
Set appAccess = Access.Application
appAccess.OpenCurrentDatabase "C:\blah.mdb"
appAccess.Visible = True
appAccess.Run "RunQueries"
appAccess.CloseCurrentDatabase
End Sub
This worked when I ran it. Good luck! :D
-Reverus
Try this:
Sub accessMacro()
Dim appAccess
Set appAccess = CreateObject("Access.Application")
appAccess.OpenCurrentDatabase "C:\blah.mdb"
appAccess.Visible = True
appAccess.DoCmd.RunMacro "RunQueries.RunQueries"
appAccess.CloseCurrentDatabase
End Sub
This doesn't specifically address the "RunQueries" version, but this works in Access 2019.
Note that the Application object has to be created and initialized a bit differently than in the previous examples (and this ends with Set [object] = Nothing).
Although not mentioned, TXE_DEN.accdb has a tie-in to a separate library database MLO_Library.accdb and a lot of the subroutines in DEN access routines in Library. The macro in the example is in the TXE_DEN database, not the Library. If it were in the Library, I don't know whether it could be accessed through the TXE_DEN database as shown.
Also, in the Navigation Pane the example macro shows up in "Unrelated Objects". So in other cases--e.g., RunQueries--it might be necessary to include a module name in the identifier.
And just to avoid confusion--this macro does not do anything to anything in Excel. It's just "Well, I'm running THIS EXCEL stuff and I also need to run THAT ACCESS stuff, so I'll digress to Access and run that and then continue with my EXCEL stuff."
Sub Run_Access_Macro()
Dim appAccess As Object
Set appAccess = CreateObject("Access.Application")
Dim AccessDB As String
AccessDB = "F:\PATH WITH SPACES\TDN\TXE_DEN.accdb"
' format: module.macro
Dim AccessMacro As String
AccessMacro = "0 - Import TDN"
appAccess.OpenCurrentDatabase AccessDB
appAccess.Visible = True
appAccess.DoCmd.RunMacro AccessMacro
appAccess.CloseCurrentDatabase
Set appAccess = Nothing
End Sub

Resources