外部実行ファイル起動


外部ファイルの実行

VBAのプログラムは基本的にVBEで作成し、エクセルに組み込まれてエクセル上で実行します。

ですが、すべてをVBAで作るのではなく、すでにある既存のプログラムをVBAから実行させたい場合もあります。

ここでは、VBAからShellを用いたエクセル外部の実行ファイルを呼び出す場合の方法について簡単に解説します。


外部実行ファイルとの連携

すでに一定の機能を備えたプログラムの実行ファイルがあるのに、VBAで同じ処理を書くのは効率的ではないかもしれません。

一般的に実行ファイルといえばexeファイルを指しますが、要するにダブルクリックして実行するタイプの実行ファイルをVBAから呼び出して実行することを考えてみます。

外部ファイルとして以下のような単純なバッチファイルを作成し、これを呼び出してみましょう。

helloworldを出力するだけのバッチファイル

上のtest.batの実行結果は以下のようになります。

helloworld

VBAから実行ファイルを呼び出す

それではこのバッチファイルをVBAから呼び出してみましょう。

実行する前にtest.batをエクセルと同じフォルダ(階層)に置いてください。

なお、今回のプログラムの内容には関係ありませんが、argsは引数で、呼び出すプログラムが引数を受け付ける場合、半角スペースで区切って引数を渡すことができます。

vbNormalFocusは通常のウインドウを指定する引数です。

Sub gaibu1() '外部ファイル名を指定して実行するプログラム1
    Dim args As String
    Shell ThisWorkbook.Path & "/test.bat " & args, vbNormalFocus
End Sub

これを実行してみると以下のようになりました。

helloworld

どちらもHello Worldを表示しており、一見同じ結果になっているようですが、微妙な違いがあります。

デスクトップに置いたtest.batを直接実行した上の画像では>echo Hello Worldの前の文字列がDesktopになっており、エクセルから実行した下の画像ではDocumentsになっているのがわかると思います。

これについて少し補足します。


VBAによるカレントディレクトリの変更

デスクトップ上のバッチファイルをダブルクリック実行した場合、カレントディレクトリはデスクトップになるのに対し、VBAからプログラムを指定して実行した場合、カレントディレクトリはエクセルのカレントディレクトリになります。

それでは先ほどの例ではドキュメントフォルダにエクセルを置いていたのか、とも考えられますが、実はエクセルもデスクトップに置いています。

上の画面はドキュメントフォルダにある別の関係ないエクセルファイルを開き、そのまま先ほどのVBAが書かれたデスクトップ上のエクセルを開いて実行した画面でした。

これだけだと混乱するかもしれませんが、最初のエクセルのプロセスを起動したときにエクセルのカレントディレクトリがDocumentsに決定されており、その後Desktopのエクセルを開いても変更されなかったということになります。

ファイル名を指定して実行している限り、カレントディレクトリに関係なく外部ファイルを実行することはできますが、その呼び出されたプログラムがカレントディレクトリを参照している場合、上のような起動方法の違いが実行結果に影響を与えてしまうことがあります。

「外部ファイル名を指定して実行するプログラム1」ではShell関数を呼び出す前に、以下のコードを書いておくと、カレントディレクトリをVBAを実行しているエクセルのパスに変更することができます。

    ChDir ThisWorkbook.Path

また、以下のように書いても同じように外部ファイルを実行することができます。

Sub gaibu2() '外部ファイル名を指定して実行するプログラム2
    Dim args As String
    Set ws = CreateObject("WScript.Shell")
    ws.CurrentDirectory = ThisWorkbook.Path
    file = ThisWorkbook.Path & "/test.bat " & args
    ws.Run file, vbNormalFocus
    Set ws = Nothing
End Sub

ws.CurrentDirectory = ThisWorkbook.Pathの部分で、カレントディレクトリを変更しています。

今回実行したような単純なプログラムではカレントディレクトリを意識しなくても問題ありませんでしたが、場合によってはVBAの実行中にカレントディレクトリを変更する必要がありますので、注意してください。