メニュー

Excel のメニューは、Office で共通で利用されている、
CommandBar クラスを中核に据える、
複雑なクラス群で構築されている。

メニューを操作するためには、
これらのクラスに関する知識が必要だ。

では、目標として、ののぐらむの解答用のメニューを、
「ツール」メニューの中に登録することにしよう。

ツールメニューは、幾つかのグループに分類されているので、
アドインであるソルバや、ゴールシークなどが含まれる、
3 つめのグループに登録することを目標とする。

Excel のメニューやツールバーは、コマンドバーと呼ばれ、
それらはファイルシステムと同じような階層構造である。

ディレクトリに相当するのが、CommandBar クラスであり、
「ユーザ設定」に表示されるツールバーやメニューには、
Application.CommandBars からアクセスできるのだ。

CommandBars コレクションには、
最上位のコマンドバーの参照が格納されており、
コマンドバーの持つ名前を利用して参照を取得する。

まずは、ワークシート用のメニューへの参照を取得する。
Excel のメニューは何種類かあり、
シートの種類によって切り替わる仕組みとなっている。
ののぐらむは、ワークシートに対して利用可能なので、
ワークシート用のメニューに登録する必要がある。

このメニューは、「Worksheet Menu Bar」という名前を持ち、
以下のようにしてアクセスできる。

    Dim oMenuBar As CommandBar

    ' ワークシート用メニューを取得
    Set oMenuBar = Application.CommandBars("Worksheet Menu Bar")

この CommandBar は、中に幾つかのメニュー項目を持つ。
メインメニューの場合、「ファイル」や「編集」などだ。
メニュー項目は、CommandBarControl 総称クラスで表現され、
CommandBar の Controls プロパティから得ることができる。

メニュー項目にはいくつかの種類がある。
「ボタン」、「コンボボックス」、「ポップアップ」だ。
それぞれ、CommandBarButton、CommandBarComboBox、
CommandBarPopup クラスとして表現される。
(これらは CommandBarControl から継承されている)

ボタンは最も一般的な項目である。
コンボボックスは、主にツールバーで使用される。
そして、ポップアップは、さらにサブ項目を持つ項目だ。
つまり、ポップアップはサブディレクトリに相当する。

今回は、「ツール」メニューを取得する。

    Dim oToolsMenu As CommandBarPopup

    ' 「ツール」メニュー項目を取得
    Set oToolsMenu = oMenuBar.Controls("ツール(&T)")

メニュー項目は、メニューの表示名で参照する。
「ツール」メニューの場合、アクセスキーも含む、
「ツール(&T)」という文字列をキーとして参照する。

本当は名前で参照するのはあまりよくない。
ユーザがメニューをカスタマイズした場合、
名前が変更される可能性があるからだ。
Excel には、名前以外にも、ID による参照の方法もあるが、
長くなるので、ここでは割愛することにしよう。

さて、oToolsMenu は、メニュー項目オブジェクトであるが、
ポップアップなので、さらにサブメニューを持つ。
それらサブメニューにアクセスするためには、
サブメニュー項目をあらわす CommandBar を得る必要がある。
これは、CommandBar プロパティでアクセスできる。

    Dim oToolsMenuBar As CommandBar

    ' 「ツール」メニュー項目のサブメニューを取得
    Set oToolsMenuBar = oToolsMenu.CommandBar

このサブメニューに新しいメニュー項目を登録するには、
oToolsMenuBar.Controls.Add メソッドを使用する。

Add メソッドには、挿入位置を指定する引数があり、
サブメニュー内でのメニュー項目の位置を指定すれば、
その直前に新しいメニュー項目を追加することができる。

今回は 3 つめのグループに登録したいので、
4 つめのグループの先頭にある、
「マクロ」メニュー項目の直前に追加することにしよう。

メニュー項目が追加されている可能性もあるので、
メニュー項目の位置を決め打つわけにはいかない、
そこで、まずは「マクロ」メニュー項目への参照を得る。

    Dim oMacroMenu As CommandBarControl

    ' 「マクロ」メニュー項目を取得
    Set oMacroMenu = oToolsMenu.Controls("マクロ(&M)")

これでやっと追加する準備が整った。
Add メソッドを呼んで、新しいボタンを追加する。

    Dim oSolveButton As CommandBarButton

    ' 「マクロ」メニュー項目の直前に新しいメニュー項目を追加
    Set oSolveButton = oToolsMenuBar.Controls.Add( _
            msoControlButton, , , oMacroMenu.Index)

1 つ目の引数はボタンの種類、4 つ目の引数は、
直後のメニュー項目の位置だ。
ここで、「マクロ」メニュー項目の位置を指定する。

Add メソッドは 戻り値として CommandBarControl を返すが、
ボタン(msoControlButton)を指定した場合、
必ず CommandBarButton が返るはずなので、
戻り値を CommandBarButton 型の変数で受ける。

最後に、新しく追加したメニューの表題を設定する。
表題は、Caption プロパティでアクセスできる。

    ' メニューのテキストを設定
    oSolveButton.Caption = "ののぐらむ自動解答(&N)"

上記を適当なマクロに登録して実行してみよう。
ツールメニューに、ののぐらむ自動解答(&N) が登録された。