VBA: Shell() command to keep CMD after execution completes - excel

I am executing a .py python script from VBA using the Shell()
Sub Run_Python()
Dim PYTHON_FULL_PATH, PYTHON_SCRIPT_PATH As String
iRowNo = 2
Do Until Sheet7.Cells(iRowNo, 1) = ""
PYTHON_FULL_PATH = Sheet7.Cells(iRowNo, 1)
PYTHON_SCRIPT_PATH = Sheet7.Cells(iRowNo, 2)
iRowNo = iRowNo + 1
Loop
RetVal = Shell(PYTHON_FULL_PATH & " " & PYTHON_SCRIPT_PATH, vbNormalFocus)
End Sub
The Python script prints few lines as part of the code and those print statements are shown in the CMD prompt.
But once the execution completes or errored our the CMD gets closed automatically.
Is there a way to keep the CMD prompt visible even after the execution gets completed ?
Thanks,

Run cmd.exe with /k parameter:
RetVal = Shell("cmd /k " & PYTHON_FULL_PATH & " " & PYTHON_SCRIPT_PATH, vbNormalFocus)

Related

Running Exe File from CMD using VBA Excel

I am trying to run a cmd line from VBA. The command line calls a createReport.exe which creates a final CSV output file using Inputfile.csv
This is what I run manually from Command prompt window:
cd C:\Users\user123\Desktop\MyReport_folder (hits enter)
createReport.exe
-in=C:\Users\user123\Desktop\MyReport_folder\Inputfile.csv (hits enter)
When I run manually, it takes around 45 seconds to create final CSV output file.
When I run the same thing from VBA code, the screen says "starting the query step" and it stays on for 30 seconds, closes and doesn't create the final CSV output file.
Sub RunReport()
Application.DisplayAlerts = False
Dim strProgramName As String
Dim strArgument As String
strProgramName = "C:\Users\user123\Desktop\MyReport_folder\createReport.exe"
strArgument = "-in=C:\Users\user123\Desktop\MyReport_folder\Inputfile.csv"
Call Shell("""" & strProgramName & """ """ & strArgument & """", vbMaximizedFocus)
Application.DisplayAlerts = True
End Sub
I believe you first need to do a ChDir before calling the Shell() command, something like:
ChDir "C:\Users\user123\Desktop\MyReport_folder"
Call Shell("""" & strProgramName ...

How to make this hard-coded file path dynamic?

The code should pass "File Path" in to the File Picker dialog window and upload/attach the file. I'm consistently getting an error.
VBA Code (error at Shell and asking for Object):
Sub AttachFile()
ufile = "D:\Desktop\Movement Pass.txt"
vbsFile = "D:\Downloads\Selenium Basic\Attachment.vbs"
Shell "WScript.exe " & vbsFile & " " & ufile
End Sub
VB Script - Attachment.vbs (error at Arguments):
Set WshShell = CreateObject("WScript.Shell")
Application.wait Now + TimeSerial(0, 0, 5)
Ret = WshShell.AppActivate("Open")
WshShell.Run "cmd.exe /c echo " & Wscript.Arguments(0) & "| clip", 0, True
WshShell.SendKeys "^{v}"
With AutoIt it worked for hard-coded file paths. I want the file path dynamically (so that I can run a loop from Excel VBA). Shell command does not compile and AutoIt does not allow dynamic paths in VBA.
I am looking for a solution in VBA and Shell command. AutoIt dynamic file path in VBA can be a solution too. I know this is not the right method but this is what I know:
VBA.Shell "Explorer D:\Seleninum\VB\Get_File_Name.exe", vbNormalFocus
Paths passed as command line argument need to be quoted if they may contain spaces:
Sub AttachFile()
ufile = "D:\Desktop\Movement Pass.txt"
vbsFile = "D:\Downloads\Selenium Basic\Attachment.vbs"
Shell "WScript.exe """ & vbsFile & """ """ & ufile & """"
End Sub

Check a command window is closed

Below is the code we use to run to check the Ping and Trace for our site address. We have a userform which we need to enter some details and when we hit run this will start running. So when we start running it will create a batch file which (opens a command window) will first the ping and then the Trace. So the ping will finish within a 5 sec but the trace root will take some time and this is not a fixed time. Once both finish running the command window closes automatically. How do the macro knows the command window is closed so that we can enable a button in our userform to submit the report. We need a code to check whether the command window is closed and then it can go to the line "cmdFinishSlow.Enabled = True"
Please can anyone help me with this? Also this will not work in a 64bit Excel, is there any solution for that too?
Dim address, NetStatAN, PingTextFile, BatchFile, TraceTextFile As String
Dim row As Integer
Dim inputline As String
Dim lineitems() As String
Dim Filepath As String
Dim MyFSO As FileSystemObject
Set MyFSO = New FileSystemObject
Filepath = "C:\Users\" & Environ("Username") & "\Desktop\"
BatchFile = "batchfile.bat"
PingTextFile = "PingSite.txt"
TraceTextFile = "TraceSite.txt"
'Call Shell("explorer.exe" & " " & Filepath, vbNormalFocus)
On Error Resume Next
Kill (Filepath & BatchFile)
Kill (Filepath & PingTextFile)
Kill (Filepath & TraceTextFile)
On Error GoTo 0
row = 1
address = Sheets("Slowness Issue").Range("C9").Value
Do Until Trim(address) = ""
Open Filepath & BatchFile For Output As #1
Print #1, "ping " & address & " >>"; Filepath & PingTextFile
Print #1, "tracert -d " & address & " >>"; Filepath & TraceTextFile
Close #1
Call Shell(Filepath & BatchFile)
Application.Wait DateAdd("s", 5, Now) ' wait for 10 seconds
Open Filepath & PingTextFile For Input As #1
Line Input #1, inputline
If Left(inputline, 10) = "Reply from" Then
lineitems() = Split(inputline, " ")
Cells(row, 2) = lineitems(2)
Cells(row, 3) = Now
End If
row = row + 1
address = Cells(row, 1)
Loop
' Here I need to check the command window is closed or not
cmdFinishSlow.Enabled = True
cmdRunSlow.Enabled = False

How to pass argument values from a sub to an excel VBA shell command for remote execution?

I need to run a command (eventually a script) remotely on a linux server invoked locally from within a VBA macro on my windows machine. I tested the command outside of VBA from windows command prompt and it works, but I am not sure how to do the same from within the VBA macro since I need to pass argument values which are the selected values of combobox. I am also unable to redirect the output of Shell to some log file. I looked up few articles online and was able to come up with the following code:
Private Sub UserForm_Initialize()
comboBox1.List = Array("A", "B", "C", "D")
comboBox2.List = Array("1", "2", "3", "4")
End Sub
Private Sub CommandButton1_Click()
Call runCommand
Unload Me
End Sub
Sub runCommand()
Dim Ret_Val
Dim Arg1 As String
Dim Arg2 As String
Dim command As String
Arg1 = comboBox1.Value
Arg2 = comboBox2.value
command = "C:\Program Files\PuTTY\plink.exe" & " -v" & " " & "user#host" & " -pw" & " " & "testpw" & " " & "echo &Arg1,&Arg2"
Ret_Val = Shell(command & ">C:\logs\log.txt", 1)
If Ret_Val = 0 Then
MsgBox "Error!", vbOKOnly
End If
End Sub
Any idea what I am missing here please?
You're passing the string "echo &Arg1,&Arg2" instead of substituting the values of Arg1 and Arg2
You need something more like:
command = "C:\Program Files\PuTTY\plink.exe -v user#host -pw testpw echo " & _
Arg1 & " " & Arg2
If that doesn't work, then provide an example of a known working command line of the type you're trying to generate.

Calling BAT with VBA - CMD Loads and Closes Immediately

I'm using VBA to write a command file and a BAT file which calls PLink to log in to a server and run a script. The Plink portion is now functioning as expected thanks to some help on here. Unfortunately VBA seems to be having some difficulty with opening the cmd and finding plink as a usable command.
I've tried multiple different ways of calling it, but the results are all the same. The cmd prompt opens and then closes immediately giving me an error stating:
"plink is not recognized as an internal or external command, operable program, or batch file."
The files generate perfectly, and if I run the bat file outside of VBA, it runs as expected. With the files, I keep a copy of plink.exe on the desktop. I've even tried adding a copy of cmd.exe to the desktop with the links and plink.exe as well, but I get the same problem.
Here are some of the ways I've tried, though modified for my code: 1 2 3
Here's the most recent code for the macro:
Dim vPath As String
Dim vscript As String
UserID = Range("F1").Value
Passwd = Range("F2").Value
Server = Range("F3").Value
StartDate = Range("F4").Value
EndDate = Range("F5").Value
Set fso = CreateObject("Scripting.FileSystemObject")
fso.CopyFile "C:\Program Files (x86)\PuTTY\plink.exe", "C:\Users\MikeDesktop\"
'fso.CopyFile "C:\Windows\System32\cmd.exe", "C:\Users\Mike\Desktop\"
vPath = "C:\Users\Mike\Desktop"
Open vPath & "\pcmd.txt " For Output As #1
Print #1, "cd /opt/test/srt"
Print #1, "./srt.tool " & StartDate & " " & EndDate & " > /opt/test/srt/test.txt &"
Print #1, "rm test.txt"
Print #1, "sleep 60; exit"
Close #1
Open vPath & "\Chg.bat" For Output As #1
Print #1, "plink " & UserID & "#" & Server & " -pw " & Passwd & " < " & vPath & "\pcmd.txt"
Close #1
vscript = vPath & "\Chg.bat"
Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 5
wsh.Run vscript, windowStyle, waitOnReturn
Application.Wait (Now + TimeValue("0:01:00"))
Kill vPath & "\Chg.bat"
Kill vPath & "\pcmd.txt"
Kill vPath & "\plink.exe"
If someone can tell me why the cmd isn't recognizing plink as an option, that would be much appreciated
Either pass the path to plink.exe in the batch file, or make sure that %Path% includes the folder that contains plink.exe.

Resources