等待shell命令完成

我在Excel VBA中运行一个简单的shell命令,该命令在如下所示的指定目录中运行batch file:

Dim strBatchName As String strBatchName = "C:\folder\runbat.bat" Shell strBatchName 

有时batch file在某些​​计算机上可能需要更长的时间才能运行,并且正在执行的VBA代码依赖于batch file来完成运行。 我知道你可以设置一个等待计时器,如下所示:

 Application.Wait Now + TimeSerial(0, 0, 5) 

但是,这可能无法在一些太慢的计算机上工作。 有没有一种方法可以让系统地告诉Excel继续运行其余的VBA代码,直到shell运行完毕?

改用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复制的想法完成,然后格式化单元格 – 同步执行命令 )

添加以下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 

这个版本应该更有效率。

将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 

你在运行命令中用括号修改的build议对我来说可以和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 

您可以在BATCH完成时创build一个文件,VBA等待该文件创build完成吗? 或者在批处理完成后批量删除一个标志文件,VBA等待标志文件消失?

将shell连接到一个对象,使批处理作业终止shell对象(exit),并在shell对象= Nothing后让VBA代码继续运行?

或者看看这个: 从VBA中的shell命令捕获输出值?

这是我使用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) 

昏暗的wsh作为新的wshshell

chdir“batch file目录”

wsh.run“batch file的完整path”,vbnormalfocus,true

完成儿子