神Excelの雑記

闇Excelでバックオフィスの人です。メモ帳的な。

Captionのプロシージャを呼び出す汎用ボタン

今回は、「ワークシートのデータベース的利用①設定シート編」で書いた「フォームボタンにSetHackを仕込んで、Captionに実行したいプロシージャ名を記載しておき、SetHack後にプロシージャを呼び出す」 とはなんぞや、という話。

god-of-excel.hateblo.jp

事例

ツールの実行時には最初に、以下のような処理をまとめたプロシージャを、必ず実行することが多いだろう。今回はツールの実行時に必ず実行するプロシージャを「Gen」と名付けよう。

  • シートの描画を止める
  • 定数を宣言する

そして、単純なツール例では、普段は「P0_All」を押下するが、たまに個別に実行したいとき、図のようにボタンを分けることは一般的と思う。

フォームボタンの設置例
フォームボタンの設置例

その時、以下のように毎回「Gen」プロシージャを書くのかという問題。なんかダサくないすか?

Sub P0_All()
    Call P1_Import
    Call P2_Update
    Call P3_Export
End Sub
Sub P1_Import()
    Call Gen
    Call Import_1
End Sub
Sub  P2_Update()
    Call Gen
    Call Update_1
End Sub
Sub P3_Export()
    Call Gen
    Call Export_1
End Sub

今回はこの課題を、「Caption名を変数として取り込む関数」を作って、ボタンに割り当てることで解決する。

先に言っておくが、必ず最初に特定のプロシージャを実行したいという目的に対し、この手法がいつも適切というわけでもない。
実を言うと、このボタンの元ネタは上記の事例ではなく、いつだったか担当した既存のシステム仕様に合わせて作ったものだ。画面遷移するときに、別に持っている式や値に対し、押下したボタンで処理が分岐するプログラムだったが、細かいところはちょっと覚えていない。
言いたいのは、手数を増やしておくと、どこかしらで役に立つということだ。

フォームコントロールのボタンを使う

今回使うのはActivXコントロールのコマンドボタンではない方。フォームボタンは細かいコントロールはできないが、ボタン自体をどうこうしたいわけじゃないなら、単純で使い出が良い。

【共通関数】キャプション取得関数の作成

まずは、ボタン名とキャプションを取得する関数を作る。

Function CapFBtn()
    'ボタン名取得
    NmFBtn = Application.Caller
    'キャプション取得
    With ActiveSheet
        CapFBtn = .DrawingObjects(NmFBtn).Characters.Text
    End With
End Function

【共通プロシージャ】汎用フォームボタンの作成

そして、4つのボタンすべてに、以下のGenプロシージャを割り当てる。

'共通処理
Sub Gen()
    Application.ScreenUpdating = False
    'ボタンのキャプション取得
    TgtProc = CapFBtn
    'キャプション名のプロシージャ実行
    Application.Run TgtProc
    Application.ScreenUpdating = True
End Sub

もうお分かりだろう。
あとは、ボタンのキャプション名と同じ名前のプロシージャを記述するだけだ。

'全部
Sub P0_All()
    Call P1_Import
    Call P2_Update
    Call P3_Export
End Sub

'P1の処理を書く
Sub P1_Import()    
End Sub
'P2の処理を書く
Sub P2_Update()    
End Sub
'P3の処理を書く
Sub P3_Export()    
End Sub

画面描画のオンオフなど、はじめと終わりが必要な処理が、煩雑なフラグ管理なしに1回で済むのは何気に便利だ。

VBAの強みは「初心者でもなんとなく分かる」「なんとなく動く」ことだと思っているので、見た目通りに、ユーザの期待通りに、直感的に動く書き方を突き詰めていきたい。