Run a MakeTable query in Access from Excel - vba

I have an Excel file that I need to automate. When the user opens the Excel Report, it will prompt if they would like to refresh the data. If they say yes, then I need it to run a MakeTable query that is in an Access database to refresh all the underlying numbers for the report.
I have searched and haven't been able to find anything that actually works.
I tried to even create VBA code inside of Access that I could run that would handle the query, but I can't even get that to run from Excel VBA.
Here is the current code I have along with some of what I have tried that didn't work:
Sub RunAccessMTQuery(ByVal DBLocation As String)
Dim db As Object
Set db = CreateObject("Access.Application")
With db
.OpenCurrentDatabase DBLocation
.Visible = True
' .Run "Main.RunMTJobBond"
' .docmd.runmacro "Main.RunMTJobBond" '<---Module.Proc Name
' .docmd.runmacro "mMTJobBond" '<---Macro name that calls the Proc
.Application.Run "mMTJobBond"
.CloseCurrentDatabase
.Quit
End With
'Below was found on https://support.microsoft.com/en-us/help/131921/running-a-microsoft-access-macro-from-microsoft-excel
' Dim Chan as Long
'Opens Microsoft Access and the file nwind.mdb
' Shell("""C:\Program Files (x86)\Microsoft Office\Office12\MSACCESS.EXE"" """ & DBLocation & """")
'Initiates a DDE channel to Microsoft Access
' Chan = DDEInitiate("MSACCESS", "system")
'Activates Microsoft Access
' Application.ActivateMicrosoftApp xlMicrosoftAccess
'Runs the macro
' Application.DDEExecute Chan, "RunMTJobBond"
'Terminates the DDE channel
' Application.DDETerminate Chan
End Sub
Either I need to be able to run the MakeTable query from Excel, or launch Access and have it run the query. Nothing I have tried has worked...I have gotten numerous errors such as:
Runtime error 5 - Invalid procedure call or arguement
Runtime error 2517 - Application-defined or object-defined error
Others as well, but I don't recall them as I was able to work through those, and these are some of the ones I'm stuck on. Any help would be great, thanks.

The Application.Run() command runs a function or sub procedure, not a macro. That's why the attempts to run the macro do not work.
As for running the function or sub directly, the expected parameter format for Run() is "projectname.procedurename", NOT "modulename.procedurename". Unless you have multiple VBA projects within your database (which I assume you do not), then you don't even need projectname. See documentation here.
Try
Set dbApp = CreateObject("Access.Application")
With dbApp
...
.Run "RunMTJobBond"
This assume that RunMTJobBond is a public function or sub in a standard module.

Related

Ms Access VBA: How do I run a Sub Procedure that is stored in one DB on another DB?

I have a DB (we'll call it DB1) with a VBA procedure that loops through all sub folders in a file path and looks for other DB files with a certain string in the file path. When it finds a DB with that string (we'll call it DB2), I need to run a Sub Procedure (that is stored in DB1) on DB2. I have the code down to the point where it Opens DB2, but I can't figure out how to run the macro from DB1 on it. I tried the appAccess.Run method first and then I tried the docmd.runmacro method but neither worked.
Sub RunExternalProcedure(strFilePath)
Dim appAccess As Access.Application
Set appAccess = CreateObject("Access.Application")
appAccess.OpenCurrentDatabase strFilePath, False
'Run Sub procedure. 'appAccess.Run "TruncateTables"
DoCmd.RunMacro "TruncateTables"
Set appAccess = Nothing
End Sub
The problem is that (most likely) you are trying to run a procedure that isnt there. If i were you I would either:
Learn to check for existence of an object and on "not found" use the DoCmd.TransferDatabase command to move the module and then execute it.
https://learn.microsoft.com/en-us/office/vba/api/access.docmd.transferdatabase
Make the file with the module you want to run a reference in the references. Then the access file without it can call it remotely.
Access 2010: linked database, reference, or add-in?
I would probably do #2, because then thats get you into a mindset of having a utility function DB that other access applications use for commonly used things (instead of copy/pasting the same funciton/sub everywhere).

Issues accessing the user desktop using VBA

I am trying to use VBA in order to save a file on a user's desktop. I have found people requesting similar things on this site and others and the answers usually recommend using the following function to get the file path of the user's desktop
Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
However, I tried this and all I get is a 424 Object required error. The spreadsheet I am trying to add this to is long and complex so I created a new sheet with just the section of code I was interested in.
Sub TestMacro()
Dim Testy As String
Testy = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
MsgBox Testy
End Sub
When I run this macro I still get a 424 object required error. Am I doing something wrong? Or is there something locked down in my office environment preventing me from using this command?
Any help appreciated.
Try with below code
Sub TestMacro()
Set oWSHShell = CreateObject("WScript.Shell")
MsgBox (oWSHShell.SpecialFolders("Desktop"))
End Sub

Access autocad object properties without opening it by VBA

