2013-04-11 160 views
17

我跑在Excel VBA中一个简单的shell命令运行象下面这样的指定目录下的批处理文件:等待shell命令来完成

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

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

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

但是,这可能不适用于某些计算机太慢。有没有办法系统地告诉Excel继续执行其余的VBA代码,直到 shell运行完毕后?

+0

请参阅http://stackoverflow.com/a/1439241/1176601(WaitForSingleObject) – Aprillion 2013-04-11 14:51:43

回答

39

使用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 

(IDEA从Wait for Shell to finish, then format cells - synchronously execute a command复制)

+1

in .net,但不是在VBA中...... – 2013-04-11 14:55:49

+1

好了,修改为使用WScript.Shell。 – 2013-04-11 15:08:59

+0

自2010年升级到2013年(并将.xlam文件移动到C:\ Program Files \ Microsoft Office 15 \ root \ office15 \ Library \)后,我无法再使用此方法启动.exe文件。我假设有一些软文件权限 - 但我已经明确地将自己添加为完全控制权限(我也是管理员的成员,它似乎已经拥有完整的权限),但仍然出现错误:应用程序无法正确启动(0xc000007b)。单击确定关闭该应用程序。任何想法/建议? – Terry 2013-09-27 15:38:16

0

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

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) 
+1

此代码在VBA中不起作用,因为没有定义RunShell – CrazyHorse 2014-05-08 16:07:48

-2

昏暗WSH新的WshShell

CHDIR “批处理文件目录”

wsh。运行“批处理文件的完整路径”,vbnormalfocus,真正

做儿子

+0

不理解您的答案.... – 2014-05-08 16:23:57

1

你与在运行命令括号的变化提出了工作正常使用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 
2

保存在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 
4

添加以下子:

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 

这个版本应该是更有效的。