t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

VBA Publicなプロシージャをマクロの実行メニューから隠す方法

ユーザーに実行させたくないマクロを「マクロの実行」メニューから隠す方法として最も簡便なのはプロシージャを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」を記述するとそのモジュールのマクロは見えなくなるとのこと。
実際やってみると、マクロメニューからは隠れ、他モジュールからの呼び出しは成功した。素晴らしい!

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