VB や VBA から外部のプログラムを実行する1つの方法として、Shell 関数を使用する方法があります。
ところが、この Shell 関数はプログラムを起動すると、その終了を待たずに次のステップへと処理を進めてしまいます。
プログラムの終了を待って次の処理に進みたい場合は、Win32API を利用して起動したプロセスの終了を待機しなければなりません。
そのためのサンプルコードを以下に示します。
Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long Public Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Public Const PROCESS_ALL_ACCESS As Long = &H1F0FFF Public Const INFINITE As Long = &HFFFF Sub main() Dim procId As Long 'プロセスID Dim hProc As Variant 'プロセスハンドル procId = Shell("notepad.exe") '外部プログラムを起動します。 hProc = OpenProcess(PROCESS_ALL_ACCESS, False, procId) 'プロセスハンドルを取得します。 If hProc > 0 Then 'プロセスハンドルを取得できた場合 Call WaitForSingleObject(hProc, INFINITE) 'プロセスがシグナル状態になるまで待ちます。 CloseHandle hProc 'プロセスハンドルを解放します。 End If MsgBox ("メモ帳の実行を終了しました。") End Sub
このサンプルコードでは、Shell 関数を使用してメモ帳を起動した後、Win32API の OpenProcess 関数を呼び出して起動したメモ帳のプロセスハンドルを取得し、WaitForSingleObject 関数を呼び出してその終了を待ち、終了すると CloseHandle を使用してそのプロセスハンドルを解放し、次のステップ(メッセージボックスの表示)へと処理を進めています。
Win32API の宣言部や呼び出し部の詳細についてはあえて触れません。詳細についてはWin32APIのリファレンスなどを参照してください。
(私は”おまじない”だと思って記述しています。)