Run Excel Macro from Access macro in VBA - excel

I am trying to run an excel macro from access 2016. This has a lot of examples out their however they are all old. The exact error code I receive is run-time error '1004':
cannot run the macro "TestScript()". The macro may not be available in this workbook or all macros may be displayed. I am only running something easy for the test. I have ensured that macros is enabled in excel. the excel code is as follows
Public Sub TestScript()
MsgBox "IT WORKED"
End Sub
Real simple for the test. Access is opening the excel spreadsheet however it stops there with an error code.
My Access code is very simple and is below. I have also noted where the code stops. While I am new at VBA I have done a lot of research in this. I am testing as simple code as I could figure out. Any help would be welcomed.
Option Compare Database
Function runExcelmacro()
Dim XL As Object
Set XL = CreateObject("Excel.Application")
With XL
'Turn Off warnings
.Visible = False
.displayalerts = False
'WorkBook path such as "C:\Computer\WorkBook.xlsx"
.Workbooks.Open "C:\DATABASE\BLQ-10\Import Database BLQ 10\NTIRAINSTALLTO.xlsm"
'Run the Macro in excel getworkbook
.Run TestScript 'Code stops here!
'Close Workbook
.ActiveWorkbook.Close (True)
.Quite
End With
Set XL = Nothing
End Function
Public Sub runMacroSub()
Call runExcelmacro("C:\DATABASE\BLQ-10\Import Database BLQ 10\NTIRAINSTALLTO.xlsm", "TestScript")
End Sub

