Trouble Running Access Macro from Excel VBA - vba

I'm trying to run an Access Macro from VBA and keep getting error:
Run-time Error 2485; Access cannot find the object 'MyTest'
My code is below - it is odd because the line:
A.DoCmd.OpenModule "temp", "MyTest"
works (opens the module to the correct location).
The macro is a simple test one; all paths are correct so far as I can tell. Thanks!
Set A = Nothing
Set A = CreateObject("Access.Application")
A.Visible = False
A.OpenCurrentDatabase (DBFileName)
A.DoCmd.OpenModule "temp", "MyTest"
A.DoCmd.RunMacro "MyTest"
A.CloseCurrentDatabase
A.Quit
Set A = Nothing

I am not sure if this is what you are looking for, but the following Excel macro starts the macro "MyTest" from a module which is included in the Access file "filename":
Sub test_accesss()
Set A = Nothing
Set A = CreateObject("Access.Application")
A.Visible = False
A.OpenCurrentDatabase ("filename")
A.Run "MyTest"
A.CloseCurrentDatabase
A.Quit
Set A = Nothing
End Sub

Related

Ignore an "external" error when opening a Word document

I'm attempting to copy the contents of a word document, but the document has embedded vba which causes a compile error anytime I open it.
The error reads
"The code in this project must be updated for use on 64-bit systems."
I expect this error to occur, so how do I tell my vba code in Access to ignore the errors without changing the word doc?
My vba code so far - the DisplayAlerts = wdAlertsNone does not work, neither does setting it to False:
Private Sub cmdQuickLtr_Click()
Dim wApp As Word.Application
Set wApp = CreateObject("Word.Application")
wApp.DisplayAlerts = wdAlertsNone
Dim doc As Object
Set doc = wApp.Documents.Open(Me.tbLetterPath.Value)
doc.Content.Copy
doc.Close
'do something with the copied content
wApp.DisplayAlerts = wdAlertsAll
Set doc = Nothing
Set wApp = Nothing
End Sub
Thank you all in advance.

Object error when calling application

