はじめに
VBAから Shell
関数でコマンドプロンプトのコマンドを実行できますが、その**実行結果(画面に表示されるテキスト)**をVBAの変数として受け取り、プログラムの中で利用したい、という場面があります。例えば、dir
コマンドの結果からファイルの一覧を取得したり、ping
コマンドの結果からネットワークの疎通を確認したりするケースです。
このような、コマンドの**標準出力(StdOut)**を取得するには、WScript.Shell
オブジェクトの .Run
メソッドの代わりに .Exec
メソッドを使います。
この記事では、.Exec
メソッドを使ってコマンドを実行し、その結果をVBAの文字列変数に格納する、より高度なテクニックを解説します。
コマンドの実行結果を取得するVBAサンプルコード
このマクロは、dir
コマンドを実行して、マクロブックが保存されているフォルダのファイル一覧を取得し、その結果をメッセージボックスに表示します。
完成コード
' コマンドプロンプトの実行結果を文字列として取得する
Sub GetCommandOutput()
Dim shellObj As Object
Dim execResult As Object
Dim commandText As String
Dim outputText As String
'--- 1. WScript.Shellオブジェクトを作成 ---
Set shellObj = CreateObject("WScript.Shell")
'--- 2. 実行したいコマンドを準備 ---
' このブックがあるフォルダのファイル一覧を取得する "dir" コマンド
commandText = "dir """ & ThisWorkbook.Path & """ /B"
'--- 3. .Execメソッドでコマンドを実行 ---
Set execResult = shellObj.Exec("%ComSpec% /c " & commandText)
'--- 4. コマンドの完了を待つ ---
Do While execResult.Status = 0
DoEvents ' CPUを解放し、Excelのフリーズを防ぐ
Loop
'--- 5. 標準出力を読み取る ---
outputText = execResult.StdOut.ReadAll
'--- 6. 結果を表示し、後片付け ---
MsgBox "【ファイル一覧】" & vbCrLf & outputText, vbInformation, "コマンド実行結果"
Set shellObj = Nothing
Set execResult = Nothing
End Sub
コードの解説
Set execResult = shellObj.Exec(...)
.Run
の代わりに .Exec
メソッドを使っているのが最大のポイントです。.Exec
は、実行したコマンドに関する情報(実行状態や、標準入出力など)を格納した WshExec
オブジェクトを返します。
Do While execResult.Status = 0 ... Loop
.Exec
で実行したコマンドは、VBAの処理とは非同期に(バックグラウンドで)実行されます。そのため、コマンドの実行が完了するのを待たずに次の行に進んでしまうと、まだ出力が得られていない、という事態になります。
execResult.Status
: コマンドの実行状態を示すプロパティです。実行中であれば0
、完了すれば1
になります。- この
Do While
ループは、Status
が0
の間(つまり、実行中)はループを続け、コマンドの完了を待つためのものです。 DoEvents
: ループ中にDoEvents
を挟むことで、Excelが他の処理(画面の再描画など)を行う余裕を与え、フリーズしたように見えるのを防ぎます。
outputText = execResult.StdOut.ReadAll
コマンドの実行が完了した後、その実行結果を取得します。
execResult.StdOut
:WshExec
オブジェクトの標準出力ストリームにアクセスします。.ReadAll
: 標準出力の内容を全て文字列として一度に読み取ります。
まとめ
今回は、WScript.Shell
オブジェクトの .Exec
メソッドを使って、コマンドプロンプトの実行結果をVBAで取得する方法を解説しました。
.Exec
メソッドでコマンドを実行し、WshExec
オブジェクトを取得する。.Status
プロパティを監視して、コマンドの完了を待つ。.StdOut.ReadAll
で、標準出力の内容を文字列として取得する。
このテクニックをマスターすれば、VBAの枠を超えて、Windowsに搭載されている様々なコマンドラインツールの機能を、自作のマクロに組み込むことが可能になります。