t-hom’s diary

主にVBAネタを扱っているブログです。

VBA ボタンから呼び出すマクロに共通の前処理をつける方法

前回の記事で、リボンから呼び出すマクロに共通の前処理をつける方法を紹介した。

同じことは、ワークシートに配置したボタンでもできる。
今回は、以前に紹介したマクロでボタンを作る方法を使ってやってみたいと思う。

コードは以下の通りで、標準モジュールに作成する。

Sub AddButtons()
    Const WSize As Integer = 80
    Const HSize As Integer = 20

    'スペース区切りで配列に。
    Dim Macros() As String
    Macros = Split("Macro1 Macro2", " ")
    
    For i = 0 To UBound(Macros)
        Call CreateButton(Macros(i), i * WSize, 0, WSize, HSize)
    Next
End Sub

Private Sub CreateButton(ButtonName, x, y, w, h)
    With ActiveSheet.Buttons.Add(x, y, w, h)
        .Name = ButtonName 'オブジェクト名と
        .Caption = ButtonName 'ボタンのテキストは面倒なので全部同じにしてしまう。
        .OnAction = "Start"
    End With
End Sub

Sub Start()
    '共通処理
    MsgBox "共通処理サンプル!"
    '個別処理呼び出し
    Application.Run Application.Caller
End Sub

Sub Macro1()
    MsgBox "個別処理:test1"
End Sub

Sub Macro2()
    MsgBox "個別処理:test2"
End Sub

以前の記事ではそれぞれのマクロを直接ボタンに登録していたが、今回はCreateButtonプロシージャ内でボタンのOnActionをStartマクロに固定している。
また、Nameに設定したボタン名は、個別のマクロ名と一致させておく。

まず、任意のシート上でAddButtonsを実行すると、ボタンが2つ作成される。
※新規のワークシートをActiveにした状態で試してください。

ボタンを押すとStartが呼び出され、共通処理が終わったあとでApplication.Runにより呼び出し元のボタン名と同じ名前のマクロが実行される。

Application.Callerについては、下記サイトの説明を参照すると良い。
Excel VBA を学ぶなら moug モーグ | 即効テクニック | VBA入門者の”どっち?”・・・フォームツールバー or コントロールツールボックス(2)


そういえば以前VBAアスペクト指向ができないという話を書いたが、今回のような共通処理はアスペクト指向における「横断的関心事」と似ている。

通常のプロシージャからプロシージャを呼ぶケースではApplication.Callerは使えないが、ワークシート上のボタンとリボンに関しては、いちおう「横断的関心事」をうまく処理できたと言えるかもしれない。

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