等待shell命令完成

时间:2013-04-11 14:46:05

标签: excel shell vba batch-file

我在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完成运行之后?

8 个答案:

答案 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代码继续吗?

或者看看这个: Capture output value from a shell command in 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

完成儿子