41

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

4

7 回答 7

85

请改用 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

(从等待 Shell 完成复制的想法 ,然后格式化单元格 - 同步执行命令)

于 2013-04-11T14:52:12.840 回答
11

添加以下子:

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

这个版本应该更有效率。

于 2015-09-13T14:59:52.870 回答
6

将 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   
于 2014-10-09T07:26:51.610 回答
2

这就是我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)
于 2014-03-05T21:27:28.360 回答
2

您在 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
于 2014-07-18T12:20:22.853 回答
0

要么将外壳链接到一个对象,要么让批处理作业终止外壳对象(退出),并在外壳对象 = 无时让 VBA 代码继续?

或者看看这个: Capture output value from a shell command in VBA?

于 2013-04-11T14:52:41.310 回答
-4

将 wsh 调暗为新的 wshshell

chdir "批处理文件目录"

wsh.run "批处理文件的完整路径",vbnormalfocus, true

完成儿子

于 2014-05-08T16:05:34.637 回答