Macro gets disabled if called using a vb script - vba

I am trying to call my excel macro using vbs. Here is a snippet of my code.
Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.Workbooks.Open("C:\Folder\Test_PO.xls")
objExcel.Application.Visible = True
objExcel.Application.Run "C:\Folder\Test_PO.xls!Data_Analysis"
objExcel.ActiveWorkbook.Close
objExcel.Application.Quit
WScript.Echo "Finished."
WScript.Quit
Now the problem here is that i am able to open the file but the macro somehow gets disabled here and shows me 'macro may not be present or may be disabled'. I am sure i am calling correct macro name but as soon as the file is opened the Add-ins tab where i had configured the macro to run from gets dissapeared.This does not open if i open the file manually , i can see the tab and run the macro from the tab itself. Any suggestions how i could overcome this problem and get the macro to run ?

Try this
Dim objExcel, objWorkbook
Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.Workbooks.Open("C:\Folder\Test_PO.xls")
objExcel.Visible = True
objExcel.Run "Data_Analysis"
objWorkbook.Close
objExcel.Quit
Set objWorkbook = Nothing
Set objExcel = Nothing
WScript.Echo "Finished."
WScript.Quit
EDIT
If the macro is in a module then the above will help. If the macro is in a sheet say, Sheet1 then replace the line
objExcel.Run "Data_Analysis"
with
objExcel.Run "sheet1.Data_Analysis"
FOLLOWUP
Try this code.
Dim objExcel, objWorkbook, ad, FilePath
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
For Each ad In objExcel.AddIns
If ad.Name = "Converteam.xla" Then
FilePath = ad.Path & "\Converteam.xla"
Exit For
End If
Next
objExcel.Workbooks.Open (FilePath)
Set objWorkbook = objExcel.Workbooks.Open("C:\Folder\Test_PO.xls")
objExcel.Run "Data_Analysis_Converteam"
objWorkbook.Close
objExcel.Quit
Set objWorkbook = Nothing
Set objExcel = Nothing
WScript.Echo "Finished."
WScript.Quit
EXPLANATION:
When you use CreateObject, the Add-Ins are not installed by default. Please see this link.
Topic: Add-ins do not load when using the CreateObject command in Excel
Link: http://support.microsoft.com/kb/213489/
You have to load the Add-In and then call the relevant macro. Also the name of your macro is not Data_Analysis but Data_Analysis_Converteam
HTH

To add to Siddhart's answer - you can load the addins you require in a VBScript like this:
objExcel.RegisterXLL("analys32.xll") 'For XLL addins
objExcel.Workbooks.Open(objExcel.LibraryPath & "\analysis\atpvbaen.xla") 'For standard XLA addins
objExcel.Workbooks.Open("C:\Program Files\MyAddins\MyAddin.xla") 'for custom XLA addins

Related

Integrating VBA inside VBScript file

I have a working VBScript file and VBA macro inside Excel worksheet that does this:
Refreshes all data connections
Writes a timestamp in a specific cell
Save and closs the Excel worksheet
VBS file:
Set objExcel = CreateObject("Excel.Application")
objExcel.Application.Run "'G:\Blank.xlsm'!Module9.Date"
objExcel.DisplayAlerts = False
objExcel.Application.Quit
Set objExcel = Nothing
VBA inside the Blank.xlsm worksheet:
Sub Date()
ActiveWorkbook.RefreshAll
With Range("M12")
.Value = Now()
.NumberFormat = "dd/mm/yy hh:mm"
ActiveWorkbook.Save
End With
End Sub
Is it possible to keep the Excel macro-free .xslx file and run both of those functions from a VBScript file, which would not call the macro inside the Excel workbook to do the things I need, but rather complete those tasks by itself? I'm very new to VBScript (and frankly, VBA, too), so I'm sorry if this comes as too basic of a question.
Yes, of course, it's possible. Here:
Option Explicit
Dim objExcel, objWorkBook
Set objExcel = CreateObject("Excel.Application")
Set objWorkBook = objExcel.Workbooks.Open(filePath)
objExcel.Application.Visible = False
objExcel.DisplayAlerts = False
objWorkBook.RefreshAll
With objWorkBook.Sheets(1).Range("M12")
.Value = Now()
.NumberFormat = "dd/mm/yy hh:mm"
End With
objWorkBook.Save
objWorkBook.Close
objExcel.Application.Quit
WScript.Echo "Finished."
WScript.Quit

Run a macro using VBS on already opened excel

