他アプリを起動する|Excel VBA

関数関連のテクニック

他アプリを起動する

(Excel 2000/2002/2003/2007/2010/2013/2016)

Excelのマクロは基本的にExcelを操作するための機能です。
しかし、ときにはExcel以外の、他のアプリケーションを起動したいこともあるでしょう。
ここでは、VBAで他アプリを起動したり、そのアプリを操作したりするテクニックをご紹介します。

■Shell関数でアプリケーションを起動する

他のアプリケーションを起動する最も簡単な方法の一つはShell関数です。
Shell関数は、引数で指定した実行形式ファイルを起動します。

Sub Sample1()
    Dim rc As Long
    rc = Shell("notepad.exe", vbNormalFocus)
    If rc = 0 Then MsgBox "起動に失敗しました"
End Sub

Sample1はWindows標準ツールの「メモ帳」を起動します。
メモ帳の実行形式ファイルはnotepad.exeで、一般的にはC:\Windows\System32フォルダに保存されています。
Windowsの標準的な環境設定では、C:\Windows\System32フォルダにパスが通っているので、このようにファイル名だけで起動することが可能です。

2番目の引数に指定した定数vbNormalFocusは、起動したアプリケーションを「フォーカスを持ち、元のサイズと位置に復元されるウィンドウ」として表示せよ、という指示です。

また、Shell関数はアプリケーションの起動に成功すると、OSが内部的に使用するタスクIDという数値を返します。このタスクIDには毎回異なる数値が返りますが、起動に失敗したときは0が返ります。

Shell関数で起動したメモ帳をVBAから操作することは難しいです。
起動したメモ帳はアクティブなウィンドウとなるので、VBAからSendKeysという命令を実行して、任意のキーが「押されたこと」にして、何かの操作を行わせることは可能です。
たとえば次のようなコードです。

Sub Sample2()
    Dim rc As Long
    ActiveCell.Copy
    rc = Shell("notepad.exe", vbNormalFocus)
    If rc <> 0 Then
        Application.SendKeys "%EP", True
    Else
        MsgBox "起動に失敗しました"
    End If
End Sub

Shell関数でメモ帳を起動する前に、アクティブセルのデータをコピーしておきます。
メモ帳が起動したらSendKeysメソッドで "%EP" というキーコードを送ります。
これは、[Alt]キーを押しながら[E]キーを押し、続けて[P]キーを押すのと同じことです。
つまり、メモ帳の[編集]メニュー→[貼り付け]を実行しているわけです。

ただし、上記のSample2は環境によっては失敗します。
Shell関数はメモ帳を起動しますが、VBAからはメモ帳が「完全に起動し終わった」かどうかの判断がつきません。したがって、メモ帳が完全に起動し終わる前にSendKeysメソッドが実行されてしまうと、"%EP" のキーコードはExcelに対して送信されてしまうのです。
CPUの速度や、メモリの搭載量などによって、アプリの起動時間やVBAの実行速度は変わるので注意が必要です。

■ファイルに関連付けられたアプリケーションを起動する

エクスプローラなどでデータファイルのアイコンをダブルクリックすると、そのデータファイルに関連づけられているアプリケーションが自動的に起動します。
これは、Windowsがファイルの拡張子とアプリケーションを関連づけて管理しているからです。
こうした"拡張子関連づけ"でアプリケーションを起動するには、WSH(Windows Script Host)の機能を使うと簡単です。

次のコードは、WSHのWshShellクラスのインスタンスを作成し、Runメソッドで"C:\Data\Image.JPG"ファイルを開きます。
Runメソッドは、拡張子JPGの画像ファイルに関連づけられているアプリケーションを起動して画像データを表示します。

Sub Sample3()
    With CreateObject("Wscript.Shell")
        .Run "C:\Data\Image.JPG", 5
    End With
End Sub

Runメソッドの第3引数には、プログラムの実行が終了するまで待つかどうか、をTrue/Falseで指定できます。省略すると待ちません。
次のSample4を実行すると、3つのPDFファイルがたて続けに表示されます。

Sub Sample4()
    With CreateObject("Wscript.Shell")
        .Run "C:\Data\Sample1.pdf", 5
        .Run "C:\Data\Sample2.pdf", 5
        .Run "C:\Data\Sample3.pdf", 5
    End With
End Sub

次のSample5では第3引数にTrueを指定しているため、1つ目のPDFを終了すると2つ目が開き、2つ目のPDFを終了すると3つ目が開きます。

Sub Sample5()
    With CreateObject("Wscript.Shell")
        .Run "C:\Data\Sample1.pdf", 5, True
        .Run "C:\Data\Sample2.pdf", 5, True
        .Run "C:\Data\Sample3.pdf", 5, True
    End With
End Sub

また、第3引数にTrueを指定するとプログラムが返す戻り値を受け取ることができるので、
Sample6のようにバッチファイルを実行し、その結果を判定してから次の処理を行う、といった使い方もできます。

Sub Sample6()
    Dim ret As Long
    
    With CreateObject("Wscript.Shell")
        ret = .Run("C:\Data\DailyTask.bat", 7, True)
    End With
    
    If ret <> 0 Then MsgBox "失敗しました": Exit Sub
    
    '何かの処理
End Sub