Дождитесь завершения команды оболочки.
Я запускаю простую команду оболочки в Excel VBA, которая запускает пакетный файл в указанном каталоге, как показано ниже:
Dim strBatchName As String
strBatchName = "C:\folder\runbat.bat"
Shell strBatchName
Иногда пакетный файл может занять больше времени на каком-либо компьютере для запуска, и происходит продолжение кода VBA, зависящего от командного файла, для завершения работы. Я знаю, что вы можете установить таймер ожидания, как показано ниже:
Application.Wait Now + TimeSerial(0, 0, 5)
Но это может не работать на некотором компьютере, который слишком медленный. Есть ли способ систематически сообщить Excel, чтобы продолжить работу с остальным кодом VBA, пока после завершения работы оболочки?
Ответы
Ответ 1
Вместо этого используйте 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
(Идея скопирована из Подождите, пока оболочка закончит, затем отформатируйте ячейки - синхронно выполните команду)
Ответ 2
Добавьте следующий 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
Эта версия должна быть более эффективной.
Ответ 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
Ответ 4
то, что вы предложили с изменением в скобках в команде "Запуск", отлично работало с 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
Ответ 5
Может ли BATCH создать файл, когда он закончен, и VBA подождать, пока этот файл не будет создан? Или пакетное удаление флага файла, когда оно закончено, и VBA ждет, пока файл флага не исчезнет?
Ответ 6
Либо свяжите оболочку с объектом, пакетное задание завершает объект оболочки (exit), и код VBA продолжается после объекта оболочки = ничего?
Или взгляните на это:
Захват выходного значения из команды оболочки в VBA?
Ответ 7
Это то, что я использую, чтобы 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)
Ответ 8
Dim wsh как новый wshshell
chdir "Каталог пакетного файла"
wsh.run "Полный путь к пакетному файлу", vbnormalfocus, true
Готовый сын