I have some Excel macro which works on a specific Excel worksheet. It checks some table and sends reminder email to some people as needed.
I want that this macro will run once a day in order to check the table every day so I will not need to open the worksheet and to do it myself every day.Does it availabe to do it? I heard about Windows task scheduler as one option, Do you think that is a good option for my purpose?
Task Scheduler is a good option as you say. To spawn a new process and open a workbook you'd have a command line specifiying (1) The Excel executable and (2) the workbook to open so something like
C:\Program Files\Microsoft Office 15\root\office15\Excel.exe "c:\MyWorkbook.xlsm"
I'd advise double quotes around the full path to the workbook (but not required for the Excel.exe).
Then in MyWorkbook.xlsm you can write code that runs upon workbook opening, classically this has been sub Auto_Open in any standard module or Sub Workbook_Open() in the ThisWorkbook module.
I would recommend a VBScript file and make that to run every day using task scheduler. I prefer this, cause then I can open the Excel file any time of the day and the macro won't run (in case you just want it to update only at that specific time).
This is the VBscript you need to write in notepad and then save with *.vbs extension.
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("path\to\the\file.xlsm", 0, True)
xlApp.Run "Update" 'Name of your Sub
xlBook.Save
xlBook.Close
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
Then you can set the event scheduler from the command-line, like this from here:
schtasks /Create [/S <system> [/U <username> [/P [<password>]]]]
[/RU <username> [/RP <password>]] /SC <schedule> [/MO <modifier>] [/D <day>]
[/M <months>] [/I <idletime>] /TN <taskname> /TR <taskrun> [/ST <starttime>]
[/RI <interval>] [ {/ET <endtime> | /DU <duration>} [/K] [/XML <xmlfile>] [/V1]]
[/SD <startdate>] [/ED <enddate>] [/IT] [/Z] [/F]
Other links you may find useful:
Task Scheduler from the command line? from SuperUser
What is a simple way to schedule a single event to happen at some time in the future? from Linux & Unix
How to Schedule Programs to Run Automatically in Windows 7? from Gizmo's freeware (TechSupportAlert)
Related
I created an Excel VBA that check for data in the cells and send email with WorkBook_Open().
Option Explicit
Private Sub Workbook_Open()
'Declaring variables
Dim notifyEmailApplication As Object
Dim notifyEmailContent As Object
Dim triggerEmailApplication As Object
Dim triggerEmailContent As Object
'Create email object
Set notifyEmailApplication = CreateObject("Outlook.Application")
Set notifyEmailContent = notifyEmailApplication.CreateItem(0)
Set triggerEmailApplication = CreateObject("Outlook.Application")
Set triggerEmailContent = triggerEmailApplication.CreateItem(0)
...
I then created a VBScript to run the Excel file.
Call ExcelMacro
Sub ExcelMacro()
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = True
xlApp.DisplayAlerts = False
Set xlBook = xlApp.Workbooks.Open("....\Email Automation.xlsm", 0, False)
xlBook.Close
Set xlBook = Nothing
xlApp.Quit
Set xlApp = Nothing
End Sub
I also created a cmd file to run the VBScript on cscript.exe
cscript.exe "....\vbscript.vbs"
exit
Whenever I trigger the cmd file manually (double clicking it), the Excel Macro runs perfectly and successfully send email to the designated person.
But when I use Task Scheduler to run the cmd file, the Excel Macro does not run successfully and this line was highlighted.
Set notifyEmailApplication = CreateObject("Outlook.Application")
Notes: I already viewed a lot of forums and didn't find a fix:
In 'dcomcnfg' I already set Outlook Message Attachment to Interactive User
I tried changing Dim notifyEmailApplication As Object to Dim notifyEmailApplication As Outlook.Application, same line is highlighted
I already added Outlook Object Library as reference in Excel VBA
But when I use Task Scheduler to run the cmd file, the Excel Macro does not run successfully
Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.
If you are building a solution that runs in a server-side context, you should try to use components that have been made safe for unattended execution. Or, you should try to find alternatives that allow at least part of the code to run client-side. If you use an Office application from a server-side solution, the application will lack many of the necessary capabilities to run successfully. Additionally, you will be taking risks with the stability of your overall solution.
Read more about that in the Considerations for server-side Automation of Office article.
If you deal with open XML documents you may consider using the Open XML SDK instead, see Welcome to the Open XML SDK 2.5 for Office for more information. Also take a look at any third-party components designed for the server-side execution (they don't require Office installed on the system).
I haven't touched this topic for many years, but as I remember, from a long time ago, the Task Scheduler allows, or requires, you to enter your Windows password and if the password is incorrect it won't notify you of the error, so it seems like it's working, but with the incorrect password, it won't work. Can you double-check that your Windows password is entered correctly?
I have some code in VBscript that creates an excel object and adds a workbook to it
Dim oExcel, oWB
Set oExcel = CreateObject("excel.application")
Set oWB = oExcel.Workbooks.Add()
When I run this myself (using VbsEdit or cscript), it has no issues and does the job.
When I make an entry in the Windows 10 Task-Scheduler (or Server 2019 too), run it with setting 'even if the user is offline', it fails with errorcode -2147023170. When I say the user MUST be online (useless, but I tried it anyway) then I get the error 1004 - Unknown runtime error.
I can't figure out what causes this. I presume it's a Office 365 issue, because on an older system (windows server 2012 R2 with office 2016) it runs just fine from the task scheduler.
The account it runs under is administrator, the task runs with the highest priority. The Vbs is not called directly, but using a bat-file with logging. Running a vbs-script directly from the task scheduler seems to get stuck at "running" indefinately :(
Who knows how to fix this ?
Thanks,
Paul
How about removing the brackets at the end of Workbooks.Add?
Set oWB = oExcel.Workbooks.Add
As the title says, I am trying to get the Task Scheduler to do as follows:
Open an specific Excel file at an specific time every day and run the module 1 within said file.
The workbook name is Daily Invoiced, and it contains a Macro, therefore the file is an xlms. The code I need to run is in the Module 1, therefore this is the one that needs to be selected.
This file is stored in my folder C:\Users\MartiJor1\Documents\MACROS\Daily Invoiced.
What have I done so far?
Followed the example listed in https://www.thespreadsheetguru.com/blog/how-to-automatically-run-excel-vba-macros-daily where the plan is to use a Script. Here is what mine ends looking like:
'Input Excel File's Full Path
ExcelFilePath = "C:\Users\MartiJor1\Documents\MACROS\Daily Invoiced ZAMSOTC02 LAC TEAM.xlsm"
'Input Module/Macro name within the Excel File
MacroPath = "Module1.LAC_Daily_Invoiced_Report"
'Create an instance of Excel
Set ExcelApp = CreateObject("Excel.Application")
'Do you want this Excel instance to be visible?
ExcelApp.Visible = True 'or "False"
'Prevent any App Launch Alerts (ie Update External Links)
ExcelApp.DisplayAlerts = False
'Open Excel File
Set wb = ExcelApp.Workbooks.Open(ExcelFilePath)
'Execute Macro Code
ExcelApp.Run MacroPath
'Save Excel File (if applicable)
wb.Save
'Reset Display Alerts Before Closing
ExcelApp.DisplayAlerts = True
- Note: If I execute the script with the Windows Based Script Host, it runs smoothly.
I also used the rest of the configuration suggested in the article for the script to run, except I am using Windows 10 Pro. However, nothing happens at the scheduled hour, nor when I run it manually. On the Last Run Result I can see the code (0x41303) which is an error code related to a date in the past. Does not matter how many times I amend it for the near future, it does not run.
I can not see the error. I believe it must be somewhere in the Actions Tab, and I arrive to this conclusion by the fact that I can run the Script with the Windows Based Script Host as mentioned above. Any idea guys?
Here is also the script from the Task when I export it:
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2020-10-31T21:41:26.1715916</Date>
<Author>GUWW\MartiJor1</Author>
<Description>Test</Description>
<URI>\DailyInvoiced</URI>
</RegistrationInfo>
<Triggers>
<CalendarTrigger>
<StartBoundary>2020-11-02T14:03:00</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByDay>
<DaysInterval>1</DaysInterval>
</ScheduleByDay>
</CalendarTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>S-1-12-1-4092016482-1174842289-577708437-4023581491</UserId>
<LogonType>Password</LogonType>
<RunLevel>LeastPrivilege</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>false</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>false</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
<UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
<WakeToRun>true</WakeToRun>
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
<Priority>7</Priority>
<RestartOnFailure>
<Interval>PT1M</Interval>
<Count>3</Count>
</RestartOnFailure>
</Settings>
<Actions Context="Author">
<Exec>
<Command>"C:\Windows\System32\cscript.exe"</Command>
<Arguments>"C:\Users\MartiJor1\Documents\MACROS\Daily.vbs"</Arguments>
</Exec>
</Actions>
</Task>
Thanks in advance.
Running a job from AutoSys and I am getting an error.
VBS runs an excel macro.
VBS code :
Option Explicit
Dim xlApp, xlBook
Set xlApp = CreateObject("Excel.Application")
On Error Resume Next
set xlBook = xlApp.Workbooks.Open("Z:\Confidential Restricted\Weekly_HR_Employees_Macro.xlsm",0, False)
xlApp.Run "Weekly_HR_Employees_Macro.Weekly_HR_Employees_Macro"
xlBook.Close True
xlApp.Quit
set xlBook = Nothing
Set xlApp = Nothing
Error:
Microsoft VBScript runtime error: ActiveX component can't create object: 'Excel.Application'
You are using GetObject syntax with CreateObject method. You need to use:
Set xlApp = CreateObject("Excel.Application")
Check this answer for more details.
Although the script runs on my machine, it would not run on the machine that the AutoSys job was using. I eventually found that the machine that was being used by the Autosys job does not have Microsoft Office installed.
You can use GetObject("Excel.Application"), but you need to make sure you open up an instance of excel before you use it. GetObject will get a reference to this open instance of Excel and let you use that.
For example something like this to open the workbook in a new instance and then start the macro:
Shell(Excel.exe workbook.xlsm!macro1)
Or if the workbook was already open then:
Shell(xlObject macro1)
Most important thing is to use Shell so as to allow the code to continue whilst the macro runs separately. If not possible then perhaps I could Shell(file.bat) to a batch file that would do the same. What would the batch file look like?
Thank you.
You cannot execute VBA code inside a host application from the command line - that includes Shell.
There are two alternatives, though (with Excel#1 being the current open file and Excel#2 being the one you want to run the code in):
Put the code you want to run in the Excel #2 workbook's Workbook_Open event handler so it will execute every time you open that file - independet of how it was opened.
Have Excel#1 create a new Excel.Application object in VBA and open Excel#2 in that application. You could now call the Run() method on the Excel#2's application object to execute code from Excel#2, but this will be done synchronous to the Excel#1's code. You can use the Excel#2 application's OnTime() method though for delayed macro execution, in which case Excel#2's application will call the code when the delay has passed and the code runs asynchronous in Excel#2's application.
Sample code for Option 2 could look like this:
Public Function RemoteRun(ByVal strFile As String) As Application
Dim app As Application
Dim wb As Workbook
Set app = New Application
Set wb = app.Workbooks.Open(strFile)
app.OnTime Now + 1 / 24 / 60 / 60, "RemoteMacro"
Set RemoteRun = app
End Function
Make sure to store the return value (the Excel#2's application object) somehwere so it won't automatically close (it still has to run RemoteMacro asynchronously). Setting its Visible property to True will work as well if you don't want Excel#1's code to manage the lifetime of Excel#2's application object.