t-hom’s diary

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

VBA 専用ツールを使わないカスタムリボン作成チュートリアル

今回はマクロを実行できるリボン作成方法の紹介。
Excel2013をターゲットにしている。2010でもほぼこの通りにできるが、微妙にrelsに指定するURLが違ったりするのでうまくいかない場合は他のサイトを合わせて確認することをお勧めする。

ブックの準備

新規ブックを作成し、標準モジュールを挿入してオブジェクト名をRibbonに変更する。
f:id:t-hom:20180613023700p:plain

標準モジュールRibbonに次のコードを挿入する。

Private Const RIBBON_TABNAME = "MyOriginalRibbon"
Sub Ribbon_onLoad(Ribbon As IRibbonUI)
    Ribbon.ActivateTab RIBBON_TABNAME
End Sub

Sub RibbonMacros(control As IRibbonControl)
    Application.Run control.Tag, control
End Sub

Private Sub Dummy(control As IRibbonControl)
    Application.Run control.ID
End Sub

この時、RIBBON_TABNAMEの値は任意だが、リボンの目的に沿った適切な名前にすると良い。

一旦ここまででブックを保存して閉じる。
今回はBook1.xlsmとした。

リボン用XMLの作成

保存したBook1のファイル名に拡張子「xlsm」が表示されていることを確認する。
f:id:t-hom:20180613024332p:plain
表示されてなければGoogleで「拡張子 表示」等と検索して設定を済ませる。

ファイル名に拡張子.zipを追加する。
f:id:t-hom:20180613024511p:plain

警告が表示されるが、「はい」で続行する。

Book1.xlsm.zipを右クリックし、メニューから、プログラムから開くをクリック。
f:id:t-hom:20180613024656p:plain

エクスプローラーが選択された状態でOKをクリック。
f:id:t-hom:20180613024748p:plain

エクスプローラーで中身が確認できるので、_relsフォルダを開く。
f:id:t-hom:20180613033818p:plain

中に.relsというファイルが入っている。
この後この.relsを編集するが、zipファイル内で直接編集はできないので一旦外に出す。
具体的には、.relsをデスクトップ等の任意の場所へドラッグ&ドロップでコピーすると良い。
f:id:t-hom:20180613033724p:plain

この.relsをメモ帳で開く。
右端で折り返しを外しておくと良い。
f:id:t-hom:20180613025620p:plain

折り返しを外すと随分と横長の行になるので、><を見つけて間で改行する。
f:id:t-hom:20180613025706p:plain

こんな感じになる。
f:id:t-hom:20180613025828p:plain

最後の</Relationship>の手前の行に次の一行を追記する。

<Relationship Id="customUI" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="customUI/customUI.xml"/>

f:id:t-hom:20180613030154p:plain

上書き保存して閉じる。

保存した.relsをBook1.xlsm.zipの元の位置にコピーする。
f:id:t-hom:20180614011112p:plain

置き換えして良いかどうかの確認が表示されるので、置き換えする方を選択する。
f:id:t-hom:20180613031141p:plain

CustomUI.xmlの作成

メモ帳を新規で開き、次のコードを張り付ける。

<?xml version="1.0" encoding="utf-8"?>
<customUI onLoad="Ribbon_onLoad" xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon>
<tabs>
<tab id="MyOriginalRibbon" label="マイリボン" insertBeforeMso="TabHome">

<group id="GroupA" label="グループA">
	<button id="R_Macro1"
	imageMso="HappyFace"
	size="large"
	label="マクロ1"
	onAction="RibbonMacros"
	tag="Dummy"
	/>

	<button id="R_Macro2"
	imageMso="HappyFace"
	size="large"
	label="マクロ2"
	onAction="RibbonMacros"
	tag="Dummy"
	/>
</group>

<group id="GroupB" label="グループB">
	<button id="R_Macro3"
	imageMso="HappyFace"
	size="large"
	label="マクロ3"
	onAction="RibbonMacros"
	tag="Dummy"
	/>

	<button id="R_Macro4"
	imageMso="HappyFace"
	size="large"
	label="マクロ4"
	onAction="RibbonMacros"
	tag="Dummy"
	/>
</group>

</tab>
</tabs>
</ribbon>
</customUI>

ファイルメニューから名前をつけて保存するが、その際に文字コードUTF-8に、ファイルの種類はすべてのファイルを選択したうえで、CustomUI.xmlという名称で保存する。
f:id:t-hom:20180613032929p:plain

デスクトップ等にCustomUIという名前のフォルダを作り、そこにCustomUI.xmlを格納する。
f:id:t-hom:20180613033104p:plain

Book1.xlsm.zipをエクスプローラーで開き、そのトップ階層にCustomUIフォルダごとコピーする。
f:id:t-hom:20180613033531p:plain

Book1.xlsm.zipを開いているエクスプローラーを閉じ、ファイル名をBook1.xlsmに戻す。
f:id:t-hom:20180613034000p:plain
警告が出るが、続行する。

Excelを起動するとずらっとボタンが並んでいる。
コンテンツを有効化してボタンを押してみよう。
f:id:t-hom:20180613034143p:plain

すると、次のエラーが表示される。
f:id:t-hom:20180613034308p:plain

これは、ボタンに対応するマクロ「R_Macro1」を用意していない為だ。

標準モジュールRibbonに次のコードを追記する。

Private Sub R_Macro1()
    MsgBox "マクロ1が実行されました。"
End Sub

Private Sub R_Macro2()
    MsgBox "マクロ2が実行されました。"
End Sub

Private Sub R_Macro3()
    MsgBox "マクロ3が実行されました。"
