vba 等待 shell 命令完成

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15951837/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 15:22:19  来源:igfitidea点击:

Wait for shell command to complete

excelshellvbabatch-file

提问by user974047

I'm running a simple shell command in Excel VBA that runs a batch file in a specified directory like below:

我在 Excel VBA 中运行一个简单的 shell 命令,该命令在指定目录中运行一个批处理文件,如下所示:

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

Sometimes the batch file might take longer on some computer to run, and there are proceeding VBA code that is dependent on the batch file to finish running. I know you can set a wait timer like below:

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

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

But that might not work on some computer that are too slow. Is there a way to systematically tell Excel to proceed with the rest of the VBA code until afterthe shell has finish running?

但这可能不适用于某些速度太慢的计算机。有没有一种方法,系统地告诉Excel中使用VBA代码的其余部分进行到壳具有光洁度运行?

回答by Nate Hekman

Use the WScript.Shell instead, because it has a waitOnReturnoption:

改用 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 copied from Wait for Shell to finish, then format cells - synchronously execute a command)

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

回答by Anonymous

Add the following Sub:

添加以下子项:

Sub SyncShell(ByVal Cmd As String, ByVal WindowStyle As VbAppWinStyle)
VBA.CreateObject("WScript.Shell").Run Cmd, WindowStyle, True
End Sub

If you add a reference to C:\Windows\system32\wshom.ocxyou can also use:

如果您添加对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

This version should be more efficient.

这个版本应该更有效率。

回答by Asam

Save the bat file on "C:\WINDOWS\system32" and use below code it is working

将 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   

回答by dadj

what you proposed with a change at the parenthesis at the Run command worked fine with VBA for me

您在 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

回答by geek0

This is what I use to have VBwait for process to complete before continuing. I did not write this and do not take credit.

这是我用来VB在继续之前等待过程完成的方法。这不是我写的,也不是我的功劳。

It was offered in some other open forum and works very well for me:

它是在其他一些开放论坛中提供的,对我来说效果很好:

The following declarations are needed for the RunShellsubroutine:

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)

回答by K_B

Either link the shell to an object, have the batch job terminate the shell object (exit) and have the VBA code continue once the shell object = Nothing?

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

Or have a look at this: Capture output value from a shell command in VBA?

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

回答by Borkman

Dim wsh as new wshshell

将 wsh 调暗为新的 wshshell

chdir "Directory of Batch File"

chdir "批处理文件目录"

wsh.run "Full Path of Batch File",vbnormalfocus, true

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

Done Son

完成儿子