I guess OP did not put the code of Testscript in an extra module. Instead the code was put into the class module of the workbook or a worksheet. In the latter case you have to add the workbook or worksheet name in front of the name of the script.
Either it is `
.Run "ThisWorkbook.TestScript"
or in case it is in Sheet1 (codename of the sheet!)
.Run "Sheet1.TestScript"
Do not forget the quotation marks!
PS The OP's code above is working if you put testscript into a module and add quotation marks.
.Run "TestScript"
Here is a description how to create a module and add code

Here try this:
Public Sub TestScript()
MsgBox "IT WORKED"
End Sub
Option Compare Database
Function runExcelmacro()
Dim XL As Object, wb as object
Set XL = CreateObject("Excel.Application")
With XL
.Visible = False
.displayalerts = False
set wb = .Workbooks.Open "C:\DATABASE\BLQ-10\Import Database BLQ 10\NTIRAINSTALLTO.xlsm"
wb.Run TestScript 'Code stops here!
.ActiveWorkbook.Close (True)
.Quite
End With
Set XL = Nothing
End Function
Public Sub runMacroSub()
Call runExcelmacro("C:\DATABASE\BLQ-10\Import Database BLQ 10\NTIRAINSTALLTO.xlsm", "TestScript")
End Sub
Here i declared wb as an object and then set wb = to the workbook.
This is of course assumin your test script is in the actual workbook being opened. Would be real funny if that wasnt a thing lol

Related

VB6 does not terminate Excel process

I'm having an VB6 application that opens an excel macro enabled file using workbooks.open method. Inside this file, there is an userform that gonna be automatically opened when the file is opened. The problem is the workbooks.open method in vb6 application keeps running and does not jump to next line even when I close my userform (I do have codes to close workbook, quit excel app when the userform is closed). I can only close the interface of my userform but Excel still running in background. As long as I dont close the Excel app in task manager, my vb6 does not terminate excel process and of course it will not jump to next line either.
Here is my code in vb6 to open excel file that contains the userform above
As I said, workbooks.open method works but it does not terminate and keeps the excel app runnning in background
P/s: don't mind the Japanese characters
Private Sub Form_Load()
Dim xlapp
Dim xlwkb
If Not App.PrevInstance Then
Set xlapp = CreateObject("excel.application")
Me.Hide
On Error Resume Next
Set xlwkb = xlapp.workbooks.open("C:\Users\david\Desktop\sale-system\fixedfile.xlsm", Readonly:= True)
Set xlwkb = Nothing
If Not xlapp Is Nothing Then
xlapp.Visible = True
xlapp.Application.quit
Set xlapp = Nothing
End If
Unload Me
Else
MsgBox "プログラムが既に起動されています!", vbInformation, "売上管理システム"
Unload Me
End If
End Sub
Here is my code in excel file when close the userform
Application.DisplayAlerts = False
ThisWorkbook.Close False
Application.Visible = True
Application.Quit
End
I really need to solve this problem in this week, any solution?
Thank you guys in advance and please pardon for my english
Here is some images. I hope they will help you guys to understand my problem
This happens when I use Thisworkbook.close False statement:
This happens when I dont use Thisworkbook.close False statement:
Inside this file, there is an userform that gonna be automatically opened when the file is opened.
when I close my userform (I do have codes to close workbook, quit excel app when the userform is closed).
You are doing this incorrectly. Do not close/quit it from the UserForm. Do it from VB6 form. This way, vb6 will be able to handle and clear the objects.
Here, try this (I already tried it and it works...). This will not leave an instance of Excel running. I have commented the code. But if you still have questions then simply ask.
Note: Before you try this (Just for testing purpose), close all Excel application. Even from the task manager.
Private Sub Form_Load()
Dim oXLApp As Object
Dim oXLWb As Object
Dim ICreateatedExcel As Boolean
'~~> Establish an EXCEL application object
On Error Resume Next
Set oXLApp = GetObject(, "Excel.Application")
'~~> If not found then create new instance
If Err.Number <> 0 Then
Set oXLApp = CreateObject("Excel.Application")
'~~> I created instance of Excel
ICreateatedExcel = True
End If
Err.Clear
On Error GoTo 0
'~~> Check if you have an instance of Excel
If oXLApp Is Nothing Then
MsgBox "Unable to get an instance of Excel.", vbCritical, "Excel is Installed?"
Exit Sub
End If
Me.Hide
'~~> Show Excel
oXLApp.Visible = True
'~~> Open file
Set oXLWb = oXLApp.Workbooks.Open("C:\Tester.xlsm")
'~~> This and other lines below will not run till the
'~~> time you close the userform in Excel
'~~> Close the workbook
oXLWb.Close (False) '<~~ Set this to True if you want to save changes
Set oXLWb = Nothing
'~~> If I created Excel then quit
If ICreateatedExcel = True Then oXLApp.Quit
Set oXLApp = Nothing
Unload Me
End Sub

Out of memory when open a golden xlsm file

I added few VBA code in my workbook (myworkbook.xlsm) for the function :
when my workbook is opened, the VBA code will copy one sheet from the golden workbook (golden.xlsm).
I added the Sub Workbook_Open into the object "ThisWorkbook" of myworkbook.xlsm, the copy is successful. But the issue is when I use "Alt+F11" to open the Visual Basic editor, there will be a message box to complain "Out of memory", and I can't edit my other VBA code anymore.
I try to comment out some code in the Workbook_Open handler, the following line will lead to this issue :
Set goldenWorkbook = Workbooks.Open("golden.xlsm")
My code added for the open event of object "ThisWorkbook"
Private Sub Workbook_Open()
Dim goldenWorkbook As Workbook
Application.ScreenUpdating = False
Debug.Print "Hello~you just open the file"
Set goldenWorkbook = Workbooks.Open("golden.xlsm")
goldenWorkbook.Sheets("Common").Copy Before:=ThisWorkbook.Sheets(1)
goldenWorkbook.Close True
Application.ScreenUpdating = True
Set goldenWorkbook = Nothing
End Sub

Excel Vba stops excution after deleting sheet

I am new to VBA. I have written a code to delete a particular sheet. After execution of that delete sheet macro, excel macro stopped execution. It didnt execute futher..
Here is my code..
Sub CopyAcross()
Dim sheetName As String
sheetName = "Master_Base"
If WorksheetExists(sheetName) Then
DeleteSheet (sheetName)
End If
MsgBox "Debug"
Workbooks("Master_Base.csv").Sheets("Master_Base").Copy Before:=Workbooks("Copy of test.xlsm").Worksheets("Sheet3")
End Sub
Sub DeleteSheet(strSheetName As String)
' deletes a sheet named strSheetName in the active workbook
Application.DisplayAlerts = False
Sheets(strSheetName).Delete
Application.DisplayAlerts = True
End Sub
Can any one help on this,
Thanks in advance.
I was experiencing the same issue, on a Windows 7 computer with Excel version 16.0.10730.20264 32-bit, the code ran fine without issue. However, on a Windows 10 computer with the same Excel install version, the macro would immediately stop execution following the Sheets.Delete line.
I found that this was only happening where I was attempting to manipulate a workbook that contained VBA code, that I had opened during the macro.
The issue is caused by the macro security settings on the computer. If you set Automation Security to Low before opening the workbook, you should no longer get the error:
Use the code:
Application.AutomationSecurity = msoAutomationSecurityLow
Since you are working with multiple workbooks, use objects. Else your code MAY work with the wrong workbook/worksheet
Try this (UNTESTED)
Sub CopyAcross()
Dim wbI As Workbook, wbO As Workbook
'~~> The workbook from where the code is running
Set wbO = ThisWorkbook
'~~> Here you open the csv
Set wbI = Workbooks.Open("E:\OPM\OPM Sheet\Master_Base.csv")
'~~> This will delete the sheet if it exists
'~~> no need to check if it exists
On Error Resume Next
Application.DisplayAlerts = False
wbO.Sheets("Master_Base").Delete
Application.DisplayAlerts = True
On Error GoTo 0
'~~> The csv will always have 1 sheet
'~~> so no need providing a name
wbI.Sheets(1).Copy Before:=wbO.Worksheets("Sheet3")
End Sub

Easy VBA Macro to list all worksheets generates error: Type Mismatch

I'm making a ExcelComparer but I bump into a probably obvious error, I clearly missed something.
I run a vba macro in Excel 2007
The exact error I get is "Run-time Error 13: Type Mismatch"
This happens when the loop tries to fetch the second worksheet.name .
So, the first sheetname is returned fine
Below you find the macro
Thanks in advance,
L
Sub compare()
Dim strWorkbook1, strWorkbook2 As String
Dim Workbook1, Workbook2 As Workbook
strWorkbook1 = Worksheets("Sheet1").Range("C5") & Worksheets("Sheet1").Range("D5")
strWorkbook2 = Worksheets("Sheet1").Range("C6") & Worksheets("Sheet1").Range("D6")
Set xlapp = CreateObject("Excel.application")
Set Workbook1 = xlapp.Workbooks.Open(strWorkbook1)
xlapp.Visible = False
Dim ws As Worksheet
For Each ws In Workbook1.Sheets
'ws.Select
If Not ws.Visible = xlSheetVeryHidden Then
MsgBox (ws.Name)
End If
Next ws
xlapp.Close
End Sub
Use this for your For loop:
For Each ws In Workbook1.Worksheets
From MSDN the difference between the Sheets and Worksheets properties are:
This property does not return macro sheets, charts, or dialog sheets.
Use the Sheets property to return those sheets as well as worksheets.
You can also use the specialized properties Excel4MacroSheets and
Excel4IntlMacroSheets to return macro sheets and the Charts property
to return charts.
[Edited my original response as I had tested with different variables rendering my comment incorrect]
In addition the back end of your code will fail as you can't set the Excel Application to close with this line xlapp.Close
You should
close the automated workbook (Workbook1.Close False)
quit the automated application (xlapp.Quit)
Ensure the automated application is destroyed (Set xlapp = Nothing)a
The working part of your code should look like this
Dim ws As Worksheet
For Each ws In Workbook1.WorkSheets
If Not ws.Visible = xlSheetVeryHidden Then MsgBox (ws.Name)
Next ws
Workbook1.Close False
xlapp.Quit
Set xlapp = Nothing
End Sub

Way to run Excel macros from command line or batch file?

I have an Excel VBA macro which I need to run when accessing the file from a batch file, but not every time I open it (hence not using the open file event). Is there a way to run the macro from the command line or batch file? I'm not familiar with such a command.
Assume a Windows NT environment.
You can launch Excel, open the workbook and run the macro from a VBScript file.
Copy the code below into Notepad.
Update the 'MyWorkbook.xls' and 'MyMacro' parameters.
Save it with a vbs extension and run it.
Option Explicit
On Error Resume Next
ExcelMacroExample
Sub ExcelMacroExample()
Dim xlApp
Dim xlBook
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open("C:\MyWorkbook.xls", 0, True)
xlApp.Run "MyMacro"
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
The key line that runs the macro is:
xlApp.Run "MyMacro"
The simplest way to do it is to:
1) Start Excel from your batch file to open the workbook containing your macro:
EXCEL.EXE /e "c:\YourWorkbook.xls"
2) Call your macro from the workbook's Workbook_Open event, such as:
Private Sub Workbook_Open()
Call MyMacro1 ' Call your macro
ActiveWorkbook.Save ' Save the current workbook, bypassing the prompt
Application.Quit ' Quit Excel
End Sub
This will now return the control to your batch file to do other processing.
The method shown below allows to run defined Excel macro from batch file, it uses environment variable to pass macro name from batch to Excel.
Put this code to the batch file (use your paths to EXCEL.EXE and to the workbook):
Set MacroName=MyMacro
"C:\Program Files\Microsoft Office\Office15\EXCEL.EXE" "C:\MyWorkbook.xlsm"
Put this code to Excel VBA ThisWorkBook Object:
Private Sub Workbook_Open()
Dim strMacroName As String
strMacroName = CreateObject("WScript.Shell").Environment("process").Item("MacroName")
If strMacroName <> "" Then Run strMacroName
End Sub
And put your code to Excel VBA Module, like as follows:
Sub MyMacro()
MsgBox "MyMacro is running..."
End Sub
Launch the batch file and get the result:
For the case when you don't intend to run any macro just put empty value Set MacroName= to the batch.
you could write a vbscript to create an instance of excel via the createobject() method, then open the workbook and run the macro. You could either call the vbscript directly, or call the vbscript from a batch file.
Here is a resource I just stumbled accross:
http://www.codeguru.com/forum/showthread.php?t=376401
If you're more comfortable working inside Excel/VBA, use the open event and test the environment: either have a signal file, a registry entry or an environment variable that controls what the open event does.
You can create the file/setting outside and test inside (use GetEnviromentVariable for env-vars) and test easily. I've written VBScript but the similarities to VBA cause me more angst than ease..
[more]
As I understand the problem, you want to use a spreadsheet normally most/some of the time yet have it run in batch and do something extra/different. You can open the sheet from the excel.exe command line but you can't control what it does unless it knows where it is. Using an environment variable is relatively simple and makes testing the spreadsheet easy.
To clarify, use the function below to examine the environment. In a module declare:
Private Declare Function GetEnvVar Lib "kernel32" Alias "GetEnvironmentVariableA" _
(ByVal lpName As String, ByVal lpBuffer As String, ByVal nSize As Long) As Long
Function GetEnvironmentVariable(var As String) As String
Dim numChars As Long
GetEnvironmentVariable = String(255, " ")
numChars = GetEnvVar(var, GetEnvironmentVariable, 255)
End Function
In the Workbook open event (as others):
Private Sub Workbook_Open()
If GetEnvironmentVariable("InBatch") = "TRUE" Then
Debug.Print "Batch"
Else
Debug.Print "Normal"
End If
End Sub
Add in active code as applicable. In the batch file, use
set InBatch=TRUE
Instead of directly comparing the strings (VB won't find them equal since GetEnvironmentVariable returns a string of length 255) write this:
Private Sub Workbook_Open()
If InStr(1, GetEnvironmentVariable("InBatch"), "TRUE", vbTextCompare) Then
Debug.Print "Batch"
Call Macro
Else
Debug.Print "Normal"
End If
End Sub
I have always tested the number of open workbooks in Workbook_Open(). If it is 1, then the workbook was opened by the command line (or the user closed all the workbooks, then opened this one).
If Workbooks.Count = 1 Then
' execute the macro or call another procedure - I always do the latter
PublishReport
ThisWorkbook.Save
Application.Quit
End If
# Robert: I have tried to adapt your code with a relative path, and created a batch file to run the VBS.
The VBS starts and closes but doesn't launch the macro... Any idea of where the issue could be?
Option Explicit
On Error Resume Next
ExcelMacroExample
Sub ExcelMacroExample()
Dim xlApp
Dim xlBook
Set xlApp = CreateObject("Excel.Application")
Set objFSO = CreateObject("Scripting.FileSystemObject")
strFilePath = objFSO.GetAbsolutePathName(".")
Set xlBook = xlApp.Workbooks.Open(strFilePath, "Excels\CLIENTES.xlsb") , 0, True)
xlApp.Run "open_form"
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
I removed the "Application.Quit" because my macro is calling a userform taking care of it.
Cheers
EDIT
I have actually worked it out, just in case someone wants to run a userform "alike" a stand alone application:
Issues I was facing:
1 - I did not want to use the Workbook_Open Event as the excel is locked in read only.
2 - The batch command is limited that the fact that (to my knowledge) it cannot call the macro.
I first wrote a macro to launch my userform while hiding the application:
Sub open_form()
Application.Visible = False
frmAddClient.Show vbModeless
End Sub
I then created a vbs to launch this macro (doing it with a relative path has been tricky):
dim fso
dim curDir
dim WinScriptHost
set fso = CreateObject("Scripting.FileSystemObject")
curDir = fso.GetAbsolutePathName(".")
set fso = nothing
Set xlObj = CreateObject("Excel.application")
xlObj.Workbooks.Open curDir & "\Excels\CLIENTES.xlsb"
xlObj.Run "open_form"
And I finally did a batch file to execute the VBS...
#echo off
pushd %~dp0
cscript Add_Client.vbs
Note that I have also included the "Set back to visible" in my Userform_QueryClose:
Private Sub cmdClose_Click()
Unload Me
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
ThisWorkbook.Close SaveChanges:=True
Application.Visible = True
Application.Quit
End Sub
Anyway, thanks for your help, and I hope this will help if someone needs it
I'm partial to C#. I ran the following using linqpad. But it could just as easily be compiled with csc and ran through the called from the command line.
Don't forget to add excel packages to namespace.
void Main()
{
var oExcelApp = (Microsoft.Office.Interop.Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
try{
var WB = oExcelApp.ActiveWorkbook;
var WS = (Worksheet)WB.ActiveSheet;
((string)((Range)WS.Cells[1,1]).Value).Dump("Cell Value"); //cel A1 val
oExcelApp.Run("test_macro_name").Dump("macro");
}
finally{
if(oExcelApp != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcelApp);
oExcelApp = null;
}
}
I generally store my macros in xlam add-ins separately from my workbooks so I wanted to open a workbook and then run a macro stored separately.
Since this required a VBS Script, I wanted to make it "portable" so I could use it by passing arguments. Here is the final script, which takes 3 arguments.
Full Path to Workbook
Macro Name
[OPTIONAL] Path to separate workbook with Macro
I tested it like so:
"C:\Temp\runmacro.vbs" "C:\Temp\Book1.xlam" "Hello"
"C:\Temp\runmacro.vbs" "C:\Temp\Book1.xlsx" "Hello" "%AppData%\Microsoft\Excel\XLSTART\Book1.xlam"
runmacro.vbs:
Set args = Wscript.Arguments
ws = WScript.Arguments.Item(0)
macro = WScript.Arguments.Item(1)
If wscript.arguments.count > 2 Then
macrowb= WScript.Arguments.Item(2)
End If
LaunchMacro
Sub LaunchMacro()
Dim xl
Dim xlBook
Set xl = CreateObject("Excel.application")
Set xlBook = xl.Workbooks.Open(ws, 0, True)
If wscript.arguments.count > 2 Then
Set macrowb= xl.Workbooks.Open(macrowb, 0, True)
End If
'xl.Application.Visible = True ' Show Excel Window
xl.Application.run macro
'xl.DisplayAlerts = False ' suppress prompts and alert messages while a macro is running
'xlBook.saved = True ' suppresses the Save Changes prompt when you close a workbook
'xl.activewindow.close
xl.Quit
End Sub
You can check if Excel is already open. There is no need to create another isntance
If CheckAppOpen("excel.application") Then
'MsgBox "App Loaded"
Set xlApp = GetObject(, "excel.Application")
Else
' MsgBox "App Not Loaded"
Set wrdApp = CreateObject(,"excel.Application")
End If

Resources