VBAからMS-DOSコマンドを実行する方法

ヘッダー広告
スポンサードリンク
VBAで開発をしているとMS-DOSコマンドを使いたいという時もたまにあります。
そんな時に使えるのが Windows Script Host です。
今回は、VBAからWindows Script Hostオブジェクトを使う方法をご紹介させていただきたいと思います。
 

VBAからWindows Script Hostオブジェクトの呼び出し


Windows Script HostをVBAで使えるように設定


VBAでWindows Script Hostオブジェクトを使えるようにするには、参照設定にて『Windows Script Host Object Model』にチェックをつける必要があります。

この設定をすることによって、今回ご紹介する『WshShell』『WshExec』オブジェクトが使えるようになります。

もし参照設定を行わない場合には、以下のようなコードを記載する必要があります。
set Wsh = CreateObject("WScript.Shell")


参照設定する方が、オブジェクトのメソッド候補が出力されますので、コーディングもしやすいと思います。

WScriptのExecメソッドでコマンド実行


WScriptにてコマンドを実行する方法は2つあります。
まずExecメソッドでコマンド実行する方法です。

Set WShell = New WshShell
WShell.Exec(ここに実行するコマンドを記載)


このようにWshShellオブジェクトのExecメソッドの引数に、実行したいコマンドを入力することで、VBAからコマンドの実行が可能となります。
実行結果は、WshScriptExecオブジェクトに格納され、WshScriptExecからコマンド実行後の標準出力などを操作することが可能となります。

Set WShell = New WshShell
Dim WshExec As WshExec

set WshExec = WShell.Exec(ここに実行するコマンドを記載)
'コマンド実行終了まで待つ
Do Until WshExec.Status = 0
    Call WaitSec(0.1)
Loop

CmdOut = WshExec.StdOut.ReadAll


このようにExecメソッド実行後は、WshScriptExecオブジェクトのStatusプロパティが0になるのを待ちます。
  • Statusプロパティが0は、コマンド実行中状態
  • Statusプロパティが1は、コマンド実行終了状態


StdOutプロパティは、コマンドラインから標準出力に送信された全情報のコピー が保存されます。
ReadAllメソッドを実行することで、コマンド実行結果を確認できます。

ただし、Execメソッドはコマンドプロンプトが画面上にされてしまうという欠点があります。
そのため、VBAから実行する際には、次のRunメソッドを使うことをおすすめします。
 

WshShellのRunメソッドでコマンド実行


まずExecメソッドでコマンド実行する方法です。

Set WShell = New WshShell
WShell.Run("%ComSpec% /c [ここに実行するコマンドを記載], [intWindowStyle], [bWaitOnReturn])


まずExecメソッドはコマンド実行する前提のメソッドですが、Runメソッドはコマンドだけに限らずプログラムを実行するメソッドになります。
そのため、コマンドプロンプトの実行ファイル保存場所を表す環境変数 %ComSpec% と、コマンドの実行することを表す /c オプションをコマンドの前につける必要があります。

※Runメソッド失敗時のエラーについて補足
参照設定を使用せず、WscriptをCreateObjectを使用して作成した際に以下のようなエラーが出力します。

実行時エラー ‘-2147024894 (80070002)’:
‘Run’メソッドは失敗しました: ‘IWshShell3’ オブジェクト

このエラーは、%ComSpec% を指定していないことが原因ですので、今回の記事をご参照いただき修正ください。 私もここで苦戦しました。 エラーとなるコードの例
    Set WShell = CreateObject("WScript.Shell")
    WShell.Run "cd /d D:\", 0, True

●intWindowStyle 引数には、主に以下のような値を設定します。
IntWindowStyle設定値設定内容
0コマンドプロンプトウィンドウを非表示にする。
1コマンドプロンプトウィンドウをアクティブにして元のサイズで表示する。
2コマンドプロンプトウィンドウをアクティブにして、最小化ウィンドウで表示する。
3コマンドプロンプトウィンドウをアクティブにして、最大化ウィンドウで表示する。


VBAでRunメソッドを実行する際には、intWindowStyle引数には 0 を設定するのが好ましいです。
他の値だと、コマンドプロンプトが開いて閉じてというのが見えて気になってしまいます。

●bWaitOnReturn 引数には、TrueかFalseを設定します。
プログラムの実行が終了するのを待つかどうかを設定します。
Trueを指定することで、プログラムの実行が終了するのを待ち、終了後は実行結果のエラーコードを返却します。
Falseを指定すると、プログラムの実行終了は待たずに、エラーコードは成功を表す 0 を必ず返却します。
状況に応じて使い分けると良いです。

●Runメソッドの注意点
Runメソッドは、コマンドを実行した際の標準出力を取得できないです。
そのため、Runメソッドを実行して、標準出力を取得したい際には、リダイレクトを使用してファイルに結果を出力し、取り込むということを行うと良いです。

リダイレクトで結果を出力
Set WShell = New WshShell
WShell.Run("%ComSpec% /c ping localhost > D:\Out.txt", [intWindowStyle], [bWaitOnReturn])

 

サンプルコード


最後にExecメソッド・Runメソッドを使用したVBAのサンプルモジュールをご紹介致します。

Private Const WAIT_TIME As Single = 0.1
Private Const CMD_IN As String = "cd /d ""D:\"" & dir /b"

Public Sub VbaMsDos()

    Dim WShell As WshShell
    Dim WshExec As WshExec
    Dim CmdIn As String
    Dim CmdOut As String

    Set WShell = New WshShell
    
    Set WshExec = WShell.Exec("%ComSpec% /c " & CMD_IN)

    Do Until WshExec.Status = 0
        Call WaitSec(WAIT_TIME)
    Loop
    
    CmdOut = WshExec.StdOut.ReadAll
    
    Debug.Print "Exec結果:" & CmdOut

    CmdOut = WShell.Run("%ComSpec% /c " & CMD_IN, 0, True)

    Debug.Print "Run結果:" & CmdOut

End Sub

Public Sub WaitSec(sngWaitSec As Single)


    Dim sngCurTimer As Single

    '現時刻のTimer関数値に引数の秒数を加えて指定時間経過後の値を設定します
    sngCurTimer = Timer + sngWaitSec

    '現時刻のTimer関数値が所定の経過後の値になるまでループで待ちます
    Do
    Loop Until Timer >= sngCurTimer

End Sub


出力結果
Exec結果:Out.txt
Run結果:0


Exec結果は、Execメソッドを実行した戻り値です。dir /bコマンドを実行後の標準出力であるファイル名が返却されます。
Run結果は、Runメソッドを実行した戻り値です。エラーなしを表す 0 が返却されます。

今回のように、cdコマンドとdirコマンドを&でつなげることで、複数コマンドを同時に実行することも可能です。
(dir D:\とやればいいだけですがあえて)

あとは実際に色々と試しながら使ってみてください。
 

以上、WshScriptExec オブジェクトをVBAから呼び出すことで、VBAからMS-DOSコマンドを実行するという内容でした。
たまにではありますが、ファイルシステムの操作などで使う機会もあると思いますので、参照いただきお役に立ててもらえればと思います。
フッター広告

スポンサードリンク



シェアする

  • このエントリーをはてなブックマークに追加

フォローする