Run batch file when starting excel - excel

I do have a question: is there a way, when user double clicks on excel file, batch or cmd file will be launched, which will launch that clicked excel file? We would like to save further a log of employees how frequent they are using files in their computers.
I need to use batch or cmd files as excel files are in other computers and we will be using group policy for an incorporation that script

You can do this using VBA. In the "ThisWorkbook" part of the VBA project you can add something like
Option Explicit
Private Sub Workbook_Open()
Dim strPath As String
'put the location and name of your batch file here
strPath = "C:\YourFolder\YourBatchFile.bat"
Call Shell(strPath)
End Sub
See this Link if you are not sure about using VBA code

Set WshShell = WScript.CreateObject("WScript.Shell")
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set objEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM Win32_ProcessStopTrace")
Do
Set objReceivedEvent = objEvents.NextEvent
msgbox objReceivedEvent.ProcessName
If lcase(objReceivedEvent.ProcessName) = lcase("Notepad.exe") then
Msgbox "Process exited with exit code " & objReceivedEvent.ExitStatus
WshShell.Run "c:\Windows\notepad.exe", 1, false
End If
Loop
This is a vbs script monitoring all program stops. You can use Win32_ProcessStopTrace, Win32_ProcessStartStopTrace, or Win32_ProcessStartTrace.
This is meant to replace a batch file. To write a log
Set Fso = CreateObject("Scripting.FileSystemObject")
Set File = Fso.CreateTextFile("c:\folder\filename", True)
file.writeline "text"

Related

VBA reading non-english characters causes errors

I am using a macro that reads every excel file in one folder and subfolders and refreshes it by opening the file and closing it with 'save changes' attribute as True. The problem is that VBA doesn't read non-english letters correctly and it causes error when trying to save the spreadsheet. My region settings in Windows control panel are correct. When I try to use the beta option of using Unicode UTF-8 for every language it works but that causes a lot of other programs I use to display some weird characters. The language I try to incorporate is polish. Any idea what to do?
Sub RefreshExcelDocs()
Const startFolder As String = "C:\Users\Patryk\Downloads\Przykład óżęą\Folder\"
Dim file As Variant, wb As Excel.Workbook
For Each file In Filter(Split(CreateObject("WScript.Shell").Exec("CMD /C DIR """ & startFolder & "*.xl*"" /S /B /A:-D").StdOut.ReadAll, vbCrLf), ".")
Set wb = Workbooks.Open(file)
wb.Close SaveChanges:=True '
Set wb = Nothing
Next
End Sub

open .exe in VBA excel and write in the input window

