VBAからGDI+を使う資料集
inet上の達人の方々から御教示いただいたコードを少しアレンジさせてもらっています(切り貼りとも言います)。
  1. ホーム
  2. ribbon
  3. ribbonsetting


リボンのカスタマイズ方法(エクセル)

リボンのカスタマイズに手を出してみました。 XMLで記述するという話で、なんだかとっても取っつき辛かったのですが、発想を変えてUserFormの一種だとみなせば
よいと思いました。XMLはWin32プログラミングでのリソースファイルといったところでしょうか。(余計に分かり難いですね)
画像入りで親切に記してくれているサイトがいくつもありますが、なかなか記事の通りにいかないのが、PCの常。
備忘録の意味でまとめてみました。

1.最も簡単な自作リボンの作り方 - Windows7 / xl2010用


1.ファイル/オプション/詳細設定で「アドインユーザーインターフェースに関するエラーを表示する」にチェックを入れます。(しくじった時にエラーを出すためです)
2.新規ファイルを作成し、標準モジュールに次のコードを書き込みます。(リボンから呼ばれる時の引数をお忘れ無く)
Sub test(control As IRibbonControl)
  MsgBox "Hello World!"
End Sub
3.マクロ有効で保存し、閉じます。ここではMyTab.xlsmとします。
4.MyTab.xlsmの名前を変更し、末尾に.zipをつけてMyTab.xlsm.zipと改名します。
5.ファイルアイコン上で右クリックして、プログラムから開く/エクスプローラを選びます
6.圧縮フォルダとして開かれるので_relフォルダ内の.relsファイルをデスクトップにコピーします。(コピーしたものでないと編集できません。)
7.コピーした.relsファイルをテキストエディターで開きます。
8.最後の</Relationships>の前に、
<Relationship Id="someID" Type="http://schemas.microsoft.com/office/2007/relationships/ui/extensibility" Target="customUI/customUI14.xml"/>
の行を追加した後、元の場所に書き戻します。
9.デスクトップにcustomUIというフォルダーを作成します。テキストエディターで下記の内容のファイルを作成し、customUI中に、customUI14.xmlという名前で保存します。(UTF-8,CR+LFで保存しないと全角文字を使った時に化けるそうです)。
<?xml version="1.0" encoding="utf-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
  <ribbon>
    <tabs>
      <tab id="CustomTab" label="My Tab">
        <group id="SimpleControls" label="My Group">
          <button id="Button1" 
            imageMso="HappyFace" 
            size="large" 
            label="Large Button" 
            onAction="Test" 
          />
       </group>
     </tab>
    </tabs>
  </ribbon>
</customUI>
10.customUIフォルダーを、圧縮フォルダー内にコピーします。_relフォルダー内では無く、圧縮フォルダ直下にコピーします。
11.MyTab.xlsmと名前を元に戻します。
12.このファイルを開くと、My Tabという新しいタブが出来ており、スマイルアイコンが一個入っています。実行するとHello World!が表示されます。

アドインにして組み込めばいつでも、または別のPCに持っていっても使用できます。
13.Excelアドイン形式でMyTab.xlamとして保存します。保存先はデフォルトの場所でも良いですし、探し易さ優先でデスクトップでもOKです。一旦閉じます。
14.ファイル/オプション/アドインで表示される画面の一番下に「管理(A):」という箇所があり、ドロップダウンにExcelアドインが表示されているので、そのまま「変更」をクリックします。
15.表示されるアドインダイアログの参照ボタンをクリックして、上で保存したMyTab.xlamを指定します。リスト上にMyTabが表示され、チェックされた状態になるので、OKをクリックして閉じます。
16.これでエクセルを起動する都度、リボンにMyTabが組み込まれ使用出来るようになります。
Projectに保護をかけてないと、VBEから自由に見るだけで無く、普通のブック同様にコードの編集、追加が出来てしまいますが、自分で使うぶんにはある意味便利です。個人用マクロブック代わりにもなります。

2.リボンに設けたeditBoxとのデータのやりとりをする - edtiBox<->ActiveCell

ボタンだけだと従来のメニューバーと変わらないので、UserForm風にワークシートと双方向のデータのやりとりをしてみました



2-1 CustomUI14.xmlの内容
・<customUIの項のAttributeに、onLoadを追加
・editBox追加、button追加
・Tagは汎用的な処理クラスを作って利用してやろうかと考えてつけてありますが、クラス作成の方は頓挫しています。

