標準モジュールに、次のようなマクロを作ったとします。
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によって異なる「見える範囲」のことをスコープと呼びます。