I have to run an .exe in VBA Excel and write in the input window "in.txt" "out.txt" in order to make the process automatic inside a macro. I tried to use shell but it works asynchrounous and I also don't know how to tell her to write inside the .exe.
I've also tried with SendKeys but apperently it doesen't work.
How could I make the VBA calling my .exe, open it, write inside the command window of the .exe, wait for the output and use it to go on?
thank you in advance
here are two attempts (both failed):
Sub write()
prog = Shell("C:\Users\arancia\Pictures\Camera Roll\axtur\axtur\AXTUR_64.exe", 1)
Application.Run "'AXTUR&EXCEL.xlsm'!inserisci_dati_input"
SendKeys.send "in.txt~", True
SendKeys.send "out.txt~", True
SendKeys "%{F4}", True
End Sub
Sub StartExeWithArgument()
Dim strProgramName As String
Dim strArgument As String
strProgramName = "C:\Users\arancia\Pictures\Camera Roll\axtur\axtur\AXTUR_64.exe"
strArgument = "in.txt~out.txt~"
Call Shell("""" & strProgramName & """ """ & strArgument & """", vbNormalFocus)
End Sub
One solution would be to write a batch file that includes all the parameters and then run the batch.
I have used WshShell (Windows scripting host) to run batch files to do what you want in the past but WshShell does not work on our computers since the Nov 2020 updates. WshShell allows you to wait for the outcome of the external program.
One way I found to go around it is to write a simple text file at the end of the batch and wait for it to show up. This is crude but it works.
In the code below, I write a simple batch file in the folder of the Excel sheet. The last line of the batch writes the content of the folder in a text file. The Do Until loop waits for the text file to show up in 1 second increments. When the code resumes after the loop, the text file is deleted. If you write the command line you would type in cmd instead of "echo Hello World" this should work.
You need to reference the Microsoft Scripting Runtime (scrrun) to use the file system object.
Good Luck!
Public Sub RunBatch()
Dim i As Integer
Dim k As Integer
Dim xlWB As Workbook
Dim fso1 As New FileSystemObject
Dim BatFile As Object
Dim IsDone As Boolean
Dim OutFileName As String
Set xlWB = ThisWorkbook
OutFileName = xlWB.Path & "\" & "HW.bat"
Set BatFile = fso1.CreateTextFile(OutFileName)
BatFile.WriteLine "cd /d " & xlWB.Path
BatFile.WriteLine "echo Hello World"
BatFile.WriteLine "dir > Done.txt"
BatFile.Close
IsDone = False
Call Shell(OutFileName, vbNormalFocus)
Do Until IsDone
If fso1.FileExists(xlWB.Path & "\Done.txt") Then IsDone = True
Application.Wait (Now + TimeValue("00:00:01"))
Loop
fso1.DeleteFile (OutFileName)
End Sub

Create live copy of password protected excel workbook

I have a workbook that is password protected and I’d like to create a read only copy that other users can view on a different location on the network drive.
I know it’s a strange request as the other people could open the original as read only, but we don’t want them to know the location of the original or have anything to do with it, should they figure out my colleagues password.
The other issue we had was that people were opening as read only and it was still telling my colleague that it was locked by another user and he needs it for most of the day so that issue is annoying
Thanks in advance
What you could do is add the following event procedure to the ThisWorkbook module:
Const RemotePath As String = "D:\YourRemoteLocation\"
Private Sub Workbook_AfterSave(ByVal Success As Boolean)
On Error GoTo CleanUp
If Success And InStr(ThisWorkbook.Name, "Copy of ") = 0 Then
Dim CopyFullName As String
CopyFullName = RemotePath & "Copy of " & ThisWorkbook.Name
Application.EnableEvents = False
Dim fso As FileSystemObject 'Requires the Microsoft Scripting Runtime Library
Set fso = New FileSystemObject
fso.CopyFile Source:=ThisWorkbook.FullName, Destination:=CopyFullName
Dim ReadOnlyWorkbook As Workbook
Set ReadOnlyWorkbook = Workbooks.Open(Filename:=CopyFullName)
Application.DisplayAlerts = False
ReadOnlyWorkbook.SaveAs Filename:=CopyFullName, Password:=""
Application.DisplayAlerts = True
ReadOnlyWorkbook.Close SaveChanges:=False
End If
CleanUp:
Application.EnableEvents = True
Application.DisplayAlerts = True
Set fso = Nothing
End Sub
This code will run every time the workbook is saved and export the current file to the remote location. Then it will open the copy and save it as a workbook without password.
Note that I've added InStr(ThisWorkbook.Name, "Copy of ") = 0 as a condition to the If-statement. Instr returns the position where a substring (arg2) appears in the main string (arg1) or zero if the substring is absent from the main string. In this context, we want it to be zero since we don't want to run the code in the workbook copy.
In this method, the owner of the original file will have to supply their password every time they save. You could automate this by passing the password as an argument to the Open method like this:
Set ReadOnlyWorkbook = Workbooks.Open( _
Filename:=CopyFullName, _
Password:="MyPassword")
However, the password would then be accessible by people looking into the VBA code.
Alternatively you could get the password from a local file that wouldn't be accessible from the Network, but then the file path would be visible.
And if the remote folder is not already set to be Read-only mode, you can make sure that people opening the remote version of the file do so in Read-Only mode by adding the following event procedure after the previous one.
Private Sub Workbook_Open()
If InStr(ThisWorkbook.Name, "Copy of ") = 0 Then
ThisWorkbook.ChangeFileAccess Mode:=xlReadOnly
End If
End Sub
Obviously this will only work if they enable macros.

How do I get my macro to run automatically every Tuesday at 1:20pm? [duplicate]

I have a xlsx macro enabled file . How can I set it in the task manager so that everyday at 9 AM task manager would open the workbook, fire the macro and close the workbook.
So far i am using
Application.OnTime . . .
But i realize that keeping the xlsm file open is inconvenient
Better to use a vbs as you indicated
Create a simple vbs, which is a text file with a .vbs extension (see sample code below)
Use the Task Scheduler to run the vbs
Use the vbs to open the workbook at the scheduled time and then either:
use the Private Sub Workbook_Open() event in the ThisWorkbook module to run code when the file is opened
more robustly (as macros may be disabled on open), use Application.Run in the vbs to run the macro
See this example of the later approach at Running Excel on Windows Task Scheduler
sample vbs
Dim ObjExcel, ObjWB
Set ObjExcel = CreateObject("excel.application")
'vbs opens a file specified by the path below
Set ObjWB = ObjExcel.Workbooks.Open("C:\temp\rod.xlsm")
'either use the Workbook Open event (if macros are enabled), or Application.Run
ObjWB.Close False
ObjExcel.Quit
Set ObjExcel = Nothing
Three important steps - How to Task Schedule an excel.xls(m) file
simply:
make sure the .vbs file is correct
set the Action tab correctly in Task Scheduler
don't turn on "Run whether user is logged on or not"
IN MORE DETAIL...
Here is an example .vbs file:
`
' a .vbs file is just a text file containing visual basic code that has the extension renamed from .txt to .vbs
'Write Excel.xls Sheet's full path here
strPath = "C:\RodsData.xlsm"
'Write the macro name - could try including module name
strMacro = "Update" ' "Sheet1.Macro2"
'Create an Excel instance and set visibility of the instance
Set objApp = CreateObject("Excel.Application")
objApp.Visible = True ' or False
'Open workbook; Run Macro; Save Workbook with changes; Close; Quit Excel
Set wbToRun = objApp.Workbooks.Open(strPath)
objApp.Run strMacro ' wbToRun.Name & "!" & strMacro
wbToRun.Save
wbToRun.Close
objApp.Quit
'Leaves an onscreen message!
MsgBox strPath & " " & strMacro & " macro and .vbs successfully completed!", vbInformation
'
`
In the Action tab (Task Scheduler):
set Program/script: = C:\Windows\System32\cscript.exe
set Add arguments (optional): = C:\MyVbsFile.vbs
Finally, don't turn on "Run whether user is logged on or not".
That should work.
Let me know!
Rod Bowen
I referred a blog by Kim for doing this and its working fine for me. See the blog
The automated execution of macro can be accomplished with the help of a VB Script file which is being invoked by Windows Task Scheduler at specified times.
Remember to replace 'YourWorkbook' with the name of the workbook you want to open and replace 'YourMacro' with the name of the macro you want to run.
See the VB Script File (just named it RunExcel.VBS):
' Create a WshShell to get the current directory
Dim WshShell
Set WshShell = CreateObject("WScript.Shell")
' Create an Excel instance
Dim myExcelWorker
Set myExcelWorker = CreateObject("Excel.Application")
' Disable Excel UI elements
myExcelWorker.DisplayAlerts = False
myExcelWorker.AskToUpdateLinks = False
myExcelWorker.AlertBeforeOverwriting = False
myExcelWorker.FeatureInstall = msoFeatureInstallNone
' Tell Excel what the current working directory is
' (otherwise it can't find the files)
Dim strSaveDefaultPath
Dim strPath
strSaveDefaultPath = myExcelWorker.DefaultFilePath
strPath = WshShell.CurrentDirectory
myExcelWorker.DefaultFilePath = strPath
' Open the Workbook specified on the command-line
Dim oWorkBook
Dim strWorkerWB
strWorkerWB = strPath & "\YourWorkbook.xls"
Set oWorkBook = myExcelWorker.Workbooks.Open(strWorkerWB)
' Build the macro name with the full path to the workbook
Dim strMacroName
strMacroName = "'" & strPath & "\YourWorkbook" & "!Sheet1.YourMacro"
on error resume next
' Run the calculation macro
myExcelWorker.Run strMacroName
if err.number <> 0 Then
' Error occurred - just close it down.
End If
err.clear
on error goto 0
oWorkBook.Save
myExcelWorker.DefaultFilePath = strSaveDefaultPath
' Clean up and shut down
Set oWorkBook = Nothing
' Don’t Quit() Excel if there are other Excel instances
' running, Quit() will shut those down also
if myExcelWorker.Workbooks.Count = 0 Then
myExcelWorker.Quit
End If
Set myExcelWorker = Nothing
Set WshShell = Nothing
You can test this VB Script from command prompt:
>> cscript.exe RunExcel.VBS
Once you have the VB Script file and workbook tested so that it does what you want, you can then use Microsoft Task Scheduler (Control Panel-> Administrative Tools--> Task Scheduler) to execute ‘cscript.exe RunExcel.vbs’ automatically for you.
Please note the path of the macro should be in correct format and inside single quotes like:
strMacroName = "'" & strPath & "\YourWorkBook.xlsm'" &
"!ModuleName.MacroName"
Code below copied from -> Here
First off, you must save your work book as a macro enabled work book. So it would need to be xlsm not an xlsx. Otherwise, excel will disable the macro's due to not being macro enabled.
Set your vbscript (C:\excel\tester.vbs). The example sub "test()" must be located in your modules on the excel document.
dim eApp
set eApp = GetObject("C:\excel\tester.xlsm")
eApp.Application.Run "tester.xlsm!test"
set eApp = nothing
Then set your Schedule, give it a name, and a username/password for offline access.
Then you have to set your actions and triggers.
Set your schedule(trigger)
Action, set your vbscript to open with Cscript.exe so that it will be executed in the background and not get hung up by any error handling that vbcript has enabled.
I found a much easier way and I hope it works for you. (using Windows 10 and Excel 2016)
Create a new module and enter the following code:
Sub auto_open()
'Macro to be run (doesn't have to be in this module, just in this workbook
End Sub
Set up a task through the Task Scheduler and set the "program to be run as" Excel (found mine at C:\Program Files (x86)\Microsoft Office\root\Office16). Then set the "Add arguments (optional): as the file path to the macro-enabled workbook. Remember that both the path to Excel and the path to the workbook should be in double quotes.
*See example from Rich, edited by Community, for an image of the windows scheduler screen.

