【ExcelVBA】マクロ側からコマンドを指定してバッチファイルで実行するには

この記事では、マクロ側からコマンドを指定してバッチファイルで実行する方法についてご説明します。

【動画】マクロ側からコマンドを指定してバッチファイルで実行する実際の動き

本題に入る前に、まずは次の動画をご覧ください。


マクロ側でコマンドを用意してRunメソッドのパラメタにそのコマンド(とバッチファイル名(フルパス))を設定します。

Runメソッドが実行されるとコマンドがバッチファイル側に渡り、呼び出されたバッチファイルでマクロ側から渡されたコマンドが実行されます。

マクロ側からコマンドを指定してバッチファイルで実行する方法

マクロ側からコマンドを指定してバッチファイルで実行するには、次の流れの通りマクロを作成します。

マクロ作成の流れ

STEP.1
WshShellオブジェクトの生成
WshShellオブジェクトを生成します。
WshShellオブジェクトは、バッチファイルを呼び出して実行させるRunメソッドを実行するのに必要です。
STEP.2
バッチファイルで実行するコマンドをRunメソッドの引数に設定し、バッチファイルに渡してバッチファイルを実行する
バッチファイルで実行するコマンドをRunメソッドの引数に設定し、バッチファイルに渡してバッチファイルを実行します。

コードの例

Excelのマクロとバッチファイルのコードは次の通りに記述していきます。

Excelのマクロのコード(例)

Option Explicit

Private Sub btn_execBatfile_Click()
    
    Dim batFile             As String       'バッチファイル名
    Dim outputFilePath      As String       '出力ファイル
    
    'WshShellオブジェクト
    Dim obj As WshShell
    
    'バッチファイル
    batFile = ThisWorkbook.Path & "\" & "exec.bat"
    
    '出力ファイル
    outputFilePath = ThisWorkbook.Path & "\" & "data.csv"
      
    '出力ファイル存在有無確認処理
    Call fileExistsCheck(outputFilePath)
    
    'WshShellオブジェクトからインスタンスを生成する
    Set obj = New WshShell
    
    '選択されたバッチファイルをパラメタに指定して、バッチファイルを呼び出す
    Range("E6").Value = obj.Run(batFile & " " & "ipconfig /all > C:\work\data.csv", 0, WaitOnReturn:=True)
        
    '後処理
        
    Set obj = Nothing
        
End Sub

Sub fileExistsCheck(outputFilePath As String)
    
    With CreateObject("Scripting.FileSystemObject")
                
        '出力ファイルが存在するか確認する
        If .FileExists(outputFilePath) Then
                      
            '存在する場合は出力ファイルを削除する
            Kill outputFilePath
                      
        End If
    
    End With

End Sub

バッチファイルのコード(例)

※下のコードは、マクロ側から渡されるコマンドのオプションが2つの場合

@echo off

%1 %2 %3

rem コマンド実行後の処理

Excelのマクロのコードの解説

注目すべきコード①

最初に見て頂きたいのは24行目です。

    '選択されたバッチファイルをパラメタに指定して、バッチファイルを呼び出す
    Range("E6").Value = obj.Run(batFile & " " & "ipconfig /all > C:\work\data.csv", 0, WaitOnReturn:=True)

Runメソッドの(第1)引数にバッチファイル名とバッチファイルで実行するコマンドを指定しています。

Runメソッドには、「バッチファイル名」と「バッチファイル実行に必要な引数」を半角スペースでつないた文字列を、第1引数に指定しています。

この「バッチファイル実行に必要な引数」をバッチファイルが受け取り、バッチファイルの処理に使われます。

ちなみに、第2引数にはバッチファイル実行時のコマンドプロンプトのウィンドウの表示方法を指定(0は表示しない)、第3引数には「同期/非同期」の設定値(Trueは同期)を指定しています。

「同期/非同期」とは?
「同期/非同期」とは、呼び出したプログラムの終了をExcelのマクロ側が待つかどうかのことを指します。
同期(True):呼び出したプログラムの終了をExcelのマクロ側が待つ
非同期(False):呼び出したプログラムの終了をExcelのマクロ側が待たない

なお、RunメソッドはWshShellオブジェクトからインスタンスを生成しておかないと実行できないので、必ずインスタンスを生成しておきます。(21行目を参照)

    'WshShellオブジェクトからインスタンスを生成する
    Set obj = New WshShell
【補足】実行したいコマンドをバッチファイルに渡すときの注意点

実行したいコマンドをバッチファイルに渡すときは注意しないといけない点があります

