マクロがどこから実行されたかを調べる方法を解説します。
Application.Callerプロパティを使用します。
サンプルコード
Sub サンプルマクロ() Dim ボタン名 ボタン名 = Application.Caller If TypeName(ボタン名) = "String" Then MsgBox "実行されたボタン名:" & ボタン名 End If End Sub
このマクロを以下のボタン・図形にセットして実行すると、
「ボタン1」「ボタン2」「四角形1」を取得します。

解説
Application.Callerプロパティを取得すると、
そのマクロがどこから呼ばれているかを調べることが出来ます。
「押されたボタン名」を取得するのが主な用途で、
同じマクロを押されたボタンによって分岐させるなどに使用します。
ボタンから実行された場合はApplication.Callerは文字列を返しますので、
TypeNameがStringか調べることで、実行元がボタンかどうかを判定できます。
上記のサンプルの通り、Formコントロールのボタン以外に、
図形(シェイプ)にマクロを登録して実行しても図形名を取得できます。
ただし図形(シェイプ)は「同名の図形を許す」仕様になっていますので、
完全な特定は不可能である点に注意してください。
ボタンや図形以外からマクロを実行した場合
ボタンや図形以外から実行されたマクロについて、
Application.Callerプロパティで取得できる値は以下の通りです。
ユーザー定義関数
Functionで作成したマクロをユーザー定義関数としてセルで使用した場合は、
Application.Callerは使用されたセルをRangeオブジェクトで返します。
例えばROW関数のように「自身のセルアドレス」を結果に使用したい場合は、
Application.Callerプロパティを使って以下のようにFunctionを作成します。
Function 再現ROW関数(Optional 参照 As Range) As Long ' 省略時は関数が入力されたセルの行番号を返す If 参照 Is Nothing Then Set 参照 = Application.Caller End If 再現ROW関数 = 参照.Row End Function
ちなみにスピル環境下ではもうほとんど用途がなくなった機能ですが、
配列関数(CSE関数)において、Application.Callerはそのセル範囲を返します。
マクロの一覧から実行
マクロの一覧から直接マクロを実行した場合は、
Application.Callerは「#REF」エラーを返します。
Application.Callerは#REF以外のエラーを返しませんので、
この判定はIsError関数を用いるだけでOKです。
あるいはTypeNameが「Error」かどうかでも判定ができますので、
ここまでの判定をひとつにまとめて以下のように書くことも可能です。
Select Case TypeName(Application.Caller) Case "String" ' ここにマクロがボタンから実行された場合の処理 Case "Range" ' ここにマクロがユーザー定義関数から実行された場合の処理 Case "Error" ' ここにマクロがマクロ一覧やイミディエイトウィンドウから実行された場合の処理 End Select
一応注意点ですが、
Dim マクロ実行元 As Variant マクロ実行元 = Application.Caller Select Case TypeName(マクロ実行元)
このように書くことはできませんのでご注意ください。
Application.Callerの結果がRangeだった場合は当然代入にSetが必要であり、
Set マクロ実行元 = Application.Caller
こう書かないとApplication.Caller.Valueが変数に代入されてしまいます。
しかしこう書いたら書いたで、これでは当然Stringの場合に動きません。
TypeNameの分岐前にVariant変数を使うことはできませんので、
なんとなく冗長な気はしますが、↓のように書くしかないことを覚えておいて下さい。
Select Case TypeName(Application.Caller) Case "String" マクロ実行ボタン名 = Application.Caller Case "Range" Set マクロ呼出セル = Application.Caller
Callによる呼び出し
マクロを他のマクロからCallした場合は、
Application.Callerは呼び出し元のマクロの実行元を返してくれます。
より正確に言うと、Application.CallerはVBA自体の呼出元を取得します。
つまりボタンから実行されたマクロがその後どのようにSub/Functionを呼ぼうとも、
そのすべてのSub/FunctionでCallerは大元の実行ボタン名を取得してくれます。
古いイベントプロシージャ系列
こちらはほとんど使用用途がないのですが、
マイクロソフト公式ドキュメントに書いてあるため触れておきます。
ブックを開閉するAuto_Open/Auto_Closeプロシージャにおいて、
Application.Callerは実行したブック名を取得します。
また、Application.OnDoubleClickでダブルクリックにマクロを登録した場合は、
Application.Callerは実行したセルを取得します。
このように古いイベント用のプロシージャを用いた場合は、
Application.Callerはそのプロシージャの呼出元を取得できます。
といってもこれを活用する必要は全くなく、
前者はThisworkbook.Nameで簡単に取得できますし、
後者はBeforeDoubleClickイベントの引数Targetから簡単に取得できます。
「イベントプロシージャがない昔のイベント処理では、
実行元の取得にApplication.Callerを使用していた」
という話であり、現在この仕様を活用する必要は全くありません。
覚えておく必要もないと思いますが、何かあったときのために記しておきますね。