web-dev-qa-db-ja.com

シェルコマンドが完了するのを待ちます

以下のような指定されたディレクトリでバッチファイルを実行するExcel VBAで簡単なシェルコマンドを実行しています。

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

一部のコンピューターでは、バッチファイルの実行に時間がかかる場合があり、実行を完了するには、バッチファイルに依存しているVBAコードが進行しています。以下のように待機タイマーを設定できることを知っています。

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

しかし、遅すぎるコンピューターでは動作しない場合があります。 after Shellの実行が完了するまで、残りのVBAコードを続行するようにExcelに体系的に指示する方法はありますか?

31
user974047

代わりにwaitOnReturnオプションがあるため、代わりにWScript.Shellを使用します。

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

シェルが終了するのを待ってから、セルをフォーマットする-コマンドを同期的に実行する )からコピーされたアイデア

62
Nate Hekman

次のサブを追加します。

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

このバージョンはより効率的です。

7
Anonymous

「C:\ WINDOWS\system32」にbatファイルを保存し、動作する以下のコードを使用します

   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
Asam

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
2
dadj

これは、続行する前にプロセスが完了するのを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
geek0

シェルをオブジェクトにリンクし、バッチジョブでシェルオブジェクトを終了(終了)し、シェルオブジェクト= NothingになったらVBAコードを続行しますか?

または、これを見てください: VBAのシェルコマンドから出力値をキャプチャしますか?

0
K_B