VBAのPublicとPrivateは「そのSubや変数をどこから使えるか(スコープ)」を決めるキーワードです。迷ったら基本はPrivate、複数のモジュールから共有したい処理・変数だけPublicにすると、コードの保守性が上がり意図しない書き換えも防げます。
この記事では、次の内容を順番に解説します。
- PublicとPrivateの違いと使える範囲の比較
- Subプロシージャへの適用例
- 変数への適用例(モジュールレベル変数)
- Dimで宣言した場合との違い
- 実務での使い分けの基準
PublicとPrivateの違いを理解するには?
一言で言うと「使える範囲(スコープ)の違い」です。
| 宣言 | 使える範囲 | マクロ一覧への表示 |
|---|---|---|
Private Sub | 宣言したモジュール内だけ | 表示されない(Alt+F8から実行不可) |
Public Sub または Sub(省略) | プロジェクト全体のどこからでも | 表示される |
Private 変数 | 宣言したモジュール内だけ | — |
Public 変数 | プロジェクト全体のどこからでも | — |
Subプロシージャへの適用を理解するには?
'Privateで定義したSub(このモジュール内からしか呼べない)
Private Sub HelloPrivate()
MsgBox "このモジュール内からしか呼べません"
End Sub
'Publicで定義したSub(他のモジュールからも呼べる)
Public Sub HelloPublic()
MsgBox "どこからでも呼べます"
End Sub
'別のモジュールから呼び出す例
Sub CallFromOtherModule()
Call HelloPublic '← OK:Publicなので呼べる
' Call HelloPrivate '← エラー:Privateなので呼べない
End Sub
Subの省略時(宣言なし)はPublicと同じ扱いになります。イベントマクロ(Worksheet_ChangeなどのPrivate Sub)は、Privateにすることでシートモジュール外から誤って呼び出されることを防いでいます。
変数へのPublic・Privateの適用を理解するには?
モジュールの先頭(Subの外)で変数を宣言するとモジュールレベル変数になります。PublicまたはPrivateを付けることでスコープを制御できます。
'ModuleAに記述
Public userName As String '全モジュールから参照・変更できる
Private counter As Long 'ModuleA内だけで使える
Sub SetUserName()
userName = "山田" 'Publicなので使える
counter = 0 'Privateだがこのモジュール内なので使える
End Sub
'ModuleBに記述
Sub ShowUser()
MsgBox userName '← OK:Publicなので参照できる
' MsgBox counter '← エラー:Privateなので参照できない
End Sub
Dimとの違いを理解するには?
Dimで宣言した変数のスコープは「宣言した場所」によって変わります。
| 宣言方法 | 宣言場所 | スコープ |
|---|---|---|
Dim x As Long | Sub内 | そのSubの中だけ(ローカル変数) |
Dim x As Long | モジュール先頭(Sub外) | そのモジュール内(Privateと同じ) |
Private x As Long | モジュール先頭 | そのモジュール内 |
Public x As Long | モジュール先頭 | プロジェクト全体 |
モジュール先頭でのDimはPrivateと同じ動作ですが、「意図的にPrivateにしている」と明示するためにPrivateを使う方が意図が伝わりやすくなります。
実務での使い分けを知るには?
基本的な使い分けの判断基準です。
| 場面 | おすすめ | 理由 |
|---|---|---|
| そのモジュール内だけで使う処理・変数 | Private | 意図しない場所から呼ばれる・変更されるリスクが減る |
| 複数のモジュールから共通で呼ぶ処理 | Public | どこからでも呼び出せる |
| 複数のSubで共有する変数(状態管理など) | Public(慎重に) | どこからでも参照・変更できる。乱用はバグの元 |
| イベントマクロ(Worksheet_Changeなど) | Private | 他から呼び出されることを防ぐ |
まとめ
- Publicはプロジェクト全体から、Privateは宣言したモジュール内だけで使える
- SubもFunctionも変数も、それぞれにPublic・Privateが適用できる
- Subを宣言なしで書くとPublicと同じ扱いになり、マクロ一覧(Alt+F8)にも表示される
- 迷ったらPrivateが基本。Public変数の乱用は意図しない書き換えやバグの原因になる
- イベントマクロ(Worksheet_Changeなど)は必ずPrivateで書き、他から呼ばれないようにする
よくある質問
Subに何も付けない場合(Sub HelloWorld())はPublicですか?
はい、Subの宣言を省略した場合はPublicと同じ扱いになります。マクロ一覧(Alt+F8)にも表示され、他のモジュールからも呼び出せます。明示的にPublic Subと書いても動作は変わりません。
PrivateにしたらボタンからマクロをAlt+F8で実行できなくなりました。どうすれば?
Privateにすると、マクロ一覧(Alt+F8)には表示されなくなります。これはPrivateの正常な動作です。ボタンやショートカットから実行したいSubはPublicにしてください。逆に「一覧に表示したくない・直接実行させたくない」内部処理はPrivateにすると整理しやすくなります。
別のモジュールからSubを呼び出そうとしたらエラーになりました。なぜ?
呼び出し先のSubがPrivateになっている可能性があります。Privateは宣言したモジュール内からしか呼べないため、他のモジュールからの呼び出しはエラーになります。他のモジュールからも使いたい場合はPublic Subに変更してください。
結局、PublicとPrivateどちらを使えばいいですか?
迷ったらPrivateを選んでください。最初からPublicにすると、どこからでも呼び出せる・変更できる状態になり、コードが複雑になってきたときに原因を追いにくくなります。「他のモジュールから使う必要が出てきた」タイミングでPublicに変えるのが、初心者のうちは安全な進め方です。
Privateにしたモジュールレベル変数の値は、マクロが終わっても残りますか?
はい、残ります。モジュールレベル変数(SubやFunctionの外で宣言した変数)は、PublicでもPrivateでも、Excelのブックを閉じるまで値を保持し続けます。Subの中でDimで宣言したローカル変数は、そのSubが終わると値がリセットされますが、モジュールレベルの変数はマクロの実行が終わっても値が消えません。意図せず前回の値が残っていてバグになることがあるので、必要に応じてSub開始時に値を初期化するようにしましょう。
動画で学びたい方へ
「記事を読んでも、実際に自分で書けるか不安…」という方には、動画で基礎からじっくり学べる講座がおすすめです。
VBAが初めての方を前提に、つまずきやすいポイントを先回りして解説しています。サンプル動画は無料でご覧いただけます。



