Shell関数 vs WScript.Shell

項目VBA Shell 関数WScript.Shell
参照設定不要不要(CreateObject)
同期実行非同期のみRun で待機可能
標準出力取得不可Exec で取得可
終了コード取得不可可能

Run メソッド(同期実行)

VBA — Run で同期実行
Option Explicit

Sub RunCommandSync()
    Dim wsh     As Object
    Dim exitCode As Long

    Set wsh = CreateObject("WScript.Shell")

    ' 第2引数: ウィンドウスタイル(0=非表示, 1=通常)
    ' 第3引数: True=完了まで待機(同期)
    exitCode = wsh.Run("cmd /c echo Hello > C:\data\test.txt", 0, True)

    Debug.Print "終了コード: " & exitCode   ' 0=成功

    Set wsh = Nothing
End Sub

Exec メソッド(標準出力取得)

VBA — Exec で標準出力を取得
Option Explicit

Function RunAndGetOutput(ByVal command As String) As String
    Dim wsh  As Object
    Dim proc As Object

    Set wsh  = CreateObject("WScript.Shell")
    Set proc = wsh.Exec(command)

    ' プロセス完了まで待機
    Do While proc.Status = 0
        DoEvents
    Loop

    RunAndGetOutput = proc.StdOut.ReadAll

    Set proc = Nothing
    Set wsh  = Nothing
End Function

Sub TestExec()
    Dim result As String
    result = RunAndGetOutput("cmd /c dir C:\ /b")
    Debug.Print result
End Sub

PowerShell 呼び出しパターン

VBA — PowerShell を呼び出す
Option Explicit

Sub RunPowerShell()
    Dim wsh     As Object
    Dim psCmd   As String
    Dim exitCode As Long

    Set wsh = CreateObject("WScript.Shell")

    ' PowerShell スクリプトを実行
    ' -ExecutionPolicy Bypass でポリシーを一時的に回避
    ' -NoProfile でプロファイル読み込みをスキップ(高速化)
    psCmd = "powershell -NoProfile -ExecutionPolicy Bypass " & _
            "-File ""C:\scripts\process_data.ps1"" -Param1 ""value1"""

    exitCode = wsh.Run(psCmd, 0, True)

    If exitCode = 0 Then
        MsgBox "PowerShell スクリプト完了"
    Else
        MsgBox "エラー: 終了コード " & exitCode, vbCritical
    End If

    Set wsh = Nothing
End Sub

' ── インラインコマンドの場合 ──
Sub RunPowerShellInline()
    Dim wsh As Object
    Set wsh = CreateObject("WScript.Shell")

    Dim psCmd As String
    psCmd = "powershell -NoProfile -Command " & _
            """Get-Date -Format 'yyyy-MM-dd' | Out-File C:\data\date.txt"""

    wsh.Run psCmd, 0, True
    Set wsh = Nothing
End Sub

セキュリティ上の注意

⚠️ コマンドインジェクションに注意

ユーザー入力や外部データをコマンド文字列に直接埋め込むのは危険です。必ず値をサニタイズ(引用符のエスケープ等)してから渡してください。特に -Command 形式ではシングルクォート・ダブルクォートの扱いに注意が必要です。

まとめ

WScript.ShellRun(同期・終了コード取得)と Exec(標準出力取得)を使い分けることで、VBAからOSレベルの操作をシームレスに呼び出せます。

次の章では…

PART 15 では JSON処理 を解説します。VBAにネイティブJSONパーサーがない問題への対処法と自前実装・ライブラリ活用を紹介します。

→ PART 15 — JSON処理へ