リボンにボタンを表示する

Visual Basic for Applications (VBA)

VBAでロジックを記述し、それを実行するときに何かしらのボタンを押して実行するようにすることが多いと思います。シート上にボタンを設けるのが簡単なのですがそうするとイマイチみすぼらしい感じがしますし、Excel標準の操作方法とは違う操作体系となってしまいます。
シート上にボタンを表示するのは簡単だけど

そこでExcel 2007以降で採用されている、リボンにボタンを表示してそのボタンをクリックすることでVBAの処理を実行させるという方法を今回は説明します。リボンに表示することでExcel標準の操作方法と似た操作体系を実現することができます。

この方法を実現するには2通りの方法があります。ひとつは全てVBAで記述する方法。もうひとつはリボンへの表示はcustomUI14.xlmに記述し、実行したいロジックはVBAで記述する方法です。

なお、Excel 2007以降のエクセルファイル(拡張子がxlsxやxlsmなど)は、バイナリーファイルではなく実態はZIPファイルになっていて、そのなかにシートの情報やリボンのカスタマイズするファイルなどが含まれています。customUI14.xlmでリボン表示を設定する場合は重要になりますので覚えておいてください。
Excelファイルの内部(主にリボン関連部分)

VBAコードでリボンに表示する

VBAでリボンに表示することができますが、これは古いExcelのファイル形式(Excel 2003以前拡張子がxlsやxlmなど)でメニューに表示する為のものなので、Excel 2007以降のリボンで表示する場合いくつかの制限があります。

リボンのタブの名称はアドインとなり変更できません。またボタンに表示できるアイコンは小さなアイコンのみとなります。
VBAだけででリボンに表示するとアイコンが小さく、カスタマイズに制限がある

下記に簡単なサンプルコードを載せておきます。環境はWindows 7 Professional 64bitで Excel 2010です。

' ThisWorksheet
Private Sub Workbook_Open()
    Dim bar As CommandBar, ctrl As CommandBarControl
    ' メニューの項目を取得する(アドインタブの独自に追加できる領域)
    Set bar = Application.CommandBars("Worksheet Menu Bar")

    ' 一旦メニューのアイテムをすべて削除
    For Each ctrl In bar.Controls
        Call ctrl.Delete
    Next

    ' メニュー用画像を読み込む
    Dim path As String
    path = ThisWorkbook.path & "¥menuicon.gif"

    ' メニューに表示するアイテムを追加・設定
    ' 表示するのはボタンで、このブックを開いている間だけ有効にする
    Dim menuBtn As CommandBarButton
    Set menuBtn = bar.Controls.Add(MsoControlType.msoControlButton, , , , True)

    With menuBtn
        .BeginGroup = True
        .Caption = "イメージ読込"
        .Style = msoButtonIconAndCaption
        .OnAction = "StartLoadImage"
        .Tag = "Button1"
        .Picture = LoadPicture(path)    ' 正確には stdole.StdFunctions.LoadPicture(path)
    End With
End Sub
' 標準モジュール
Public Sub StartLoadImage()
    Call MsgBox("呼び出されました")
End Sub

CommandBarButtonオブジェクトのOnActionプロパティにボタンが押された時に実行する関数名を記述します。

リボンに大きなボタンを表示したい場合などは、次に紹介するcustomUI14.xmlを使ってリボンに表示するを使うことになります。

customUI14.xmlを使ってリボンに表示する

Excel 2007以降でリボンに表示する推奨方法。難点はVBAだけで完結できずに手順も面倒なところですが、VBAコードでリボンに表示するに比べて、自由度が高くcustomUI14.xmlに記述することで独自リボンを自由にカスタマイズできます。
customUI14.xmlでは大きなアイコンも使えるし、リボンのカスタマイズも容易

リボンに表示する情報はcustomUI14.xmlに記述するのですが、Excel 2007の場合はcustomUI.xmlに記述しなければなりません。ちなみにこのcustomUI14.xmlの14という数字はOffice 2010がバージョン14というところから来ているようです。

Excelバージョン リボン設定ファイル
Excel 2007 customUI.xml
Excel 2010以降 customUI14.xml

Excel 2007以降のファイルの中身はZIPの圧縮ファイルです。それを拡張子xlsxやxlsmにしているだけなので、拡張子をZIPにして解凍することでExcelファイルを構成しているファイルを確認することができます。

リボンに関わるのは、customUIフォルダーに入っているファイルになります。
Excelファイルの内部構造でリボンに関するフォルダーやファイル

ここでは下記のようなリボンへの表示をする場合について説明します。環境はWindows 7 Professional 64bitで Excel 2010です。
customUI14.xmlでは大きなアイコンも使えるし、リボンのカスタマイズも容易

  1. リボンに表示するボタンの画像をgeneric_picture.pngとする場合、customUIフォルダーのimagesフォルダーに画像ファイルgeneric_picture.pngを保存します。
    customUIフォルダーのimagesフォルダーにボタンに表示する画像を保存

  2. そして画像ファイルgeneric_picture.pngをIDで管理できるように、customUI14.xml.relsを設定します。内容は下記になります。

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
        <Relationship Id="loadImageIcon" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="images¥generic_picture.png"/>
    </Relationships>

    RelationShipタグのTaget要素に画像ファイルのパス(ここではimages¥generic_picture.png)を記述し、Id要素にそれに対するID(ここではloadImageIcon)を記述します。このIDは後述のcustomUI14.xmlで利用します。

  3. 最後にリボンへの表示設定するcustomUI14.xmlに記述します。内容は下記になります。

    <customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
        <ribbon>
            <tabs>
                <tab id="customTab" label="サンプル">
                    <group id="etoriKeiriGroup" label="ツール">
                        <button id="customButton1" label="イメージ読み込み" size="large" onAction="StartLoadImage" image="loadImageIcon"/>
                    </group>
                </tab>
            </tabs>
        </ribbon>
    </customUI>

    tabタグがリボンのタグに対応し、そのlabel要素にタブに表示するテキスト(ここではサンプル)を記述します。

    buttonタグのlabelにボタンに表示するテキスト(ここではイメージ読み込み)を、onAction要素に後述する実行したい関数名(ここではStartLoadImage)を記述します。そしてimage要素に、customUI14.xml.relsで記述したID(ここではloadImageIcon)を記述します。

  4. 実行する処理をVBAで記述します。この時単純な関数(Sub)では呼び出されません。IRibbonControl型を引数にとる関数として実装しなければなりません。

    ' 標準モジュール
    Public Sub StartLoadImage(ByVal control As IRibbonControl)
        Call MsgBox("呼び出されました")
    End Sub

手動ですると結構手間になりますが、GUIツールとしてCustom UI Editorといったツールを使うことで、GUIで設定することもできます。ただこのCustom UI Editorは、GitHubからダウンロードしてインストールしようとしてもエラーになってしまうことがありますので、下記参考情報のCustom UI Editorの最新版がGitHubで公開されましたを参考にして利用してください。