I have been using folder browser for VBA, I could paste the code of it, but bottom line is that I get returned file name as a string.
Is there any way to access drawing properties (i.e number of layouts) without open?
Public Sub TestFileDialog()
dwgname = FileBrowseOpen("C:", "*", ".dwg", 1) 'dwgname is typeof string
End Sub
Its only the first step (use of FileBrowseOpen function is shown, but also i can use FolderBrowse and collect all .dwg inside of folder),actually i had in mind to batch export all layouts of selected .dwgs to currenty open one. Is there any chance for that?
To effectively read a .dwg file you'll need to open AutoCAD, otherwise the information is not accessible. Some properties may be, such as author, but not number of layouts...
But you can use AutoCAD Console (accoreconsole.exe) to run a headless AutoCAD and use APIs to read any information you need. This is really fast for reading lot's of files and the user will not see it running (but it needs to be installed anyway).
http://aucache.autodesk.com/au2012/sessionsFiles/3338/3323/handout_3338_CP3338-Handout.pdf
you could stay in VBA and use ObjectDBX
it leads to a very similar approach as accoreconsole.exe on in .NET does, i.e you won't see any drawing open in UI since it works on the database itself
It requires adding library reference (Tools->References) to "AutoCAD/ObjectDBX Common XX.Y Type Library", where "XX.Y" is "19.0" for AutoCAD 2014
a minimal functioning code is
Sub main()
Dim myAxDbDoc As AxDbDocument
Dim FullFileName As String
FullFileName = "C:\..\mydrawing.dwg" '<== put here the full name of the file to be opened
Set myAxDbDoc = AxDb_SetDrawing(FullFileName)
MsgBox myAxDbDoc.Layers.Count
End Sub
Function AxDb_SetDrawing(FullFileName As String) As AxDbDocument
Dim DBXDoc As AxDbDocument
Set DBXDoc = Application.GetInterfaceObject("ObjectDBX.AxDbDocument.19") '<== place correct AutoCAD version numeber ("19" works for AutoCAD 2014)
On Error Resume Next
DBXDoc.Open FullFileName
If Err <> 0 Then
MsgBox "Couldn't open" & vbCrLf & vbCrLf & FullFileName, vbOKOnly + vbCritical, "AxDB_SetDrawing"
Else
Set AxDb_SetDrawing = DBXDoc
End If
On Error GoTo 0
End Function
Still, you must have one AutoCAD session running from which make this sub run! But you should have it since talked about "currently open" drawing

Access not finding an excel file which was created in vba on a network

I have code that opens & alters an excel table, saves it to a new (network) location, and then imports data from the newly formatted excel. The issue I have is that the code can't find the newly created file, saying it doesn't exist. I've played around with adding a 'pause' function, but I'm wondering if there's a way to refresh the network link in vba? Or is there a better method? Files will vary by size.
If I add a break in the code and let it sit for a few minutes it finds the file fine.
Private Sub btnImport_Click()
[other code]
'save excel file onto network location
xlApp.ActiveWorkbook.SaveAs ("\\network\file.xlsx")
xlApp.Quit
'Import file to temp table.
DoCmd.TransferSpreadsheet acImport,acSpreadsheetTypeExcel9, "tblImport","\\network\file.xlsx", True
End sub
Run-time error '3011': The Microsoft Access database engine could not find the object '\network\file.xlsx'. Make sure the object exists and that you spell its name and the path name correctly.
Free up the Excel resources when finished:
xlApp.Quit
'free any other Excel resources, then..
Set xlApp = Nothing
If it is a network issue and you need a delay then you can use Application.OnTime. For 15 seconds:
Application.OnTime Now + TimeValue("00:00:15"), "my_Procedure"
This will run your procedure (my_Procedure()) after the delay, and this procedure can perform the import.

How to open macros from other databases - VBA, MS Access 2003

I've been tasked with creating an Access 2003 application that will act as a focal point for all other databases (6 in total).
These 6 databases will each contain a macro used to build data bound for a table called DispenseExport.
Originally each of these databases had their own version of this table but now we have to have them all write to the one application - which I've affectionately codednamed Omega.
Omega will contain the DispenseExport table that all the others will write to. It will also be the database that calls the macros from the others to write to it.
So - what is the best way to accomplish this?
I already have a sample sub to call a macro from another database (and works) but the problem here is that it opens the database as any normal user would - Omega will sit on a server and needs to bypass this - by possibly using the SHIFT-KEY access method, if best?
How do I do that programmatically in VBA, assuming it's the best way to do so?
Here's what I have so far:
Option Compare Database
Option Explicit
'Sub to call a macro from another database
Public Sub CallMacro()
On Error GoTo ErrHandler:
Debug.Print "Opening Macro"
'/x tells the database to run the macro as soon as it is opened
Call Shell("msaccess.exe C:\path-to-database\database.mdb /x mcrTestCall", 0)
Debug.Print "Completed Macro"
ErrHandler:
If Err.Number <> 0 Then
'Create a message box with the error number and description
MsgBox ("Sorry but error number " & Err.Number & " occurred; " & vbCrLf & Err.Description)
End If
End Sub
UPDATE
Still haven't found the answer but believe that I'm closing in. I need to find out how to emulate HOLDING DOWN SHIFT - any ideas?
Thanks
This will avoid shell call (Access 2007, also Access 2003?):
'
' variables:
' strDbName: database filename
' strMacro: macro name
'
Sub CallMacro()
'
Dim strDbName, strMacro
Dim objApp
'
strDbName = "C:\path-to-database\database.mdb"
strMacro = "mcrTestCall"
'
Set objApp = CreateObject("Access.Application")
'
objApp.OpenCurrentDatabase strDbName
'
' Run Macro:
'
objApp.DoCmd.RunMacro strMacro
'
objApp.Quit
Set objApp = Nothing
'
End Sub
To skip startup form or AutoExec, there is no simple solution, but we have a workaround in http://access.mvps.org/access/api/api0068.htm, by simulating the Shift key, using API.
There is a cleaner way to do this without opening the remote database. Build a query within that database that does what you want, then call it from the other database without ADO, DAO or opening it. Below is a link explaining how:
Remote Queries
Since links go away, the gist of it is this:
1. Build the query you want to call to return what you need in the other database
2. In the remote calling database, open a query without selecting a table (I use Query Design)
3. Right click on the query background and select 'Properties'
4. Replace the Database setting of (Current) with the full path to the database with the query
5. Build a query to call the original query as the datasource
6. Output the data by a "SELECT INTO" or DoCmd.TransferSpreadsheet, etc