I'd like to launch a Virtual Machine (Oracle VirtualBox) from Excel 2016. I tried with this code but nothing happens, not even errors.
Dim FileName As String
FileName = "D:\Program Files\Oracle\VirtualBox\VirtualBox.exe"" --comment ""PANT"" --startvm ""2c2e4312-6d7d-4892-8a8f-1471a4d2c79d"""
FileName = "cmd.exe /c " & FileName
Debug.Print FileName``
'End
Call Shell(FileName, vbNormalFocus)
Any suggestion??? Thanks
Your line which says:
FileName = "D:\Program Files\Oracle\VirtualBox\VirtualBox.exe"" --comment ""PANT"" --startvm ""2c2e4312-6d7d-4892-8a8f-1471a4d2c79d"""
is creating a string variable which contains the characters:
D:\Program Files\Oracle\VirtualBox\VirtualBox.exe" --comment "PANT" --startvm "2c2e4312-6d7d-4892-8a8f-1471a4d2c79d"
You need an extra double-quotation mark at the start of those characters to "enclose" the filename so that the shell doesn't get confused by the space between "Program" and "Files". So you need the character string to be:
"D:\Program Files\Oracle\VirtualBox\VirtualBox.exe" --comment "PANT" --startvm "2c2e4312-6d7d-4892-8a8f-1471a4d2c79d"
and the code needed to create that would be:
FileName = """D:\Program Files\Oracle\VirtualBox\VirtualBox.exe"" --comment ""PANT"" --startvm ""2c2e4312-6d7d-4892-8a8f-1471a4d2c79d"""
Related
I believe I've replicated the stachoverflow recommended code to sort a .txt file using VBA in Excel. The following is the relevant code from my program. It processes this code without error but does not produce the sorted output file. The IntualityInputRealTimeFIFOTable file is produced correctly. Can't figure out what I'm doing wrong.
Public MyCommand As String
.
.
IntualityInputRealTimeFIFOTable = WorkbookPath & "IntualityInputRealTimeFIFOTable.txt"
IntualityInputRealTimeFIFOTableTemp = WorkbookPath & "IntualityInputRealTimeFIFOTableTemp.txt"
.
.
Close #3
MyCommand = "Sort IntualityInputRealTimeFIFOTable /O IntualityInputRealTimeFIFOTableTemp"
Shell MyCommand, vbHide
We seem to be seeing more and more questions about executing awk on Excel spreadsheets so here is a Q/A on how to do that specific thing.
I have this information in an Excel spreadsheet "$D/staff.xlsx" (where "$D" is the path to my Desktop):
Name Position
Sue Manager
Bill Secretary
Pat Engineer
and I want to print the Position field for a given Name, e.g. output Secretary given the input Bill.
I can currently save as CSV from Excel to get:
$ cat "$D/staff.csv"
Name,Position
Sue,Manager
Bill,Secretary
Pat,Engineer
and then run:
$ awk -F, -v name="Bill" '$1==name{print $2}' "$D/staff.csv"
Secretary
but this is just a small part of a larger task and so I have to be able to do this automatically from a shell script without manually opening Excel to export the CSV file. How do I do that from a Windows PC running cygwin?
The combination of the following VBS and shell scripts create a CSV file for each sheet in the Excel spreadsheet:
$ cat xls2csv.vbs
csv_format = 6
Dim strFilename
Dim objFSO
Set objFSO = CreateObject("scripting.filesystemobject")
strFilename = objFSO.GetAbsolutePathName(WScript.Arguments(0))
If objFSO.fileexists(strFilename) Then
Call Writefile(strFilename)
Else
wscript.echo "no such file!"
End If
Set objFSO = Nothing
Sub Writefile(ByVal strFilename)
Dim objExcel
Dim objWB
Dim objws
Set objExcel = CreateObject("Excel.Application")
Set objWB = objExcel.Workbooks.Open(strFilename)
For Each objws In objWB.Sheets
objws.Copy
objExcel.ActiveWorkbook.SaveAs objWB.Path & "\" & objws.Name & ".csv", csv_format
objExcel.ActiveWorkbook.Close False
Next
objWB.Close False
objExcel.Quit
Set objExcel = Nothing
End Sub
.
$ cat xls2csv
PATH="$HOME:$PATH"
# the original XLS input file path components
inXlsPath="$1"
inXlsDir=$(dirname "$inXlsPath")
xlsFile=$(basename "$inXlsPath")
xlsBase="${xlsFile%.*}"
# The tmp dir we'll copy the XLS to and run the tool on
# to get the CSVs generated
tmpXlsDir="/usr/tmp/${xlsBase}.$$"
tmpXlsPath="${tmpXlsDir}/${xlsFile}"
absXlsPath="C:/cygwin64/${tmpXlsPath}" # need an absolute path for VBS to work
mkdir -p "$tmpXlsDir"
trap 'rm -f "${tmpXlsDir}/${xlsFile}"; rmdir "$tmpXlsDir"; exit' 0
cp "$inXlsPath" "$tmpXlsDir"
cygstart "$HOME/xls2csv.vbs" "$absXlsPath"
printf "Waiting for \"${tmpXlsDir}/~\$${xlsFile}\" to be created:\n" >&2
while [ ! -f "${tmpXlsDir}/~\$${xlsFile}" ]
do
# VBS is done when this tmp file is created and later removed
printf "." >&2
sleep 1
done
printf " Done.\n" >&2
printf "Waiting for \"${tmpXlsDir}/~\$${xlsFile}\" to be removed:\n" >&2
while [ -f "${tmpXlsDir}/~\$${xlsFile}" ]
do
# VBS is done when this tmp file is removed
printf "." >&2
sleep 1
done
printf " Done.\n" >&2
numFiles=0
for file in "$tmpXlsDir"/*.csv
do
numFiles=$(( numFiles + 1 ))
done
if (( numFiles >= 1 ))
then
outCsvDir="${inXlsDir}/${xlsBase}.csvs"
mkdir -p "$outCsvDir"
mv "$tmpXlsDir"/*.csv "$outCsvDir"
fi
Now we execute the shell script which internally calls cygstart to run the VBS script to generate the CSV files (one per sheet) in a subdirectory under the same directory where the Excel file exists named based on the Excel file name (e.g. Excel file staff.xlsx produces CSVs directory staff.csvs):
$ ./xls2csv "$D/staff.xlsx"
Waiting for "/usr/tmp/staff.2700/~$staff.xlsx" to be created:
.. Done.
Waiting for "/usr/tmp/staff.2700/~$staff.xlsx" to be removed:
. Done.
There is only one sheet with the default name Sheet1 in the target Excel file "$D/staff.xlsx" so the output of the above is a file "$D/staff.csvs/Sheet1.csv":
$ cat "$D/staff.csvs/Sheet1.csv"
Name,Position
Sue,Manager
Bill,Secretary
Pat,Engineer
$ awk -F, -v name="Bill" '$1==name{print $2}' "$D/staff.csvs/Sheet1.csv"
Secretary
Also see What's the most robust way to efficiently parse CSV using awk? for how to then operate on those CSVs.
See also https://stackoverflow.com/a/58879683/1745001 for how to do the opposite, i.e. call a cygwin bash command from a Windows batch file.
I want to open a cmd.exe and then execute a few lines of code.
I searched the web for some examples.
Code I tried modifying:
strToPrint = "Hello World!"
Shell "cmd.exe /K echo " & strToPrint, vbNormalFocus
I found How to write message to command window from VBA?
I tried multiple lines of coding, but the lines are executed in different command windows:
Sub CMD_VBA_Script()
Shell "cmd.exe /K echo Hello World!", vbNormalFocus
Shell "cmd.exe /K color 0a", vbNormalFocus
End Sub
I understand when I call the Shell two times, that it will execute two times.
My goal is to call the following script from VBA:
#echo off
title Matrix
color 0a
mode 1000
:a
echo %random%%random%
goto a
How can I execute multiple lines of code from VBA in command prompt?
MyFile = "C:\cmdcode.bat"
fnum = FreeFile()
Open MyFile For Output As #fnum
Print #fnum, "#echo off"
Print #fnum, "title Matrix"
Print #fnum, "color 0a"
Print #fnum, "mode 1000"
Print #fnum, ""
Print #fnum, ":a"
Print #fnum, "echo %random%%random%"
Print #fnum, "goto a"
Close #fnum
' Run bat-file:
Shell MyFile, vbNormalFocus
' optional, remove bat-file:
Kill "C:\cmdcode.bat"
So in short. You need to create a bat-file that you run.
If you don't need the bat-file after it's done you can delete it with Kill
You can write something like this -
Call Shell("cmd.exe /c "cd C:\Users\username\local\temp\" & " && temp.vbs" & " && mkdir newfolder")
This executes 3 lines of command:
Change directory
Execute a vbs file
Make a new folder
It looks like you want to execute a Command Prompt Batch file - batches are stateful, so simply executing each line separately is not going to have the same effect as executing the batch as a whole.
Two other alternative approaches involve faking batch execution by instructing an interactive instance of cmd.exe to execute commands as-they're-entered by some automated process: either sending window messages, or piping into the cmd process' stdin stream. I do not recommend either of these approaches because of their inherent flakiness (i.e. dependency on undocumented behavior)
So the best approach would be to just execute a batch file as it's intended - you would need to write the batch to a temporary file first, and then execute it:
Using the code from here: https://support.microsoft.com/en-us/kb/195763
Dim tempFileName As String
tempFileName = CreateTempFile("SomeBatch.cmd")
WriteToBatchFile( tempFileName ) ' you will have to write to the temp batch file yourself here
Shell "cmd.exe /c """ & tempFileName & """", vbHide, True ' Run the batch file, then cmd.exe will terminate. The Shell function will block until cmd is closed
Kill tempFile ' delete the temp batch file
Use "cmd.exe /K" option, and '&' to connect multiple commands.
In C:\Users\%USERNAME%, create test.bat with two simple commands:
echo %PATH%
dir
Here is the complete sample:
Sub Demo_Multi_Commands()
Cmd1 = "cd " & Environ("USERPROFILE")
Cmd2 = "test.bat"
Connector = " & "
Commands = "cmd.exe /K " & Cmd1 & Connector & Cmd2 & Connector & "systeminfo"
Debug.Print Commands
pid = Shell(Commands, vbNormalFocus)
End Sub
Environment: Windows 10 Enterprise, VBA 7.1
I am currently able to pass one argument from my Excel file to my batch file using the following:
filepath = "C:\Users\agaron\Desktop\batchmaster\batchfiles\batchfiletest.bat " & month
followed by calling a shell command:
Call Shell(filepath, vbNormalFocus)
This works fine. However, I now require to pass not just one, but 18 parameters using the above method. I tried concatenating using the & but it appears that the batch file recognizes all the parameters as a single one.
How can I pass more parameters from Excel to batch file?
Windows batch files get different parameters delimited by spaces. So if your batch file batchfiletest.bat is like:
echo off
echo %1
echo %2
echo %3
pause
then the following VBA should run properly:
Sub testBatch()
sMonth = Format(Now, "mmmm")
sDay = Format(Now, "dd")
sYear = Format(Now, "yyyy")
filepath = "C:\Users\axel\batchfiletest.bat " & sMonth & " " & sDay & " " & sYear
Shell filepath, vbNormalFocus
End Sub
To provide multiple parameters to a batch file, separate them with spaces. If a parameter contains spaces on its own, enclose it in "" (this is also required for some other characters like ,, ;, =; use quotes also for the batch file path in case; the quotes might also be used for every parameter):
"C:\Users\agaron\Desktop\batchmaster\batchfiles\batchfiletest.bat" param1 param2 "param3 with spaces" ...
To access the parameters in the batch file, use the %# syntax, were # represents a single decimal digit (see call /? for details). Note that %0 returns the path of the batch file itself. To remove potential surrounding "", use %~#:
echo This batch file: %~0
echo First parameter: %~1
echo Second parameter: %~2
echo Third parameter: %~3
With the shift command, you shift the assignment of the %# numbers, for instance:
echo This batch file: %~0
shift
echo First parameter: %~0
echo Second parameter: %~1
shift
echo Third parameter: %~1
As you might have noticed, you cannot access the batch file path anymore after the first shift; the next shifts prevents the first parameter from being accessed, and so on (type shift /? for more information).
However, shift lets you access more than 9 parameters. For example, when calling the batch file with a command line like:
"C:\Users\agaron\Desktop\batchmaster\batchfiles\batchfiletest.bat" param1 param2 param3 ... param9 param10
you can access the parameters like:
echo This batch file: %~0
echo Parameter 1: %~1
shift
echo Parameter 2: %~1
shift
echo Parameter 3: %~1
:: ...
shift
echo Parameter 9: %~1
shift
echo Parameter 10: %~1
As you can see, shift provides the possibility to access even more then 9 parameters.
Finally, let us call the batch file via the VBA code:
filepath = Chr(&H22) & "C:\Users\agaron\Desktop\batchmaster\batchfiles\batchfiletest.bat" & Chr(&H22) _
& " " & variable_containing_param1 _
& " " & "param2" _
& " " & Chr(&H22) & "param3 with spaces" & Chr(&H22)
Call Shell(filepath, vbNormalFocus)
I made, better I rummage together an AppleScript that results encrypted zip Files. It works except for Applications. If I expand the Archiv it is not an Application anymore. How can I compress valid Applications?
tell application "Finder"
set theItem to ((choose file) as alias)
set itemPath to quoted form of POSIX path of theItem
set fileName to name of theItem
set theFolder to POSIX path of (container of theItem as alias)
set zipFile to quoted form of (theFolder & fileName & ".zip")
display dialog "Enter password" default answer "" buttons {"OK"} default button 1
set thePassword to (text returned of result)
end tell
set cmd to "zip -P " & thePassword & " -rj " & zipFile & " " & itemPath & " -x *.DS_Store"
do shell script cmd
Check the -y option for zip. It may be what you need.
From iPhone: Compressing .app files in command line (Mac OS X) removes CodeSigning