<?xml version="1.0" encoding="utf-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="OnLoad">
<ribbon>
<tabs>
<tab id="CustomTab" label="My Tab">
<group id="SimpleControls" label="My Group">
<editBox id="EditBox1"
 getText="EditBox1_getText"
 label="My EditBox"
 onChange="EditBox1_change"
 tag="editBox"
 sizeString="wwwwwwwwwwwwwwww"
 />
<button id="Button1" 
 imageMso="Copy" 
 size="normal" 
 label="Normal Button" 
 onAction="Button1_click"
 tag="button" 
 />
<button id="Button2" 
 imageMso="Paste" 
 size="normal" 
 label="Normal Button" 
 onAction="Button2_click"
 tag="button" 
 />
</group>
</tab>
</tabs>
</ribbon>

2-2 標準モジュール

'//////////////////////////////////////////////////////////////
'モジュールレベル変数

Private rbribbon As IRibbonUI ' リボンを保持するオブジェクト変数
Dim editBox1Value As String

'//////////////////////////////////////////////////////////////
'Callbackプロシージャ群

'Callback for customUI.onLoad
'ここにcustomUI(リボンを含む)が読み込まれる時に実行する処理を記述する
'1.後で利用するためにリボンをオブジェクト変数に保存する
'2.モジュールレベル変数の初期化

Sub OnLoad(ribbon As IRibbonUI)
  ' リボンの表示を更新できるようにするためにリボンをオブジェクト変数にセットする
  Set rbribbon = ribbon
  'ModuleLevel変数の初期化
  editBox1Value = "initial text"
  'リボンの表示を更新する
  rbribbon.Invalidate
End Sub

'ボタンを押したときの動作を記述 Button1_clickはcustomUI14.xml内でonActionに指定したプロシージャ名
'引数をお忘れ無く(中味、個数はコントロールの種類により異なる)
Sub Button1_click(control As IRibbonControl)
  editBox1Value = ActiveCell.text
  'EditBox1のidを指定して更新
  If rbRibbonExist(rbribbon) Then rbribbon.InvalidateControl "EditBox1"
End Sub

Sub Button2_click(control As IRibbonControl)
  ActiveCell.Value = editBox1Value
End Sub

'Call back for EditBox1 getText
Sub EditBox1_getText(control As IRibbonControl, ByRef text)
  text = editBox1Value
End Sub

'Call back for EditBox1 change
Sub EditBox1_change(control As IRibbonControl, ByRef text)
  editBox1Value = text
'  ActiveCell.Value = editBox1Value
End Sub

'rbRibbonが消えてしまっているか否かの判別とメッセージ
Function rbRibbonExist(rbribbon As IRibbonUI) As Boolean
  If Not rbribbon Is Nothing Then
    rbRibbonExist = True
  Else
    MsgBox "Ribbon My Tabがリセットされています" & vbCrLf & "ブックを開き直して下さい"
    rbRibbonExist = False
  End If
End Function

次の段階として、基本的な機能を盛り込んだスケルトンも用意してあるので、ご覧下さい。
独自リボン作成のためのスケルトン

'**************************************************************
以下は当初の解説で、WindowsXPや、xl2007も視野にいれています

0.最初にファイル/オプション/詳細設定で「アドインユーザーインターフェースに関するエラーを表示する」にチェックを入れます

1.新規ブックを作成して、マクロ有効形式で名前をつけて保存します

2.上記ブックの、拡張子.xlsmの後ろに、.zip を追記します。
xl2007以降のエクセルブックの実体は、zip圧縮されたテキストファイル群なので、
この処理により圧縮されたフォルダとして取り扱える様になります。

3.WindowsXP以降では、Windowsの機能で解凍しなくても圧縮フォルダの中身にアクセスできます。
XPなら、当該フォルダ上で、右クリックメニューから、プログラムから開く、Compressed (zipped) Foldersを選択
7なら、右クリックメニューから、プログラムから開く、エクスプローラを選択
Wクリックすると解凍されてしまうので、要注意
エクスプローラで、左側にフォルダツリーを表示した状態で実行すると、圧縮フォルダのサブフォルダも表示されるので
アクセスしやすいです。

