Excel VBAのTipsとしては、かなりの反則だと思います。だって、Excel VBAの機能ではないのですから。
これは、先日作成していたマクロで、どうしてもこの情報が必要になり、あれこれ探していたら偶然見つけたテクニックです。見つけたときに思ったのは「えぇ~ズルい!」という印象でした(^^;
現在実行しているすべてのソフトを調べるには、タスクマネージャを起動して[アプリケーション]タブを開きます。ここにリストされる「プロセス一覧」をプログラムから取得するには、WindowsのAPIや、WMI(Windows Management Instrumentation)などを使うのが一般的です。この「プロセス一覧」をVBAだけで取得しようというのが今回のテーマです。次のようにやります。
Sub Sample1() Dim WD, task, n As Long Set WD = CreateObject("Word.Application") ''Wordを起動します For Each task In WD.Tasks ''Word VBAのTasksコレクションを調べます If task.Visible = True Then ''タスク(プロセス)が実行中だったら n = n + 1 Cells(n, 1) = task.Name ''タスクの名前を書き出します End If Next WD.Quit Set WD = Nothing End Sub
実行結果と、このときのタスクマネージャは次の通りです。
2行目の「Set WD = CreateObject("Word.Application")」はWordを起動しています。なぜWordが必要かというと、驚くべきことにWordのVBAには現在実行中のタスク一覧を返すTasksコレクションが実装されているからです。正確には、タスクではなく実行中のプロセスでしょうか。本稿では便宜上「タスク」と呼ぶことにします。
なぜWordに!?文章の作成にどう関係してくるのでしょう!?まぁ、Wordについて私は詳しくありませんから、もしかすると何か密接なつながりがあるのかもしれません。いずれにしても、こんなに便利な機能がExcel VBAに実装されていないのはズルい!です(^^;
Tasksコレクションには現在実行中の全タスク(Taskオブジェクト)が含まれますので、For Eachステートメントで取得しています。ただし、実行中の全タスクには、ユーザーが意識しない特別なものも含まれます。それらはWindowsのバックグラウンドで動作しています。そこで、Taskオブジェクト(各プロセス)のVisibleプロパティがTrueかどうかを調べて「実行中」のタスクだけをアクティブシートに書き出しました。
Taskオブジェクトには、いくつかのプロパティやメソッドが用意されています。詳しくはWordのヘルプを呼んでもらうとして(読んでもよくわかりませんけど)、ここでは「もしInternet Explorerが起動していたら終了する」というサンプルを紹介します。まずは、起動しているかどうかを調べてみましょう。
Sub Sample2() Dim WD Set WD = CreateObject("Word.Application") If WD.Tasks.Exists("Internet Explorer") Then MsgBox "Internet Explorerが起動しています", vbInformation End If WD.Quit Set WD = Nothing End Sub
TasksコレクションのExistsメソッドは、指定したタスクが存在するかどうかを返します。引数にはタスクの名前(Nameプロパティ)を指定します。Sub Sample1の結果を見てもらうとわかるように、現在起動しているIEのタスク名は「気象庁 | 週間天気予報 - Microsoft Internet Explorer」ですが、Existsメソッドでは「引数に指定した文字列を含む」タスクが存在した場合にTrueが返ります。ですから、他のタスクに似た名前がないのなら「If WD.Tasks.Exists("Explorer") Then」などでも判定は可能です。
さて、Taskオブジェクトには、指定したタスクを終了させるCloseメソッドが用意されています。起動しているIEを終了するには、先のコードを利用して次のようにします。
Sub Sample2() Dim WD Set WD = CreateObject("Word.Application") If WD.Tasks.Exists("Internet Explorer") Then WD.Tasks("Internet Explorer").Close End If WD.Quit Set WD = Nothing End Sub
さすがに、Closeメソッドで閉じるときは正確な名前を指定しなくてはエラーになるだろうと思ったら、ナント削除できてしまいました。ここまでアバウトだと逆に心配です。それでいいのか?>Tasksコレクション
念のため確認メッセージを出したいのなら、次のようにします。
Sub Sample3() Dim WD, task Set WD = CreateObject("Word.Application") For Each task In WD.Tasks If task.Visible = True And InStr(task.Name, "Internet Explorer") > 0 Then If MsgBox(task.Name & vbCrLf & "を終了させますか?", 36) = vbYes Then task.Close End If End If Next WD.Quit Set WD = Nothing End Sub
心配なので、実行中のタスクで、かつタスク名に"Internet Explorer"を含んでいるかどうかを判定するようにしました。
用途は限られますが、知っていると思わぬときに役立つかもしれないテクニックですね。それにしても、なぜWord VBAにだけ実装されているのでしょうね。ズルいです・・・