【VBA】複数ボタンのクリックイベントをまとめて処理する
下図のようにボタンが10個ばらばらに配置されているユーザーフォームのクリックイベントを取得するにはどうしたらいいでしょうか?

VBAではボタンのクリックイベントはボタン名に"_Click"を付加したプロシージャで拾うことができます。たとえばボタン名が"CommandButton1"のときは次のようなプロシージャをユーザーフォームに記述します。
Private Sub CommandButton1_Click() MsgBox "CommandButton1が押されました" End Sub
10個のコマンドボタンのイベントを取得するには10個のプロシージャを記述する必要があります。各プロシージャから共通の処理へ飛ばすにはコマンドボタンの番号などを引数にしたプロシージャを作ることになります。
Private Sub CommandButton1_Click() Call CommonSub(1) End Sub Private Sub CommandButton2_Click() Call CommonSub(2) End Sub Private Sub CommandButton3_Click() Call CommonSub(3) End Sub '~~~ CommandButton10 までのクリックイベントを記述 ~~~ Private Sub CommonSub(Index As Integer) MsgBox "CommandButton" & Index & "が押されました" End Sub
同じような記述を何度も繰り返すのは冗長です。今回は全体を覆った画像コントロールでイベントを取得する方法を考えてみます。
1.概要

ユーザーフォームに10個のコマンドボタンとそれらを覆う透明なイメージコントロールを配置します。コマンドボタンのクリックイベントはイメージコントロールのマウスダウンイベントに代替させます。
2.ユーザーフォームを作る
まず最初に新規ブックでVBE画面を表示してユーザーフォームを追加し、コマンドボタンを10個配置します(位置は適当に)。
次にイメージコントロールをすべてのコマンドボタンを覆うように配置します。

イメージコントロールは「透明」で枠線を「なし」にします。
| プロパティ | 値 |
|---|---|
| (オブジェクト名) | Image1 |
| BackStyle | 0 - fmBackStyleTransparent |
| BorderStyle | 0 - fmBorderStyleNone |
| Picture | (なし) |
またコマンドボタンを覆うために表示を最前面にする必要があるので、メニューから [書式]→ [順序]→[最前面へ移動] をクリックします。イメージ(Picture)を指定せず背景(BackStyle)を透明にすると裏に隠れているはずのコマンドボタンが透けて見えます。コマンドボタンをクリックしても前面にあるイメージコントロールがクリックされてコマンドボタンのクリックイベントは発生しません。
3.ユーザーフォームのコード
ユーザーフォームにイメージコントロールのマウスダウンイベントを記述します。
Private Sub Image1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) With Image1 X = X + .Left Y = Y + .Top End With Dim Index As Integer For Index = 1 To 10 Dim btn As CommandButton Set btn = Controls("CommandButton" & Index) With btn If X >= .Left And X < .Left + .Width And Y >= .Top And Y < .Top + .Height Then .BackColor = &H80000005 MsgBox "CommandButton" & Index & "が押されました" Else .BackColor = &H8000000F End If End With Next End Sub
イメージコントロールにはコマンドボタンのようなクリックイベントはありません。拾うことのできるイベントはマウスダウンかマウスアップということになるのですが、今回はマウスダウンを使いました。
4.プログラムの実行
メニューから [実行]→[Sub/ユーザーフォームの実行] でプログラムが実行できます。

適当なコマンドボタンをクリックするとクリックしたコマンドボタンの背景色が白くなりそのコマンドボタンが押された旨のメッセージが表示されます。

5.最後に
ここで紹介した方法はマウスのみを対象にしています。キーボードでのクリック操作はまったく考慮していませんので悪しからず。コマンドボタンをキーボードでクリックできないようにするときはコマンドボタンのTabStopプロパティをFalseにしてください。
またMouseDownではなくMouseUpで判断するようにすると、マウスダウンで指定したボタンを外してマウスアップすることでキャンセル扱いにすることができます。
VBAは融通が利かないのでVB.Netでは平気で書いていた構文がコンパイルエラーとなってイライラすることが多くあります。配列にVariantしか使えないところなどはVB.Netのジェネリックに慣れた者からするとちょっと気持ちが悪いところです。VBAはもうこれ以上発展の余地はないのでしょうか?
最後まで御覧いただきありがとうございました。