I would like to run a macro on an Excel using VBS code. My Excel will be always open. I am using below code for that.
Excel: main.xlsm, macro name: Inc
Option Explicit
Dim xlApp, xlBook
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open("E:\Main.xlsm", 0, False)
xlApp.Run "Inc"
xlBook.Close
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
WScript.Quit
The problem is whenever I run the code, it looks like the Excel trying to open in read only mode. As soon as the VBS runs, I am getting "save changes window" and saving the sheet as a copy.
I would like to save the changes on the same sheet rather than saving it as a new copy.
Excel lets you save a copy because you create a new instance of Application object, so you open the workbook again in read-only mode. To get a reference to Application object of the particular running instance of Excel with already opened workbook you should use the following lines:
Set xlBook = GetObject("E:\Main.xlsm")
Set xlApp = xlBook.Application
instead of
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open("E:\Main.xlsm", 0, False)
Then you just need to save that workbook with .Save.
You are creating a new Instance with Set xlApp = CreateObject("Excel.Application"), also the WB is then opened twice. Easiest fix, if you just close the WB before executing your code, then it should work fine. Also when closing use xlBook.Close SaveChanges:=True, no prompt should appear then.

VBScript to loop through Excel-files and change macro

I already posted a closely related question last week VBScript to add code to Excel workbook which got solved by a fellow programmer. But I ran into the next problem with that task:
With the following code, I try to loop through a folder of Excel files then open them one by one and change the macro in DieseArbeitsmappe. This works fine for the first file but the second ends with this error message.
Error message
Set objFSO = CreateObject("Scripting.FileSystemObject")
sFolder = "P:\Administration\Reports\operativ\Tagesbericht\templates\START07\TestTabsiNeu\"
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
objExcel.DisplayAlerts = False
For Each objFile In objFSO.GetFolder(sFolder).Files
Set objWorkbook = objExcel.Workbooks.Open(sFolder & objFile.Name)
Set component = objworkbook.VBProject.VBComponents("DieseArbeitsmappe")
strCode = _
"Sub WorkBook_Open() 'just for testing" & vbCr & _
" Application.Run (""'CommonMacro.xlsm'!Workbook_Open"")" & vbCr & _
"End Sub"
component.CodeModule.AddFromString strCode
objWorkbook.SaveAs "P:\Administration\Reports\operativ\Tagesbericht\templates\START07\TestTabsiNeu\" & objFile.Name
objExcel.Quit
Set objWorkbook = Nothing
Set component = Nothing
Next
Set objFSO = Nothing
Set objExcel = Nothing
Line 10 is Set component = objworkbook.VBProject.VBComponents("DieseArbeitsmappe")
Another problem I will face soon is that sometimes the VBComponent is called ThisWorkbook. So I will have to introduce if-else based on the Error code thrown by Line 10. Or is there a better solution for this?
Thanks in advance for your help.
This isn't a perfect answer, as I am more confused than I am certain of the exact problem... However hopefully this will help.
The command objExcel.Quit is going to close the Excel application.
I'm not quite sure how the code (in the next loop) then successfully executes
Set objWorkbook = objExcel.Workbooks.Open(sFolder & objFile.Name)
when the objExcel application has been quit. However, the .Visible and .DisplayAlerts will no longer be set True/False. The latter could cause your failure in line 10.
Therefore I suggest replacing
objExcel.Quit
with
objWorkbook.Close

Can't close Excel App with vba in a scheduled task

