t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

VBA Application.OnKeyを使い、F1キーで任意のアクティブブックのメインプロシージャを実行させる

今回の記事はF1キーを押したときに、今使用しているブックによって実行するプロシージャを分けるというもの。

執筆のきっかけになったのはこちらの記事のコメント欄のやりとり。
chemiphys.hateblo.jp

OnKeyマクロを記載したブックを閉じた後,そのショートカットを実行すると,OnKeyマクロを記載していたブックを自動的に開いてそのマクロを実行しようとする

なるほど、特定ブックでのみ使用するマクロをOnKey登録し、解除を忘れる(あるいは失敗する)と上記のように想定外の事象になってしまうデメリットがある。

F1キーを特定ブックのマクロに紐づけてしまうと、Excelアプリ全体に作用してしまい、F1キーはそのブックのマクロ実行専用になってしまう。

では、発想を変えて特定ブックに紐づかない実行キーを作ってしまおうと考えたのが今回のネタ。

この記事ではその仕掛けはPersonal.XLSBに作成するが、配布を考慮するならアドイン化しておくのも良いと思う。

まずPersonal.XLSB(個人用マクロブック)のThisWorkbookシートモジュールに以下のコードを記述する。

Private Sub Workbook_Open()
    Application.OnKey "{F1}", "'MacroLauncher ""F1_Key""'"
End Sub

つまりこれで、Excelを起動した際にF1キーにMacroLouncherプロシージャ呼び出しが登録される。
文字列"F1_Key"はMacroLouncherの引数で、実際に呼び出すブックごとのマクロ名を指す。

※本当はF1というプロシージャにしたかったけど名前が不適切となるのでやめた。恐らくキーコード定数と被っているせいかと思う。

わざわざ引数にしたのは後からF3、F4なども簡単に追加できるようにするため。
※F2は個人的にExcel本来のショートカットとしてよく使うのでマクロで上書きするわけにはいかない。

次にPersonal.XLSBに標準モジュールを追加し、以下のコードを記述する。

Sub MacroLauncher(macro_name)
    Dim QuotedBookName As String
    QuotedBookName = "'" & ActiveWorkbook.Name & "'"
    
    On Error Resume Next
        Application.Run QuotedBookName & "!" & macro_name
    On Error GoTo 0
End Sub

こうするとF1キーを押した際にMacroLouncherを経由してApplication.RunでアクティブブックのF1_Keyプロシージャが呼び出されるようになる。On Errorで囲んでいるのでマクロ登録がないブックでは何も起きない。登録がない旨のメッセージを出すようにしても良いかもしれない。

これで準備は整った。
あとはショートカットを使いたいブックごとにF1_Keyプロシージャを作り、それをメインコードにするか、そこからメインコードを呼び出すようにすれば完成。

ただこのテクニックはきわめて個人的な改善なので、チームが共通で使うようなブックだと、なかなか使えない。
F1_Keyプロシージャを作らせてもらうか、それともしれっと作ってしまうか、オフィシャルにして皆にも使ってもらうかという方向になるかと。

あと発展系としてはシートごとにF1キーの意味を変えたい場合にも使えると思う。
Application.Runの引数文字列の書式は 'ブック名'!シートオブジェクト名.マクロ名 である。(試してないけど、たぶん。)

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。