[関数の挿入]ダイアログボックスに表示させない


標準モジュールに、次のようなマクロを作ったとします。

Sub Sample()
    If Not シートチェック Then
        With Worksheets.Add
            ActiveSheet.Name = "合計"
        End With
    End If
End Sub

Function シートチェック()
    Dim ws, flag As Boolean
    For Each ws In Worksheets
        If ws.Name = "合計" Then
            flag = True
            Exit For
        End If
    Next ws
    If flag Then
        シートチェック = True
    Else
        シートチェック = False
    End If
End Function

Functionプロシージャ「シートチェック」は、すべてのワークシート中に「合計」という名前のシートが存在するかどうかを返します。Sub Sampleでは、「シートチェック」の結果がFalseだったとき、新しいワークシートを挿入して、シートの名前を「合計」に変更します。

マクロの内容はどうでもいいのですが、このようなFunctionプロシージャには一つ特徴があります。それは、ワークシート上で開く[関数の挿入]ダイアログボックスに表示されてしまうということです。

[関数の挿入]ダイアログボックスでは、関数がジャンルごとに分類されています。このようなFunctionプロシージャがあると、[関数の分類]リストに「ユーザー定義」というジャンルが追加され、選択するとこのようなFunctionプロシージャが[関数名]リストに表示されます。表示されることによる実害はありません。しかし、心配性のビギナーや、研究熱心な自称中級者たちは、あなたのデスクに電話をかけてくるかもしれません。「これ、何?」って。毎回「ああ、何でもありません。気にしないでください」と返答するのが嫌なら、ここから先をじっくり読んでください

先ほどから「このようなFunctionプロシージャ」と書きましたが、いったい「Function シートチェック」はどのようなFunctionプロシージャなのでしょう。ヒントは本トピックの先頭に書いておきました。

Functionプロシージャには「Public Function」と「Private Function」の二種類があります。「Public Function」は"公開された"プロシージャです。プロシージャを記述した標準モジュール内はもちろん、[Sheet1]モジュールや[UserForm1]モジュールからも自由に使うことができます。一方の「Private Function」は"専用の"プロシージャです。そのプロシージャを使う権限は、そのプロシージャを記述したモジュール内に限られます。プロシージャをPublicにするか、それともPrivateにするかは、プロシージャを宣言する先頭に記述します。

Public Function シートチェック()
  :
End Function
または
Private Function シートチェック()
  :
End Function

そして、これが重要なポイントです。標準モジュール内で[Public/Private]の区別を省略した場合はPublicとみなされるのです。トピックの先頭で、このマクロを「標準モジュールに」記述したと明記しています。したがって「Function シートチェック」は自動的にPublicとなり、ユーザー定義関数と同じ扱いになってしまうのです。その証拠に、次のようにワークシート上で使うことができます。

Functionプロシージャを[関数の挿入]ダイアログボックスに表示させたくないときは、手を抜かずPrivateキーワードを使いましょう。なお、[Sheet1]などのシートモジュールではPublicを宣言できませんので、省略すると自動的にPrivateとなります。

プロシージャがPublicかPrivateかという問題は、実は非常に奥が深いです。いや、プロシージャに限りません。変数だって本当はPublicとPrivateを区別して意識するべきです。思いつきで書き始めましたが、この問題は「[関数の挿入]ダイアログボックスに表示されるかどうか」というレベルの話ではなかったですね。他のケースも合わせて、そのうち別のコンテンツとしてまとめてみましょう。ちなみに、PublicとPrivateによって異なる「見える範囲」のことをスコープと呼びます。