I'm trying to open an excel document when a user clicks a button. There are multiple buttons that open the same document but I want it to change the worksheet if the document is already opened and not another instance of the document
Public objExcel As Object
Sub Main()
Set objExcel = CreateObject("Excel.Application")
End Sub
Public Sub QE1_Click()
Call Main
If objExcel Is Nothing Then
objExcel.Visible = True
objExcel.Workbooks.Open "H:\My Documents\Flowchart to Word\Quality and Environmental management system flowchart.xlsm"
objExcel.Worksheets("Project enquiry").Activate
Else
objExcel.Worksheets("Project enquiry").Activate
End If
End Sub
Public Sub QE2_Click()
Call Main
If objExcel Is Nothing Then
objExcel.Visible = True
objExcel.Workbooks.Open "H:\My Documents\Flowchart to Word\Quality and Environmental management system flowchart.xlsm"
objExcel.Worksheets("Order and project release").Activate
Else
objExcel.Worksheets("Order and project release").Activate
End If
End Sub
Running the code gives me the error: Application-defined or object-defined error
Can anyone point out what's causing the error?
This code here:
Set objExcel = CreateObject("Excel.Application")
Is creating a new Excel Application. Then this one here:
objExcel.Worksheets("Project enquiry").Activate
already assumes that the new application is having a worksheet called Project enquiry, which cannot be true. Thus, you are getting the 1004 error. Refine your business logic and it should work.
In general, try to delete this condition If objExcel Is Nothing Then because objExcel will never be Nothing, you are calling Main which assigns object to it. Then the code may work.
A little upgardes to get your code to work more efficiently:
Option Explicit
Public objExcel As Object
Sub Main()
' don't need to open another instance of Excel, can use the same instance
On Error Resume Next
Set objExcel = GetObject(, "Excel.Application") ' check if there is an open instance of Excel running
On Error GoTo 0
If objExcel Is Nothing Then
Set objExcel = CreateObject("Excel.Application")
End If
End Sub
'==================================================================
Public Sub QE1_Click()
Dim wb As Workbook
Dim sht As Worksheet
If objExcel Is Nothing Then
Main ' call sub that initializes an Excel application object
End If
objExcel.Visible = True
Set wb = objExcel.Workbooks.Open("H:\My Documents\Flowchart to Word\Quality and Environmental management system flowchart.xlsm")
On Error Resume Next
Set sht = wb.Worksheets("Project enquiry")
On Error GoTo 0
If sht Is Nothing Then ' sheet doesn't exist >> raise an error
MsgBox "Workbook doesn't have a sheet named 'Project enquiry'", vbCritical, "Sheet critical error"
Else ' sheet object created successfully
sht.Activate ' <-- NOT SURE why you need to use Activate ?
End If
End Sub
Note: same modifications should be applied to Sub QE2_Click().
If you want to control an Office application from within a different one - Excel from within Word, for example, you first need to decide whether you want to write your code using Intellisense and what's called "early-binding" or whether you want to use "late-binding", which does not have Intellisense but has the advantage that you don't need to rely on a link to the other (Excel) VBA code library.
In order to use early-binding you must go to Tools/References in the VBA editor and activate the checkbox next to the entry for the other application (Excel). Only then can you use something like Dim wb As Workbook.
If you don't want to use early-binding, then you must declare things as Dim wb as Object, same as you've done for the Excel.Application.
In order have code decide whether it needs to use an running instance of the other application (Excel) or start a new instance, use the method GetObject. This can be used to pick up any running instance, or to check for a specific file.
Set ojbExcel = GetObject(,"Excel.Application")
vs
Set objExcel = GetObject("H:\My Documents\Flowchart to Word\Quality and Environmental management system flowchart.xlsm")
If what you're looking for with GetObject isn't currently available, you'll get an error which you can check and subsequently use CreateObject in order to start the application.
Option Explicit
Public objExcel As Object
Sub Main()
''' Try to re-use an existing instance
' If that instance does not exist, an error will be generated
' So temporarily turn off error messages
On Error Resume Next
' check if there is an open instance of Excel running
Set objExcel = GetObject(, "Excel.Application")
' Turn error messages back on
On Error GoTo 0
If objExcel Is Nothing Then
Set objExcel = CreateObject("Excel.Application")
End If
End Sub
Note that you should usually not turn off error-messaging - you need a really good reason to do so and you should turn it on again as soon as possible.
If all your buttons are essentially the same - in the two procedures you show everything is the same except the Else step - then you can cut down on the duplicate code. (That will also make maintenance simpler if you don't have to make changes in all the procedures).
Also, since the Else action is the same as the last action in the If you can simply put that after End If.
Private Sub ActivateWorksheet(wsName as String)
If objExcel Is Nothing Then
objExcel.Visible = True
objExcel.Workbooks.Open "H:\My Documents\Flowchart to Word\Quality and Environmental management system flowchart.xlsm"
End If
objExcel.Worksheets(wsName).Activate
End Sub
Public Sub QE1_Click()
Call Main
ActivateWorksheet "Project enquiry"
End Sub
Public Sub QE2_Click()
Call Main
ActivateWorksheet "Order and project release"
End Sub

Macro stops at `ThisWorkbook.EnvelopeVisible = True`

I'm trying to automated the process by using VBs to auto run the macro without opening the Excel.
I have tested the Macro and it works fine if the workbook is opened. However, when I run the Macro through the VBs Script, the Maro stops at ThisWorkbook.EnvelopeVisible = True. Does anybody knows why?
My Macro
Sub sendEmail()
MsgBox "sendEmail Start!" 'Appears when run VBs
ThisWorkbook.EnvelopeVisible = True
MsgBox "EnvelopeVisible True!" 'did not appear when run VBs
With ThisWorkbook.Sheets("sheet1").MailEnvelope
MsgBox "MailEnvelope Prepare!"
.Introduction = "Message"
.Item.To = "To who it may concern"
.Item.Subject = ""
.Item.Send
MsgBox "MailEnvelope Send!"
End With
ThisWorkbook.EnvelopeVisible = False
MsgBox "sendEmail Done!"
End Sub
My VBs
Set objExcel = CreateObject("Excel.Application")
objExcel.Application.Run "'C:\Users\UserName\Desktop\Folder\Ver 6.xlsm'!AutoEmail.sendEmail"
objExcel.DisplayAlerts = False
objExcel.Application.Quit
Set objExcel = Nothing
I'm running the VBs to activate the Macro
You need to add following line to VBS:
objExcel.Visible = True
just after
Set objExcel = CreateObject("Excel.Application")
It is based on a simple clue that your issue description gave.
Excel Macro works if it is opened and run from Excel.
It halts if it is being run from the VBS
When I looked at the MSDN explanation for this property
https://msdn.microsoft.com/en-us/vba/excel-vba/articles/workbook-envelopevisible-property-excel
It says
True if the e-mail composition header and the envelope toolbar are both visible. Read/write Boolean .
So to make it work we need to make the parent object visible i.e. Excel.Application.

Using VB script to run VBA Macros and save the excel workbook

I am trying to run a macro from a * .vbs file. You can find the code below. The module runs with no issue (this has been tested). But workbook is not saved. I tried adding ThisWorkbook.Save into the module itself but it causes an error and tells me that my file is ReadOnly. To clarify, I want to know how to save the workbook after running a macro through VBScript.
Option Explicit
'On Error Resume Next 'Comment-out for debugging
ExcelMacro
Sub ExcelMacro()
Dim xlApp
Dim xlBook
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open("\\internal.company.com\River_Automated.xlsm", 0, True)
xlApp.Run "Update"
xlBook.Save
xlBook.Close
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
Some side notes that may be helpful:
After running VBScript I got this message that:
Resume.xlsw already exists. Do you want to replace it?
I added lines that create a text file right before End Sub and it creates it. So, it runs the macro but does not save the workbook.
This line:
Set xlBook = xlApp.Workbooks.Open("\\internal.company.com\River_Automated.xlsm", 0, True)
Is causing the file to be opened in ReadOnly mode. The third argument of the Open method determines whether to open the file in ReadOnly mode if True, or otherwise False.
ReadOnly | Optional | Variant | True to open the workbook in read-only mode.
The solution would be either to open the file in ReadOnly = False via:
Set xlBook = xlApp.Workbooks.Open("\\internal.company.com\River_Automated.xlsm", 0, False)
Or, to check if the file is ReadOnly and if so, save it as something else.
If Not xlBook.ReadOnly Then
xlBook.Save
Else
xlBook.SaveAs ... '### Modify as needed
End If
xlBook.Close
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing

VBA function call: Excel Button vs VBS call

I'm struggling with a VBA Sub that is called by a button. This Sub opens an Configuration.xls Excel spreadsheet from a hard coded file path. A MsgBox tell me about the current workspace - the workspace changes from the current file to the just opened one. All is fine here.
I now want to execute this Sub from an outside batch that calls a VBS that calls the VBA Sub. The workspace after opening the Configuration.xls file remains the same and does not change to Configuration.xls. Additionally when calling the Sub by VBS the function gets executed twice - No clue why.
So my question is - why do I have different behaviors between the two calling mechanisms?
I simplified the code below as it shows the same behavior as my more complex real code.
Sub ReadConfiguration()
MsgBox ActiveWorkbook.Name
FileExcel = "D:\_Trash\VBA_VBS\Configuration.xls"
Workbooks.Open Filename:=FileExcel, ReadOnly:=True, IgnoreReadOnlyRecommended:=True
strFileName = FunctionGetFileName(FileExcel)
MsgBox ActiveWorkbook.Name
On Error Resume Next
Set wBook = Workbooks(strFileName)
If Err Then
Exit Sub
End If
ActiveWorkbook.Close savechanges:=False
End Sub
'*****************************************************
Function FunctionGetFileName(FullPath As Variant)
Dim StrFind As String
Do Until Left(StrFind, 1) = "\"
iCount = iCount + 1
StrFind = Right(FullPath, iCount)
If iCount = Len(FullPath) Then Exit Do
Loop
FunctionGetFileName = Right(StrFind, Len(StrFind) - 1)
End Function
'*****************************************************
The VBS looks like this
Dim args, objExcel
Set args = WScript.Arguments
Set objExcel = CreateObject("Excel.Application")
objExcel.Workbooks.Open args(0)
objExcel.Visible = False
objExcel.Run "Module1.ReadConfiguration()"
objExcel.ActiveWorkbook.Close(0)
objExcel.Quit
I just want to let you know about the solution of this issue allthough I cannot explain completely. The solution is to get rid of the "()" behind the macro call. This has the effect that the VBS script is run twice and the Workbook 'scope' is mixed up.
So easy solution but still the question WHY- What do I tell the function additionally when adding the "()"?
Thanks for your help!
TheMadMatt