How to automate the forced closure of excel, followed by a restart?

Occasionally excel freezes or crashes while performing some long running VBA code (runs 24hr/day) and I'm examining ways to handle the restart of excel programmatically. Any advice on best way to go about this would be appreciated.
One idea i have is to write a dotnet app that might be potentially triggered by, say, a windows logging error event such as 'Event Name: APPCRASH' and 'Faulting application EXCEL.EXE', but i have no idea if this is feasible/sensible way to go about it.
If it happens to be a sensible approach, i would envisage the app potentially performing the following tasks;
1) Auto close/cancel any windows error popup boxes such as "Do you want to send more information about the problem?", "Microsoft Excel has stopped working", or "Microsoft Excel is trying to recover your information."
2) Force close excel if still open (eg if hanging), as well as killing any excel.exe processes
3) Restart excel
Is is possible to write such an app in dotnet? What references/tags should i be looking for to find further information?
Thanks,
Yug
After some digging, I pieced together the following solution. The vbs code below will force taskkill any outstanding excel.exe processes, and then opens the stated excel file (from which vba code can be restarted automatically from a worksheet_open event).
1) Turn off Windows error reporting:
Start, search 'Problem Reports and Solutions', change settings, advanced settings, Turn off problem reporting
2) Disable auto recovery for excel:
Within the WB in question, click; file, options, save, disable file recovery for this WB only
3) Under windows event viewer, application logs, highlight the error (faulting excel app) , right click 'create a basic task', run application/script, and enter the chosen name of the file in 4).
4) Paste the following code into text file and save as a vbScript file (.vbs)
Option Explicit
KillProcesses
ExcelRestart
Sub ExcelRestart()
Dim xlApp
Dim xlBook
Set xlApp = CreateObject("Excel.Application")
xlApp.DisplayAlerts = False
Set xlBook = xlApp.Workbooks.Open("C:\...\test.xlsx")
xlApp.visible = True
xlBook.activate
Set xlBook = Nothing
Set xlApp = Nothing
End sub
Sub KillProcesses
On error resume next
Dim objWMIService, WshShell
Dim proc, procList
Dim strComputer, strCommand
strCommand = "taskkill /F /IM excel.exe"
strComputer = "."
Set WshShell = WScript.CreateObject("WScript.Shell")
Set objWMIService = GetObject("winmgmts:"& "{impersonationLevel=impersonate}!\\"& strComputer & "\root\cimv2")
Set procList = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'excel.exe'")
For Each proc In procList
WshShell.run strCommand, 0, TRUE
Next
End sub

Resources