Excel error when using path name as parameter from command line - vba

I am trying to launch a specific Excel document from the command line and pass in a variable in the form of a file path. On starting the Excel sheet runs a macro. This file path may contain spaces however when Excel interprets this it, I believe it tries to open up each section after a space as a new workbook. This results in a number of error warnings after the program runs as it obviously cannot file created from the substring.
The batch file looks like this
echo %~1
start excel.exe %USERPROFILE%\Desktop\Compare.xlsm /e/%1%
pause
EDIT: For Clarification. The batch file is activate when a file is drag and dropped onto it. The path of the file dropped is then stored in the %1 variable. If this file path has spaces then after each space Excel assumes that this is a new worksheet and tries to open it. The call to the Compare.xlsm which contains a macro that is going to use the path of the dragged file works correctly as it will always be on the desktop. My issue therefore is how to get Excel to take the entire path name stored in %1 and use it as one command line parameter rather than several calls to open new workbooks.
If the file that is used on the batch file does not contain any spaces then the errors do not occur. Is there any way of getting rid of the errors when using a file path that might have spaces e.g. C:\Users\My Documents\foobar.txt

Try this (TRIED AND TESTED)
echo %~1
start "excel.exe" "%USERPROFILE%\Desktop\Compare.xlsm" /e/%1%
pause
Notice the quotes around "Excel.Exe" and the file path?
Another example
echo %~1
start "excel.exe" "%USERPROFILE%\Desktop\Blah Blah.xlsm" /e/%1%
pause
I am assuming that you are running the code from a .Bat file

as Sid says, any paths that contain spaces must be quoted.
so to use a pth such as C:\My Documents\fubar.txt you would have this:
"C:\My Documents\fubar.txt"
and in your example:
echo
%~1
start excel.exe "%USERPROFILE%\Desktop\Compare.xlsm" /e/%1%
pause
EDIT:
When using a variable as the path, you need to include the quotes in the variable!

Related

Environment Variables not recognized when calling Run in WScript.Shell object