End Sub

Private Sub R_Macro4()
    MsgBox "マクロ4が実行されました。"
End Sub

これでもう一度ボタンを押すと、ボタンに対応したマクロが実行される。
f:id:t-hom:20180613034606p:plain

CustomUIの説明

冒頭部分はそれぞれコードとリボンの表示に次のように対応している。
f:id:t-hom:20180613035709p:plain

insertBeforeMso="TabHome"は省略することができ、省略した場合は最後尾のタブになる。

中身のグループとボタンのうち、リボンの表示に関係する部分を赤字で示した。
f:id:t-hom:20180613040602p:plain

次に、実行コードに関係する部分を赤字で示した。
f:id:t-hom:20180613041005p:plain

ボタンが押されると、まずonActionに指定したプロシージャ(RibbonMacros)が呼ばれる。
このとき引数としてリボンのボタンオブジェクトがRibbonMacrosに渡される。

RibbonMacrosはApplication.Runでボタンオブジェクトに指定したタグ("Dummy")に格納された名称のプロシージャを実行する。
このとき引数として、受け取ったボタンオブジェクトをDummyプロシージャに引き渡す。

DummyプロシージャはApplication.Runで受け取ったボタンオブジェクトのID("R_Macro1")に格納された名称のプロシージャを実行する。

私の場合は普段からこのように3段構えでボタンマクロを実行させる仕組みを構築している。
いきなりonActionに実際のマクロ名を書いても良いのだが、そうしないのは三段構えにすると柔軟性が高まる為だ。
タグにはDummyを指定しているが、マクロ1とマクロ2で共通の前処理があった場合は次の用に変更する。

CustomUI.xml

<group id="GroupA" label="グループA">
	<button id="R_Macro1"
	imageMso="HappyFace"
	size="large"
	label="マクロ1"
	onAction="RibbonMacros"
	tag="CommonProcA"
	/>

	<button id="R_Macro2"
	imageMso="HappyFace"
	size="large"
	label="マクロ2"
	onAction="RibbonMacros"
	tag="CommonProcA"
	/>
</group>

VBAProject.Ribbon

Sub RibbonMacros(control As IRibbonControl)
    Application.Run control.Tag, control
End Sub

Private Sub Dummy(control As IRibbonControl)
    Application.Run control.ID
End Sub

Private Sub CommonProcA(control As IRibbonControl)
    MsgBox "共通処理A"
    Application.Run control.ID
End Sub

Private Sub R_Macro1()
    MsgBox "マクロ1が実行されました。"
End Sub

Private Sub R_Macro2()
    MsgBox "マクロ2が実行されました。"
End Sub

すると、マクロ1ボタンとマクロ2ボタンの共通処理をCommonProcAに纏めることができる。
ボタンクリック時に最初に呼ばれるコードをRibbonMacrosに纏めることで、各処理をPrivateにできることも大きい。
リボン側に公開するためにPublicにするのはRibbonMacrosだけで済むのだ。

実際にはR_Macro1の中身は別のモジュールに作成し、R_Macro1はその別モジュールのプロシージャを単に呼び出すだけという作りにすることが多い。
Ribbonモジュールはリボンの処理に専念させる。

参考:ImageMSOのアイコンを探す方法

HappyFace以外のアイコンはこちらで探すと良い。
www.ka-net.org

Bitmapとして一括保存する方法はこちら。
thom.hateblo.jp

オリジナルアイコンをファイルに埋め込んでリボンのボタンに表示させる方法

まずpng画像を用意する。32x32の背景透過アイコンがベストだが、自動的にリサイズされるので細かいつぶれが気にならなければ何でも良い。
適当なものが無い場合、オートシェイプでアイコンを作ってグループ化し、右クリックメニューから図として保存を選択するとpngで保存できる。
f:id:t-hom:20180613051452p:plain

デスクトップ等にimagesというフォルダを作り、用意したpng画像を入れておく。
f:id:t-hom:20180613051622p:plain

次にメモ帳を開き、次のコードを張り付ける。

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

CustomUI.xml.relsという名前で、UTF-8を選択して保存する。
そしてデスクトップ等に_relsというフォルダを作り、CustomUI.xml.relsを格納する。
f:id:t-hom:20180613052033p:plain

Book1.xlsmをBook1.xlsm.zipに変更し、エクスプローラーで開き、CustomUIフォルダを開いて_relsとimagesフォルダをコピーする。
f:id:t-hom:20180613052341p:plain

CustomUI.xmlを一旦デスクトップにコピーし、imageMso="HappyFace"の部分をimage="mySample"に書き換えてから再度zipのCustomUIフォルダに戻す。
Msoが取れて単にimageになるので、ここ間違えないよう注意。

次に、zipの直下にある[Content_Types].xmlをデスクトップにコピーしてメモ帳で開く。

<Default Extension="rels"という表記を探す。
f:id:t-hom:20180613052733p:plain

見つかったらその手前に、<Default Extension="png" ContentType="image/png"/>を挿入する。
f:id:t-hom:20180613052910p:plain

上書き保存し、zipの直下に戻す。

ファイル名をBook1.xlsmに戻し、ファイルを開く。

このように、オリジナルのアイコンが埋め込まれる。
f:id:t-hom:20180613053144p:plain

ImageMSOはなかなか思い通りのアイコンが無かったり、探すのが大変だったり、Excelのバージョンによって表示が異なったりするので、絵心がある方は自分で描くなり、ロイヤリティーフリー素材を活用するなりして素敵なアイコンを用意すると魅力的なツールになると思う。

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