見出し画像

マクロのある暮らし(8回目) - 身近で便利なApplicationオブジェクト

こんにちは!なるーらぼです!
今日から4月、新しい年度の始まりですね。新しい生活をはじめた方も多いと思います。素晴らしい年度になるといいですね!
雨が降ってますけど、わたしが新卒のときは4/1は大雨でした(-_-)

身近なのにあまり知らないApplicationオブジェクト

今回はApplicationオブジェクトについてです。
相当身近で、いつもマクロを使うときに近くにいるのですが、VBAが暗黙的に参照してくれるせいでその存在に気づくことは少ないかもしれません。

え?どこにいるかって?いつもいますよ。
例えば、次のコードにも隠れています。どこにいるでしょうか?

Sub note_mu()
 ActiveCell.Value = "エイプリルフールだった!!"
End Sub

ん?どこに?わかりますか?
「ActiveCell」ですよ!

では次です。どこに隠れているかわかりますか?

Sub note_mu()
 ThisWorkbook.Worksheets(1).Range("B1").Value = _
  "ほんとにポケモンなの?"
End Sub

もうお分かりかもしれませんね。「ThisWorkbook」です。

そうです、こうしたオブジェクトだと思っていたものはすべてApplicationオブジェクトのプロパティだったのです。最初のコードは「Application.Activecell」の短縮形、次のものは「Application.ThisWorkbook」の短縮形です。

VBAが暗黙的に参照すべきオブジェクトを探して該当するプロパティを利用することでそれぞれ「アクティブになっているワークブックのアクティブになっているセルを示すRangeオブジェクト」、「現在のマクロが実行されているブックを示すWorkbookオブジェクト」が返されているのです。

便利なやつ

このオブジェクトは実はExcelプロセスを表すもので、Excelそのものと言ってもいいでしょう。このオブジェクトへの参照が残っているとタスクマネージャで見たときに「EXCEL.EXE」が残り続けることになったりしますが…

便利な機能をたくさん持っているのですが、「Active」ではじまるプロパティや「ThisWorkbook」プロパティはいいとして、そのほかのものを少しだけご紹介したいと思います。

おそらく頻繁に利用されるのはユーザーに開く、保存するファイルを選択してもらうためのファイルダイアログでしょう。

Sub note_mu()
 Debug.Print Application.GetOpenFilename( _
              "画像ファイル,*.jpg", _
              1, _
              "画像を選択します", _
              "選択する", False)
End Sub

上記はファイルを開くダイアログを表示して、選択されたファイルのパスを返します。キャンセルを押されたら「False」が返されます。返される値はVariantなんですが、文字列で比較できるので「False」かどうかだけチェックすれば選択されたかどうかわかります。

でもこのメソッドではファイルしか選択できません。そこで利用したいのがFileDialogプロパティです。このプロパティはFileDialogオブジェクトを返すので、これを使います。このオブジェクトには種類があるので、フォルダ選択ができるものが必要な場合は「msoFileDialogFolderPicker」を渡すと思ったものが返されます。

Sub note_mu()
 With Application.FileDialog(msoFileDialogFolderPicker)
  .Title = "フォルダを選択してください"
  .InitialFileName = Environ("UserProfile")
  .ButtonName = "選択する"
  .Show
  Debug.Print .SelectedItems(1)
 End With
End Sub

そのほかに頻繁に目にするのは「DisplayAlerts」プロパティでしょうか。これは警告のメッセージボックスなどを非表示にすることができるので、一括処理したいときなどにいちいちユーザーへ確認をすることなく作業をさせることができます。しかし、デメリットとしてはチェックすべき警告が発生してもメッセージボックスで教えてくれないというのがあります。

Sub note_mu()
 Application.DisplayAlerts = False
 With Workbooks.Add
  .Worksheets(1).Range("A1").Value = "こんにちは"
  '' ここで普通なら保存していないよ、とメッセージが表示
  '' だが、この場合は表示されずに閉じる
  .Close
 End With
 Application.DisplayAlerts = True
End Sub

このプロパティと同じくらいよくあるのがマクロの操作状況が見えてしまうということを防ぐために設定する「ScreenUpdating」というのもありますね。

