我在Excel VBA中运行一个简单的shell命令,它在指定的目录中运行批处理文件,如下所示:
Dim strBatchName As String
strBatchName = "C:\folder\runbat.bat"
Shell strBatchName
有时批处理文件可能需要更长时间才能运行某些计算机,并且正在进行的VBA代码依赖于批处理文件来完成运行。我知道你可以设置如下的等待计时器:
Application.Wait Now + TimeSerial(0, 0, 5)
但这可能不适用于速度太慢的计算机。有没有办法系统地告诉Excel继续执行其余的VBA代码,直到在 shell完成运行之后?
答案 0 :(得分:59)
请改用WScript.Shell,因为它有waitOnReturn
选项:
Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 1
wsh.Run "C:\folder\runbat.bat", windowStyle, waitOnReturn
(从Wait for Shell to finish, then format cells - synchronously execute a command复制的想法)
答案 1 :(得分:5)
添加以下Sub:
Sub SyncShell(ByVal Cmd As String, ByVal WindowStyle As VbAppWinStyle)
VBA.CreateObject("WScript.Shell").Run Cmd, WindowStyle, True
End Sub
如果您添加对C:\Windows\system32\wshom.ocx
的引用,您也可以使用:
Sub SyncShell(ByVal Cmd As String, ByVal WindowStyle As VbAppWinStyle)
Static wsh As New WshShell
wsh.Run Cmd, WindowStyle, True
End Sub
这个版本应该更有效率。
答案 2 :(得分:3)
将bat文件保存在“C:\ WINDOWS \ system32”上并使用以下代码进行操作
Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 1
Dim errorCode As Integer
errorCode = wsh.Run("runbat.bat", windowStyle, waitOnReturn)
If errorCode = 0 Then
'Insert your code here
Else
MsgBox "Program exited with error code " & errorCode & "."
End If
答案 3 :(得分:1)
您在Run命令的括号中进行更改的建议对我来说与VBA一起正常工作
Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 1
Dim errorCode As Integer
wsh.Run "C:\folder\runbat.bat", windowStyle, waitOnReturn
答案 4 :(得分:0)
你可以让BATCH在文件完成时创建一个文件,VBA等到文件创建完毕吗?或者在完成后批量删除一个标志文件,VBA会等到标志文件消失?
答案 5 :(得分:0)
将shell链接到对象,让批处理作业终止shell对象(退出)并在shell对象为Nothing时让VBA代码继续吗?
答案 6 :(得分:0)
这是我用VB
等待进程完成之前继续使用的。
我没有写这个,也没有信用。
它在其他一些开放式论坛中提供,对我来说效果非常好:
RunShell
子例程需要以下声明:
Option Explicit
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Const PROCESS_QUERY_INFORMATION = &H400
Private Const STATUS_PENDING = &H103&
'then in your subroutine where you need to shell:
RunShell (path and filename or command, as quoted text)
答案 7 :(得分:-3)
将wsh视为新的wshshell
chdir"批处理文件目录"
wsh.run"批处理文件的完整路径",vbnormalfocus,true
完成儿子