If I run the command Rscript "C:/TEMP/test.R" in the command line it works and my script runs as expected. Once I try to run it in my VBA code it does not recognize the Rscript as a valid command.
Dim shell_obj As Object
Set shell_obj = VBA.CreateObject("WScript.Shell")
Dim errorCode As Integer
errorCode = shell_obj.Run("Rscript ""C:/TEMP/test.R""", 1, True)
When I looked into the PATH variable being used by the WScript.Shell I saw that it does not include the System Variables with the Rscript path inside of it.
Dim shell_obj As Object
Dim wshSystemEnv As Object
Set shell_obj = VBA.CreateObject("WScript.Shell")
' This one does not include the path to the Rscript'
Debug.Print shell_obj.ExpandEnvironmentStrings("%PATH%")
Set wshSystemEnv = shell_obj.Environment("SYSTEM")
' This one includes the path to the Rscript'
Debug.Print wshSystemEnv("PATH")
Can I force the the WScript.Shell object to use the System environment? Or at least use its variables?
Cmd:
VBA (version 1):
VBA (version 2):
EDIT: See bottom of post.
Hopefully you'll find some use in my (lengthy) take on this... :-)
Testing for command-line readiness
Any command (including an RScript) that can be run as-is from the Windows command-line can also be run with either the VBA Shell function or the Windows WScript.Shell method.
The issue is, your cmd string is not command-line ready. This can be confirmed by hitting +R and pasting the contents of your cmd string variable:
Rscript "**path**/test.R"
I don't currently have rscript.exe installed but I suspect you will get an error if you try running your command manually in either the Run window or on the command line. If it doesn't run there it obviously won't run with in a VBA Shell.
As I understand it, the double asterisk is a Java notation the way you are using it, and in R is the same as a ^ caret character, which is for calculating exponents.
Referencing an environment variable
To return the Windows PATH environment variable in VBA, you would use VBA's Environ function.
To insert the value environment variable inline at the command line, you would surround it with %percent% symbols, like %path%
Windows' PATH environment variable
PATH does not return a single folder. It's a list of folders that Windows should check to find an executable file that one attempts to run.
When a command is entered in a command shell or a system call is made by a program to execute a program, the system first searches the current working directory and then searches the path, examining each directory from left to right, looking for an executable filename that matches the command name given.
The Windows system directory (typically C:\WINDOWS\system32) is typically the first directory in the path, followed by many (but not all) of the directories for installed software packages.
An example a default value of PATH (from a fresh install of Windows 7) is:
%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem
As with %path%, this includes%SystemRoot%` which, by default on Windows 7 is the string:
C:\Windows
Checking environment variables
You can verify the value of your PATH environment label:
Hit +R.
Type cmd and hit Enter. (A command line window should open.)
Type or paste echo %path% and hit Enter.
The contents of the Window PATH environment variable will be displayed.
You can also check environment variables from within Windows:
and type env (to search)
Click Edit the system environment variables. (There is a similar option "...for your account" which is not quite the same.)
Click
Note: Although you technically can change the PATH in this window, I would not recommend doing so, especially with PATH since it is split up into System and User folders, and Windows likes certain folders in certain areas, and some changes don't take effect until reboot but others do, and blah blah blah, trust me: it's easier to do from the command line.
What's wrong with your code?
Therefore it based on all of this, it appears that the command you're trying to run is:
Rscript "C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem/test.R"
...which obviously will not work.
Get or set the current working folder/directory
I can only speculate as to what you're trying to accomplish.
I suspect you didn't intend to return the entire PATH variable, but are only interested in the current working folder.
If so, you don't need to specify a folder at all. Shell already commands execute in the "current" folder.
One way you can check which directory or folder is current, is with the VBA CurDir() function, like:
Debug.Print CurDir()
The value of CurDir can be changed with the ChDir statement.
Similar functions
Note that the CurDur() command is often confused with similar functions like:
Application.Path which returns the path to the Excel application, or,
ActiveWorkbook.Path which returns the location that the active workbook is saved (or an empty string if it's unsaved).
Possible Solution: (How to run an rScript in the current path in VBA)
If your R script and the rscript.exe are both in the current working folder, run it with just one line of VBA:
Shell "rscript.exe test.R", vbNormalFocus
If you require VBA to wait for execution of the Shell command to complete before resuming VBA, then you can you just this one line:
CreateObject("WScript.Shell").Run "rscript.exe test.R", vbNormalFocus, True
More Information:
I generally make a point of including links to any sites I used to verify my answers, so this must be my most-researched answer yet because I've never had a list this long... and I left some off out this time!
Stack Overflow : Running R scripts from VBA
MSDN : Shell Function (VBA)
MSDN : Environ Function (VBA)
R-Bloggers : Passing arguments to an R script from command lines
Stack Overflow : R.exe, Rcmd.exe, Rscript.exe and Rterm.exe: what's the difference?
Stack Exchange: Statistics : Double star ** in R?
Wikipedia : PATH (variable)
Stack Overflow : Default values of PATH variable in Windows 10
SuperUser : Default PATH for Windows 7
MSDN : CurDir() Function (VBA)
MSDN : ChDir() Statement (VBA)
MSDN : Application.Path (Excel/VBA)
MSDN : ActiveWorkbook.Path (Excel/VBA)
Stack Overflow : Wait for Shell command to complete
MSDN Forums : Difference between wscript.shell and shell.application
Stack Overflow : Steps to run R script through Windows command prompt
One More Demo of What's Wrong With Your Code:
I have a batch file named test.bat located in C:\WINDOWS. My PATH environment variable contains C:\WINDOWS (among other things).
If I go to the command prompt in root folder C:\ and type test.bat:
...it runs properly (even though my file is not in that folder... since the c:\windows folder is within the PATH variable.)
However, if I go to the command prompt and type C:\test.bat:
...it does not work. It cannot find the file because I specified a folder where the file is not located.
--- In VBA, if I run the command Shell "test.bat",1:
...it runs properly (even though my file is not in that folder... since the c:\windows folder is within the PATH variable.)
However, if in VBA I run the command Shell "c:\test.bat",1:
...it does not work. It cannot find the file because Ispecified* a folder where the file is not located**.
Both VBA and the Shell command are behaving the same way, when given the same information.
If you have recently modified the system PATH variable, you must restart the Office application you are running VBA from. VBA sends WScript the path variable and only rereads it on a restart. On restart, it will reread the PATH variable from the system and send the new correct path to WScript.
I had the same issue. I had updated the system PATH variable, but the WScript.Shell object was being passed the path variable from Excel rather than reading from the system. Excel had read the path at startup and was not aware it had changed. Once I closed Excel and reopened, WScript had the updated path variable and my script execute successfully.

Call .reg File from Excel-VBA script

I want to call a .reg File out of my VBA script. I'm using Office/Excel 2013.
I know Excel can't run these files by itself, so i need to call the file via shell. The code i wrote doesn't work:
Sub deactivateHyperlinkWarnings()
Dim x
x = Shell("cmd /C C:\TEMP\DisableHyperlinkWarnings.reg")
End Sub
I found this piece of code somewhere on the web, but its not working. I don't even get an error message. The .reg File is located in C:\TEMP
What do i need to write to make it work?
Plus: Is it possible to suppress the MessageBoxes that are displayed when i run the .reg-File? When i start the file manually, i need to Hit "OK" like 3 Times. The people who are working with the Excelsheet later on shouldn't be seeing these things.
Instead of running cmd try to run reg. So in your case it should be x = Shell("reg import C:\TEMP\DisableHyperlinkWarnings.reg")
More info here

Would like to run an Excel macro with drag and drop

I have a macro that asks the user to choose an excel file and then outputs two text files based on the data.
I am looking for a way to just drop the excel file onto the macro file and have it process without the need for opening the macro file, a command button, an open file dialog, etc. I would like to drop the file on the other file and just have the two text files output.
I saw something that looked promising using a VBS file, but was unable to get it to work.
Here's the bare bones of what you need to do:
Wscript.echo "Begin..." 'just letting you know it's working
Set objArgs = Wscript.Arguments 'capture arguments; arg 0 is the name of the dropped file
Wscript.echo "The file name you dropped is:" & objArgs(0)
'DO STUFF TO THE FILE HERE
Wscript.echo "...Finished" 'all done
Save this to a file with a "vbs" extension.
Drag and drop a file onto it.
If your Windows file associations are properly setup,
you'll see this output a message for each of the wscript.echo
lines.

Excel file name changed dynamically

I used an excel template. In my ssis package at first the template is copied in the working directory and package execute. In the next run the excel file which is already existed in the working directory it moved into BACKUP folder and again the template file copied. It works good.
But i want to do something when i move it i want to rename it like is the previous file name is Input_01 in the next move it will input_02. How can i do this?
i am using Execute process task toolbox in SSIS pacakge.
and a .bat file is called. in the .bat file i write
move "E:\InputFolder\Input.xls" "D:\Backup"
copy "E:\Template\Input.xls" "E:\InputFolder\Input.xls"
I want a ouput in the backup folder the excel files are like
Input_01,Input_02.... what will be my command?
Here's how to do it with a batch file:
#echo off
set cnt=1
for /f %%f in ('dir /b "D:\Backup\Input_*.xls"') do set /a cnt+=1
if %cnt% lss 10 (move "E:\InputFolder\Input.xls" "D:\Backup\Input_0%cnt%.xls") else (move "E:\InputFolder\Input.xls" "D:\Backup\Input_%cnt%.xls")
copy "E:\Template\Input.xls" "E:\InputFolder\Input.xls"
You can have more control over your files' naming convention (not to mention deletion of old files) if you use a Script Task, though.
can we use a 'File system task' instead. It helps us Renaming a file. You will have to use a 'For-Each loop Container' as well.

Directing the output of a cmd line procedure to Excel

I am running a cmd command on VBA using call Shell(), but I would like to get the output of the command line to paste it to a range.
something basic like:
forfiles /P C:\Directory\ /S /D %DATE:~4,10%
this returns 99% of the time either nothing or a single string (1 file name) for me which shows the files updated today.
I am hoping to get this output string pasted into a Range. Anyone know a way to redirect outputs?
I guess I can make the cmd line write to a csv and then import but that sounds inefficient to me.
Could you redirect the output of your batch script to a file, then read those file contents into a variable inside your VBA program? Then you could just load that variable value to your range.
You could read the file contents like this:
Open "C:\batch_output.txt" for input as #1
Input #1, textValue
Close #1
Your VBA code could also delete the batch output file when finished if needed.