【注意点】マクロ側から渡されたコマンドのオプションは、バッチファイル側では引数で受け取る

マクロ側から渡されたコマンドのオプションは、バッチファイル側では引数で受け取ります。

例えば、「ipconfig /all」というコマンドをバッチファイルで実行したいとします。

この「ipconfig」というコマンドに対して「/all」というオプションを付けていますが、バッチファイルでは「/all」を引数で受け取ります。

なので、バッチファイルで「ipconfig /all」を実行する場合は、バッチファイルのコードは次のように記述します。

@echo off

%1 %2

1つ目の引数用の変数「%1」にはコマンド「ipconfig」が、2つ目の引数用の変数「%2」にはオプション「/all」が格納されます。

「/all」だけでなくもう一つオプションを渡したい場合は、次のコードの通り「%3」を用意する必要があります。

@echo off

%1 %2 %3

1つ目の引数用の変数「%1」にはコマンド本体が、2つ目以降はオプションの数に合わせて「%2」「%3」・・・・というようにコードを記述します。

もしマクロ側から渡されるコマンドのオプションの数よりもバッチファイル側の引数用の変数が少ないと、マクロ側から渡されるはずのオプションが受けれずにオプションなしでコマンドが実行されてしまうので注意が必要です。(バッチファイルで正しくコマンドが実行されない)

注目すべきコード②

次に見て頂きたいのは32行目から46行目です。

Sub fileExistsCheck(outputFilePath As String)
    
    With CreateObject("Scripting.FileSystemObject")
                
        '出力ファイルが存在するか確認する
        If .FileExists(outputFilePath) Then
                      
            '存在する場合は出力ファイルを削除する
            Kill outputFilePath
                      
        End If
    
    End With
 
End Sub

このコードは何をやっているのかというと、「出力ファイルが存在するか確認し、存在していたらその出力ファイルを削除する」というものです。

本編とは外れた内容ではなりますが、出力ファイルがない状態でバッチファイルを呼び出したいのであえてこのコードを記述しました。

動作確認

マクロ側からコマンドを指定してバッチファイルで実行した結果は次の通りです。(コマンドとオプションが1つで実行した場合)

コマンドと1つオプションを付けた「ipconfig /all」をマクロ側が用意してマクロを実行します。(実行された結果をcsvファイルに出力します)

バッチファイルでコマンドが実行されてテキストファイルに実行結果が出力されています。

【参考】コマンドプロンプト上で同じコマンドを実行

コマンドプロンプト上で同じコマンドを実行した結果、同じ内容であることが確認できました。

【注意】参照設定が必要です

一つ注意点があるのですが、先ほどのコードを動かすには参照設定が必要です。

参照設定の一覧(下の画像を参考)から次の項目(ライブラリ)にチェックを付けて「OK」ボタンをクリックします。

  1. Windows Script Host Object Model(wshom.ocx)

なぜ必要かというと、先ほどのコードの9行目でWshShellのインスタンスを生成する際に「wshom.ocx」というファイルを参照するからです。

    'WshShellオブジェクト
    Dim obj As WshShell

この参照設定をしないと下の画像のエラーが出ますので必ず行う必要があります。

ここでは「wshom.ocx」とは何者かについては記事の本題から逸れてしまうので詳細は割愛しますが、マクロで「WshShell」というオブジェクトを使う場合は参照設定しないと動かない、程度に思って頂ければと思います。

最後に

本記事では、マクロ側からコマンドを指定してバッチファイルで実行する方法についてご説明しました。

マクロ側からコマンドを指定してバッチファイルで実行するには、コマンドをRunメソッドの引数に渡してRunメソッドを実行することで、バッチファイルがそのコマンドを受け取り実行することができます。

なお、コマンドにオプションを付けて実行したい場合には、バッチファイル側ではそのオプションがコマンドとは別の引数として扱われて受け取ります。

なので、バッチファイルのコードを記述する際はマクロから渡されるオプションを受け取るための変数の数に漏れがないように気を付けてくださいね。

変数の数に漏れがあるとコマンドにオプションが付かない状態でコマンドが実行されてしまうので注意が必要です。

マクロ側からコマンドを指定してバッチファイルで実行する時は参考にしてみてくださいね。

プログラミングのスキルを習得するなら

プログラミングのスキルを習得したい、今のスキルをもっと高めたい、そう考えているなら「プログラミングスクール」がおすすめです。

プログラミングのスキルの基礎を身につけるなら「TechAcademy」で1週間の無料体験があるので、これで「プログラミングの基礎」を学ぶのにおすすめですよ。

→ TechAcademyの「1週間 無料体験」はこちら