4.上記の方法で圧縮フォルダーにアクセスできますので、_relというフォルダー内の、.relsというファイルを
デスクトップ等にコピーします
これはXMLファイルで、中身はこんなです(本来は改行が入っていないので、エディターで > を >\n に置換すると見やすくなります)
XMLでは改行は意味がありませんので、挿入しても大丈夫です。ちなみに、空行もelement扱いになるそうですが、今回の用途では特に邪魔はしないようでした。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
</Relationships>

5.エディターで開いて、最後の</Relationships>の前に次の行を挿入します。
下記にはcustomUI.xmlとありますが、xl2010用にはcustomUI14.xmlという名前にする方がベターです。Offece Ribbon Editorの様な援用アプリでは、この名前を使っています。(2013/8/14追記)
<Relationship Id="someID" Type="http://schemas.microsoft.com/office/2007/relationships/ui/extensibility" Target="customUI/customUI.xml"/>
ここで、someIDは好きな様につけてOKです。
customUI/customUI.xml は、ユーザーの設定ファイルcustomUI.xmlが、フォルダーcustomUI内にある事を示します。

なお、WEB上の記事で時にみられる下記の記述は、Office2007用です。
<Relationship Id="someID" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="customUI/customUI.xml"/ >

これから作成するcustomUI.xmlの名前空間も、Office2010用または、Office2007用のいずれかに設定する必要がありますが、.relsの記述と整合が
とれている必要があります。(整合していないと、リボンデータを読み込む際に、訳の分からないところでエラーが出ます。)

6.次にエディターで、customUI.xmlを作成します。文字コードutf-8、改行コードcr+lfで保存する事をお忘れ無く。
(2バイト文字を使用したとき、文字化けの原因となります)

<?xml version="1.0" encoding="utf-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
    <ribbon startFromScratch="true">
        <tabs>
            <tab id="CustomTab" label="My Tab">
                <group id="SimpleControls" label="My Group">
                    <button id="Button1" 
                        imageMso="HappyFace" 
                        size="large" 
                        label="Large Button" 
                        onAction="ThisWorkbook.RibbonTest" 
                    />
                </group>
            </tab>
        </tabs>
    </ribbon>
</customUI>

ここでidの「Button1」は任意に名付ける事が出来、イベントコード側で、control.idで取得して利用できます。
onActionに設定するプロシージャ名は従来のイベントの記述にならってButton1_click等にする方が分かり易いでしょう。
このファイルを、デスクトップに作成したフォルダーcustomUIに保存し、フォルダーごと、4の圧縮フォルダー内にコピーします。_relというフォルダー内ではなく、_relの並びです。
なお、上記の記述は、Office2007用です。
Office2010の場合は、
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="OnLoad">
という名前空間にする必要があります。ここで、onLoad以降は、リボンを組み込む際に実行するイベントマクロ名を記述します。

7.1で作成したxlsmファイル(現状は圧縮フォルダー)の拡張子の.zipを取り除き、エクセルのファイルに戻します。

8.VBEでThisworkbookモジュールに、6のonActionに対応するコードを記述します。
Private Sub RibbonTest(ByVal control As IRibbonControl)
    MsgBox "Ribbon Test Successful"
End Sub
なお、標準モジュールに記述すれば、Thisworkbook.の修飾は不要です。

9.以上により、本ブックを開くと、リボンにMy Tabというタブが一個追加され、開くとニコちゃんマークのアイコンがあり、
クリックすると、マクロが実行されます。

このファイルをアドインとして保存して組み込むと、すべてのブックから、本コマンドを使用する事ができる様になります。

イベントの種類と引数の参考
http://msdn.microsoft.com/ja-jp/library/aa722523.aspx

※リボンは従来、マクロの条件設定用のユーザーフォームを作成していた機能を、リボン内に組み込む様な使い方ができ、高機能です。

拡張子を変えないでリボンの設定変更が出来るフリーのユーティリティがいくつか頒布されていますが、0項の設定さえしておけば、
また、通常のXMLのルールからの外れだけチェックしておけば、テキストエディターでなんとかなるでしょう。

使いこなせていませんが、MS純正のXML Notepad 2007というソフトを使用すると、要素の親子関係を表示させて編集ができます。
サードパーティのフリーソフトよりも会社のシステム部門を説得しやすいと思います。なお、2007用と、2010用のスキーマファイルを
MSのサイトからダウンロードして、設定してやる必要があります。→ エラー検出の能力は疑問でした。