I have made a code in vba which works with different Workbooks and Worksheets. This code must be execute in a scheduled task. But for an unknow reason I have a problem with it :
When I execute it manually, it works fine and excel closes itself. But with my scheduled task, Excel closes all Workbooks and Worksheets but it stays open.
Here you have my code :
Set xlApp = GetObject(, "excel.application")
Set wkbMe = xlApp.ActiveWorkbook
test = False
xlApp.DisplayAlerts = False
xlApp.AskToUpdateLinks = False
'Open files
xlApp.Workbooks.Open Filename:=MarketDataPath & WbRiskedge, ReadOnly:=True
xlApp.Workbooks.Open Filename:=MarketDataPath & WbMarketData, ReadOnly:=True
Set WorksheetIncoming = xlApp.Workbooks(WbMarketData).Worksheets(wsIncoming)
Set WorksheetMarketdata = xlApp.Workbooks(WbMarketData).Worksheets(WsMarketData)
xlApp.Workbooks.Open Filename:=GTPath & WbGoodTime, ReadOnly:=True
Cells.Copy
WorksheetIncoming.Activate
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Workbooks(WbGoodTime).Close
WorksheetMarketdata.Calculate
Worksheets(wsMarketDataForWebsite).Calculate
Worksheets(wsMarketDataForWebsite).Activate
If test = False Then
Application.Run "MarketEnv.xlsm!subCreateCSV"
End If
Workbooks(WbMarketData).Close , False
Workbooks(WbRiskedge).Close , False
xlApp.DisplayAlerts = True
xlApp.AskToUpdateLinks = True
ThisWorkbook.Save
ThisWorkbook.Saved = True
xlApp.Quit
End Sub
I have tried different solutions found on the web but nothing work. Even if I only make :
Set xlApp = GetObject(, "excel.application")
xlApp.Quit
End Sub
my excel stays open.
Anyone can help me plz ?
Okay, this seems long winded... but here goes.
The problem you are seeing is because there can be more than one instance of the Excel Application on a machine at a given time.
When you are manually running the file, you are likely using the default behavior, which is that when you open a workbook directly it opens in your already loaded Excel Application.
This means that when you use:
Set xlApp = GetObject(, "excel.application")
It is actually returning the current Excel.Application.
However, when you load it via the scheduled task, it generates a new Excel.Application in order to handle your task. When it calls the code I quoted it ends up referencing the Excel.Application you already had open (probably).
Since your scheduled workbook is running in a different instance of Excel.Application, when you run xlApp.Quit it only quits that other Excel and not the one actually running the code.
If you want to also close your automated Excel, you will need to add Application.Quit to the end of your sub. Yes, I do mean use both xlApp.Quit AND Application.Quit.
Now technically, you could have more than one Excel Applications open when you load the new one. If you want to close all instances of Excel, the simplest way I know would be to kill all of them via a vbscript call to a program like this which terminates all processes named excel.exe. Note I did not test this on Win 7:
Dim objWMIService, objProcess, colProcess
Dim strComputer, strProcessKill, strFilePath
strComputer = "."
strProcessKill = "'excel.exe'"
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colProcess = objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = " & strProcessKill)
For Each objProcess In colProcess
objProcess.Terminate
Next
WScript.Quit
Edit: I just wanted to add that you can replicate the behavior of the scheduled task manually by doing the following:
Have Excel already open.
Navigate through your start menu and open Excel.
From the new instance of Excel, open your workbook.
OR
Have Excel already open.
Run the following Excel.exe [path of workbook in quotes]
Edit 2:
Due to your request, I've written this short vbscript file that will close all open Excel Applications without upsetting auto-recover. If you also want to avoid any, "Do you want to save ..." alerts uncomment the commented section.
On Error Resume Next
Dim xlApp
Set xlApp = GetObject(, "Excel.Application")
Do While Err.Number <> 429
'For each wb in xlApp.Workbooks
' wb.saved = true
'next
xlApp.Quit
Set xlApp = Nothing
Set xlApp = GetObject(, "Excel.Application")
Loop
Wscript.quit
To run it, just include the following at the end of your Excel VBA.
Shell "wscript.exe [path of .vbs file]"
I can see you have opened more than one workbook instances with your excel application. You need to close all workbook instances to get the plain excel application and than quit it.
try this: (pseudo code)
dim xlApp as Excel.Application
dim wBook as Excel.Workbook
dim wSheet as Excel.Worksheet
Set xlApp = new Excel.Application
Set wBook = xlApp.Workbooks.Add(wb_Path)
Set wSheet = wBook.Sheets(1)
wSheet.Range("A1").Value = "Hello this is a test from vbcode"
wbook.close saveChanges:= true
xlApp.quit
Above code will open your workbook. write a custom message on your worksheet
saves the changes and closes. and the xlapp will also be terminated/destroyed.

GetObject not unloading from VBA Project Window

I have the following VBA code
Sub test2()
Set xlobj = GetObject("C:\Users\osknows\Desktop\One of each\Jan_2011.xls")
With xlobj
For Each wsobj In .Worksheets
Set rngobj = wsobj.UsedRange
arrArray = rngobj.Value
Next
End With
Erase arrArray
Set rngobj = Nothing
Set xlobj = Nothing
End Sub
The problem is that once this runs and exits the sub the Jan_2011.xls details are still in the VBA project window. I would expect this to disappear by setting xlobj = Nothing
Any ideas?
The line containing GetObject does two things: it opens the workbook and makes xlobj a reference to the workbook. When xlobj is set to nothing, the reference is cleared, but the workbook is still open. This can be avoided by adding the line
xlobj.Close
before emptying the variables.