そのほかの便利なもの

他にも便利なものがいくつかあります。
たとえばバージョンやビルド番号を取得するプロパティである「Version」、「Build」はExcelのバージョンによって処理を分岐するときに役に立ちます。

変わり種としては「UserName」プロパティがあります。現在ログオンしているユーザーの名前を取得することができます。これはドキュメントの更新者や作成者に使われているものと同じようです。

もしもマクロの実行中にマウスポインタのアイコンを変更したい場合は「Cursor」プロパティで変更することができます。例えば砂時計にしたい場合は「xlWait」です。しかし自動的には元に戻りませんのでマクロの終了時にもとに戻すようにしましょう。

さらに変わり種としてはマクロの実行を中断する「Wait」メソッドというのがあります。指定された時間までマクロの実行が延期されますが、完全にExcelの処理が中断されるわけではなくマクロの処理だけが中断されます。ですから「13時に実行」みたいなことはタスクスケジューラから行うべきです。

また、完全に処理が中断されてほしい場合はWindows APIが提供しているsleep関数を利用したほうが良い結果を得ることができます。ただ、ちょっとExcelとはかけ離れていますのでこのあたりにしておきます。興味のある方は調べてみてください。

そのほかにもExcelの実行ファイルが置いてあるフォルダパスを取得できる「Path」プロパティ、任意のマクロを直接コード内から実行できる「Run」メソッドなどがありますが、興味がありましたら必要に応じて調べてみましょう。

おっと、まだ便利だけど用途は自分で考えましょうというものがありました。
「StatusBar」プロパティというのがあります。これはExcelの左下に表示されている部分です。

処理が長ーくなるマクロですと、進み具合が分からないので心配になります。
繰り返し処理のなかでここへ書き込みをしながらにすると、どこまで進んだかわかるのでちょっと安心できます。

Sub note_mu()
 Dim i As Integer
 Dim i As Integer
 For i = 0 To 10
  Application.StatusBar = i & " / 10件中"
  DoEvents
  Application.Wait _
    TimeSerial(Hour(Now), Minute(Now), Second(Now) + 1)
 Next
 Application.StatusBar = False
 DoEvents
End Sub

上記を実行すると、次のような感じで進捗がわかります。

「DoEvents」というステートメントを利用していますが、これはExcelに再描画をしてもらうことができるように一瞬マクロから「スタジオにお返しする」ものです。これでタイムリーに進捗がわかるようになります。

自分でApplicationオブジェクトをつくる

もしもExcelをもうひとつ起動しなければならない、そしてその操作を行う必要があるということが万が一にもあったとしたら。
そういうときにApplicationオブジェクトをつくるにはどうしたらいいでしょうか?

これもよく見かけるかもしれませんが「CreateObject関数」を利用します。

Sub note_mu()
 Dim app As Application
 Set app = CreateObject("Excel.Application")
 With app.Workbooks.Add
  .Worksheets(1).Range("A1").Value = "こんにちは!"
  app.Visible = True
  app.Wait _
   TimeSerial(Hour(Now), Minute(Now), Second(Now) + 3)
  .Worksheets(1).Range("A2").Value = _
        app.InputBox("なにかコメントを", "どうぞどうぞ")
  app.Wait _
   TimeSerial(Hour(Now), Minute(Now), Second(Now) + 3)
  .Close False
 End With
 app.Quit
 Set app = Nothing
 Application.StatusBar = "彼は逝きました..."
 Application.Wait _
  TimeSerial(Hour(Now), Minute(Now), Second(Now) + 3)
 Application.StatusBar = False
 DoEvents
End Sub

Excelを起動するには「Excel.Application」という名前で呼んであげます。終了するには「Quit」メソッドを呼びます。きちんと終了してあげましょう。もしも上記のコードのように「Visible」プロパティを「True」にすることなく操作している間に異常終了した場合はタスクマネージャからしか終了させることができなくなってしまいます。ご注意ください。

最後に

そういえば最後のコードでしれっと使っていますが、InputBoxはApplicationオブジェクトのメソッドだったんですね…

ということで今回はこのあたりで。

この記事が気に入ったらサポートをしてみませんか?