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.
Related
I am running Gnuplot in the confines of VBA and it works surprisingly well. I am able to produce an entire book of about one hundred graphs using GNUPLOT and Word VBA. (With Excel graphs, I could get maybe about four)
There is one small problem - STDERR disappears, or is not being created, when run under VBA. No diagnostics.
Given the following small GNUPLOT script,
set key bmargin left horizontal Right noreverse enhanced autotitle box lt black linewidth 1.000 dashtype solid
set samples 800, 800
set title "Simple Plots"
set title font ",20" norotate
DEBUG_TERM_HTIC = 119
DEBUG_TERM_VTIC = 119
plot [-30:20] sin(x*20)*atan(x)
my VBA code writes it to a temporary file and attempts to run it. VBA generates
"C:\temp\Gnuplot\bin\gnuplot.exe" C:\Users\VVKOZLOV\AppData\Local\Temp\gnuA5E0.txt 2>"C:\Users\VVKOZLOV\AppData\Local\Temp\gnuA5E2.err"
Then runs it with the Windows Shell, invoked like so:
Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
then
wsh.Run x, 0, True ' x contains the generated GNUPLOT expression
GNUPLOT executes flawlessly.
In the GNUPLOT expression, the first item is the location of the GNUPLOT program, which on my system happens to be "C:\temp\Gnuplot\bin\gnuplot.exe". The second file is the temporary generated in the official Microsoft location C:\Users\VVKOZLOV\AppData\Local\Temp\gnuA5E0.txt. Last is the location of STDERR, 2>"C:\Users\VVKOZLOV\AppData\Local\Temp\gnuA5E2.err" where the 2> thing indicates that this is STDERR, not the normal output STDOUT.
Now suppose I introduce a deliberate error into the GNUPLOT source, I would expect an error file written containing something like
scooby doo where are you?
^
"C:\Users\VVKozlov\AppData\Local\Temp\gnuEC55.txt", line 4: invalid command
When executed with the usual CMD.EXE outside of VBA, the STDERR file is created as expected.
When executed in the confines of VBA using the Windows Shell, no STDERR file is created.
How could I get this STDERR file to be produced under VBA?
CreateObject("WScript.Shell").Run executes a command line directly.
Output redirection (the 2> syntax you're using) is a feature of the cmd.exe Windows Command Processor.
What you want to do is either:
Execute cmd.exe with the arguments and redirection you want.
Use CreateObject("WScript.Shell").Exec instead, which gives you access to the input, output, and error streams directly. You would then need to read from the stream and write the contents to a file yourself within the script if you want them recorded to a file.
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
I am currently reprogramming code made long ago by a less than skilled programmer. Granted the code works, and has for a number of years but it is not very efficient.
The code in question is in VB6 with SQL calls and it checks a particular directory on the drive (in this example we will use c:\files) and if a file exists, it moves the file to the processing directory loads the parameters for that particular file and processes them accordingly.
Currently the code uses the DIR function in VB6 to identify a file in the appropriate directory. The only problem is that if a number of files exist in the directory it is a crap shoot as to if it will grab the 5kb file and process it in 3 seconds or if it will grab the 500,000kb file and not process any others for the next 10 minutes.
I search many message boards to find some way to have it pick the smallest file and found I could build a complicated array to perform something similar to a sort but I decided to try alternate ideas instead to hopefully reduce processing time involved. Using ancient DOS knowledge I created something that should work, but for some reason is not (hence posting here).
I made a batch file that we will call c:\test.bat which contained the following lines:
delete c:\test.txt
dir /OS /B c:\files\*.txt>c:\test.txt
This deletes a prior existence of test.txt the pipes a directory without headers sorted by file size smallest to largest into c:\test.txt.
I then inserted the following code into the pre-existing code at the beginning:
Shell "c:\test.bat", vbHide
filepath = "c:\test.txt"
Open filepath For Input As #1
Input #1, filegrabber
Close #1
When I step through the code I can see that this works correctly, except now later on in the code I get a
Runtime error 91 Object variable or with block variable not set
in regard to assigning a FileSystemObject. Am I correct in guessing that FSO and Shell do not work well together? Also if you can suggest a better alternative to getting the smallest file from a existing directory suggestions are appreciated.
No need for sorting.
Just use Dir() to cruise through the directory. Before the loop set a Smallest Long variable to &H7FFFFFFF then inside the loop test each returned file name using the FileLen() function.
If FileLen() returns a value less than Smallest assign that size to Smallest and assign that file name to SmallestFile a String variable.
Upon loop exit if Smallest = &H7FFFFFFF there were no files, otherwise SmallestFile has your file name.
Seems incredibly simple, what am I missing?
Another approach is to use the FileSystemObject's Files collection. Just iterate the files collection for a given folder and evaluate each File object's Size property. So long as you don't have a million files in a folder or something, performance should be fine.
I have a macro in VBA (Excel 2007).
It opens an exe file with entering a HEX value as variable.
The exe gives the output (also a HEX number).
I do everything with "shell" command and the results is saved to a txt file. Then I write this to Excel.
retVal = Shell("cmd.exe /c C:\AABB\app.exe 0x5110 > C:\AABB\output.txt", vbNormalFocus)
It is complicated and time-consuming.
I would prefer getting the result directly to Excel, without an intermediate file like txt or similar.
When I use an output.xlsx as output destination, the file is created and the value is written. But I cant read it with Excel. I see the value when I open the xlsx with Notepad.
My questions are:
1) Is it possible to write the result directly to xlsx, especially a target cell e.g. A10
2) Why when I use xlsx as destination in shell command, I can't open it with Excel? It gives Error Message of "file-format or file-extension is not valid. Data might be corrupted".
I think you can't do that with shell object.
you can do it with WSHExec with the function StdOut.ReadLine().
You have to go to reference and choose "Windows Script Host object model" so you can declare a WshExec object. than see the Method yourWshExecObject.StdOut.ReadLine().
To construct WshExec :
First declare a WshShell Object and you construct it like that :
Dim WshShellObject as WshShell
Dim WshExecObject as WshExec
Set WshShellObject = New WshShell
Set WshExecObject = WshShellObject.Exec("your .exe filename").
The WshExecObject.StdOut TextStream will read everything you write in the console.
I did it with an .exe compilated with C++.
You can also use WshExecObject.StdOut.ReadAll to read all lines at once.
Hope that helps.
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!