■ Shell関数の基本構文
Shell(pathname [, windowstyle])
- pathname:実行するプログラムのパスやコマンド(文字列)
- windowstyle(省略可能):コマンド実行時のウィンドウの表示方法(整数)
■ windowstyleの主なオプション一覧
定数名 | 値 | 説明 |
---|---|---|
vbHide | 0 | ウィンドウを非表示 |
vbNormalFocus | 1 | 通常のウィンドウでフォーカスあり |
vbMinimizedFocus | 2 | 最小化状態でフォーカスあり |
vbMaximizedFocus | 3 | 最大化状態でフォーカスあり |
vbNormalNoFocus | 4 | 通常ウィンドウでフォーカスなし |
vbMinimizedNoFocus | 6 | 最小化状態でフォーカスなし |
■ 基本的な例
Sub RunNotepad()
Shell "notepad.exe", vbNormalFocus
End Sub
このコードはメモ帳(Notepad)を起動します。
■ コマンドプロンプト(cmd.exe)の実行例
例えば、コマンドラインでディレクトリを削除する場合:
Sub DeleteFolderViaCmd()
Dim folderPath As String
folderPath = "C:\TestFolder"
Shell "cmd /c rmdir /s /q """ & folderPath & """", vbHide
End Sub
解説:
cmd /c
:コマンド実行後にウィンドウを閉じるrmdir /s /q
:/s
:サブディレクトリ含めて削除/q
:確認なし(quietモード)
"""
:VBA内でダブルクォーテーションを文字として使う場合、3重にする必要があります(実際には1文字分)
■ 外部プログラムへの引数付き実行
Sub OpenFileWithProgram()
Dim filePath As String
filePath = "C:\example.txt"
Shell "notepad.exe """ & filePath & """", vbNormalFocus
End Sub
ダブルクォーテーションの扱いに注意が必要です。ファイル名にスペースがある場合、正しく囲まないとエラーになります。
■ Shell関数の戻り値とプロセスID
Dim pid As Long
pid = Shell("notepad.exe", vbNormalFocus)
MsgBox "起動されたプロセスID: " & pid
Shell
関数は起動されたプロセスのIDを返しますが、プロセスの完了を待機することはできません。それには別のAPIが必要です(後述)。
■ ShellAndWait:Shellで実行後に完了を待つ方法
VBAやVBでは、Shell
の実行を待機する標準機能はないため、Windows APIを使って「終了を待つ」関数を作成するのが一般的です。
ShellAndWait関数(API使用)
Private Declare PtrSafe Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As LongPtr
Private Declare PtrSafe Function WaitForSingleObject Lib "kernel32" _
(ByVal hHandle As LongPtr, ByVal dwMilliseconds As Long) As Long
Private Declare PtrSafe Function CloseHandle Lib "kernel32" (ByVal hObject As LongPtr) As Long
Const SYNCHRONIZE = &H100000
Const INFINITE = &HFFFFFFFF
Sub ShellAndWait(cmd As String)
Dim pid As Long
Dim hProc As LongPtr
pid = Shell(cmd, vbHide)
hProc = OpenProcess(SYNCHRONIZE, False, pid)
If hProc <> 0 Then
WaitForSingleObject hProc, INFINITE
CloseHandle hProc
End If
End Sub
使用例:
Sub TestShellAndWait()
ShellAndWait "cmd /c timeout /t 5"
MsgBox "完了しました!"
End Sub
このコードは5秒待ってからメッセージを表示します。
■ ファイルの存在確認後に開く例
Sub OpenIfExists()
Dim path As String
path = "C:\test\document.txt"
If Dir(path) <> "" Then
Shell "notepad.exe """ & path & """", vbNormalFocus
Else
MsgBox "ファイルが存在しません"
End If
End Sub
■ トラブル回避のための注意点
問題 | 対応方法 |
---|---|
パスにスペースがある | """ で囲む |
コマンド完了を待たない | ShellAndWait を使う |
管理者権限が必要な操作 | 通常のShell では実行不可 |
実行できない/無反応 | パスやコマンドの文法ミスを確認する |
32bit/64bit互換性 | Declare PtrSafe の使用に注意(特にVBA) |
■ 応用:バッチファイルの実行
Sub RunBatchFile()
Shell "cmd /c ""C:\scripts\mybatch.bat""", vbHide
End Sub
■ まとめ
Shell
はVB/VBAから外部コマンドやプログラムを呼び出す基本機能。- ファイルやパスにスペースがある場合はダブルクォーテーションで正確に囲む必要がある。
- 実行後の完了待ちはAPIを使うことで可能(
ShellAndWait
)。 - トラブルを避けるには、引数の構文や権限などにも注意する必要がある。