Excel VBA | 超初心者(Excel操作+マクロ体験):VBA基礎環境 – Public / Private

Excel VBA VBA
スポンサーリンク

Public / Private は「どこから見えるか」を決めるラベル

Public と Private は、
「この変数(や Sub / Function)を、どこから見えるようにするか」
を決めるための“ラベル”です。

同じ変数宣言でも、Public を付けるか Private を付けるかで、
「プロジェクト全体から見えるグローバルな存在」にもなるし、
「このモジュールの中だけでひっそり使うローカルな存在」にもなります。

超ざっくり言うと、

Public = 外からも見えるように“公開”する
Private = 外からは見えないように“隠す”

というイメージで捉えると、かなり分かりやすくなります。

変数に付ける Public / Private

モジュールの先頭に書く変数宣言とスコープ

Public / Private を変数に付けるのは、基本的に「モジュールの先頭(プロシージャの外)」です。

Option Explicit

Public UserName As String
Private TotalCount As Long

Sub Sample()

    ' ここから下で UserName と TotalCount を使える

End Sub
VB

ここで重要なのは、
「Public / Private を付ける場所は“モジュールレベル”」
ということです。
Sub の中で Dim する変数には、Public や Private は付けません(付けられません)。

Public 変数のイメージと例

Public を付けた変数は、「プロジェクト全体(このブックのすべてのモジュール)から見える変数」になります。

標準モジュール Module1 に、こう書いたとします。

Option Explicit

Public UserName As String

Sub SetUserName()

    UserName = "山田"
    MsgBox "ユーザー名を設定しました"

End Sub
VB

別の標準モジュール Module2 から、こう書けます。

Option Explicit

Sub ShowUserName()

    MsgBox "現在のユーザーは " & UserName & " さんです"

End Sub
VB

UserName は Module1 で宣言されていますが、Module2 からも普通に見えます。
これが Public 変数の「広いスコープ」です。

ただし、何でもかんでも Public にすると、
「どこからでも書き換えられる“野ざらしの共有変数”」だらけになり、
バグの原因になりやすくなります。

本当に「全体で共有したい情報」だけを Public にする、という意識がとても大事です。

Private 変数のイメージと例

Private を付けた変数は、「そのモジュールの中だけで使える変数」です。
他のモジュールからは見えません。

Module1 にこう書いたとします。

Option Explicit

Private TotalCount As Long

Sub AddCount()

    TotalCount = TotalCount + 1

End Sub

Sub ShowCount()

    MsgBox "合計回数: " & TotalCount

End Sub
VB

Module1 の中の Sub からは、どちらも TotalCount を共有できます。
しかし、Module2 から

Sub Test()

    MsgBox TotalCount   ' コンパイルエラー:定義されていません

End Sub
VB

と書くと、「そんな変数知らない」と怒られます。

ここでのポイントは、
「この変数は、このモジュールの中だけで完結させたい」
という意図を Private がはっきり表してくれることです。

Dim をモジュール先頭に書いた場合も、既定では「そのモジュール内だけ」のスコープですが、
Private を付けると、「あえて外から隠している」ことが読み手に伝わります。

Sub / Function に付ける Public / Private

Public Sub と Private Sub の違い

Public / Private は、変数だけでなく Sub や Function にも付けられます。

Option Explicit

Public Sub PublicProc()

    MsgBox "どのモジュールからでも呼べる Sub です"

End Sub

Private Sub PrivateProc()

    MsgBox "このモジュールの中からしか呼べない Sub です"

End Sub
VB

PublicProc は、別のモジュールからも呼び出せます。

Sub CallPublic()

    PublicProc   ' OK

End Sub
VB

一方、PrivateProc は同じモジュールの中からしか呼べません。
別モジュールから呼ぼうとすると、「定義されていません」というコンパイルエラーになります。

ここでもキーワードは「公開するか、隠すか」です。
外から呼んでほしい“窓口”の Sub は Public、
内部でだけ使う“裏方”の Sub は Private、
という分け方を意識すると、構造がとても分かりやすくなります。

Function に対する Public / Private

Function も同じです。

Option Explicit

Public Function Add(a As Long, b As Long) As Long

    Add = a + b

End Function

Private Function InternalCalc(x As Long) As Long

    InternalCalc = x * 2

End Function
VB

Add は Public なので、他のモジュールからも呼べますし、条件を満たせばワークシート関数としてセルからも呼べます。

InternalCalc は Private なので、このモジュールの中のコードからしか呼べません。
「Add の内部でだけ使う補助計算」といった位置づけにできます。

Public Function は「外に見せる API(入口)」、
Private Function は「中でだけ使う部品」
というイメージを持つと、設計の整理がしやすくなります。

Public / Private を体感する小さな例題

例題1:Public 変数で「状態を共有する」

Module1:

Option Explicit

Public LoginUser As String

Sub Login()

    LoginUser = "佐藤"
    MsgBox "ログインユーザーを " & LoginUser & " に設定しました"

End Sub
VB

Module2:

Option Explicit

Sub ShowLoginUser()

    If LoginUser = "" Then
        MsgBox "まだログインしていません"
    Else
        MsgBox "現在のユーザーは " & LoginUser & " さんです"
    End If

End Sub
VB

この場合、Login を先に実行してから ShowLoginUser を実行すると、
Module をまたいで LoginUser の値が共有されているのが分かります。

「アプリ全体で共有したい“状態”」を Public 変数に持たせると、こういうことができます。
ただし、どこからでも書き換えられるので、使いすぎは危険、という感覚も同時に持っておくと良いです。

例題2:Private Sub で“裏方処理”を隠す

Module1:

Option Explicit

Public Sub RunMain()

    Initialize
    Process
    Finish

End Sub

Private Sub Initialize()

    MsgBox "初期化中..."

End Sub

Private Sub Process()

    MsgBox "処理中..."

End Sub

Private Sub Finish()

    MsgBox "終了処理中..."

End Sub
VB

ここでは、RunMain だけを Public にして、Initialize / Process / Finish は Private にしています。

外のモジュールからは RunMain しか呼べません。
内部の細かい手順(Initialize など)は隠されていて、外からは意識しなくていい設計になっています。

「外に見せたいのはどこか」「中だけで完結させたいのはどこか」
これを意識して Public / Private を付けると、コードが“モジュール化”されていきます。

超初心者向けの実践ルール

最後に、「今の段階でこれだけ意識しておけば十分」というルールをまとめます。

変数について
まずは基本、「変数は Sub / Function の中で Dim して、その中だけで使う」。
どうしてもモジュール内で共有したいときだけ、モジュール先頭に Private で宣言する。
Public 変数は、「本当に全体で共有したい情報」に限る(乱用しない)。

プロシージャについて
外から呼んでほしい“入口”の Sub / Function だけ Public にする。
内部でしか使わない補助的な Sub / Function は Private にする。

Public / Private は、難しい文法というより、
「どこまで見せるか」「どこで閉じるか」を決める“設計の道具”です。

タイトルとURLをコピーしました