ユーザーに実行させたくないマクロを「マクロの実行」メニューから隠す方法として最も簡便なのはプロシージャをPrivateにしてしまうことだ。
しかしマクロがある程度大きくなると、複数のモジュールにプロシージャを分散させたい場合がある。
他モジュールから呼び出すためには、Publicにする必要があるが、単にPublicにするとマクロの実行メニューにも見えてしまう。
今回はこのジレンマを解消する方法を紹介する。
まず、引数があるプロシージャはたとえPublicでもマクロの実行メニューに表示されない。
引数を使わない場合はどうすれば良いかというと、Optionalで適当なダミー引数を設定してしまえば良い。
標準モジュールを作って以下のコードを挿入する。
Public Sub HiddenProcedure(Optional void = Empty) MsgBox "このプロシージャはマクロの実行メニューには表示とされません。" End Sub Public Sub Main() Call HiddenProcedure End Sub
HiddenProcedureプロシージャは引数があるので単体では実行できなくなるが、Mainからだと普通に呼び出せる。
また、Publicなので他プロシージャからの呼び出しも可能。
以前はdummyという名称の仮引数を作って実際に1とか0とかの実引数を渡していたんだけど、単にOptionalで良いことに気付いたので今回記事にした。
今回のvoidはC言語のキーワードから英単語を拝借した。
Cでは引数をとらない場合にキーワードvoidを指定する。
#include <stdio.h> int main(void){ printf("Hello, World!\n"); return 0; }
初期値は何でも良いので最初は0とか""とかにしていたけれど、VBAのキーワードEmptyが最も意図をよく表していることを発見して置き換えた。
ちなみにSubの代わりにFunctionを用いれば引数をつけなくてもマクロメニューから隠すことはできる。
しかしFunctionの主目的は値を返すことだから、私の場合、値を返さない純粋な手続きの場合はSubで作る。
追記
Twitterでimihitoさんに情報もらったので追記。
モジュールの先頭に「Option Private Module」を記述するとそのモジュールのマクロは見えなくなるとのこと。
実際やってみると、マクロメニューからは隠れ、他モジュールからの呼び出しは成功した。素晴らしい!