Excel VBAでコードを書いていると、
次のような状況に必ず一度は遭遇します。
Publicと書いたはずの変数が参照できない- 別のプロシージャやモジュールから見えない
- 「変数が定義されていません」「ユーザー定義型が定義されていません」が出る
- 昨日まで動いていたのに急にエラーになる
特に混乱を招くのが、
Public なのに参照できない
という現象です。
「Public と書いているのだから、
どこからでも使えるはずでは?」
と考えてしまい、
原因が分からずコードをいじり続けてしまうケースは非常に多いです。
しかし、この問題の本質はシンプルで、
Public変数が参照できないのは、
ほぼ例外なく「書く場所」が間違っている
これに尽きます。
この記事では、
Excel VBAにおける Public変数が参照できない原因 を、
- VBAのスコープ(有効範囲)の基本
- モジュールの種類ごとの違い
- 「書いてはいけない場所」「書くべき場所」
- よくある勘違いと失敗例
- 実務で再発させない設計指針
という流れで、体系的・実務目線 で徹底解説します。
目次
- ✅ Public変数が参照できない現象とは
- ・よくある症状
- ・Public変数の問題は「文法」ではない
- ✅ VBAにおける「スコープ(有効範囲)」の基本
- ・VBAの変数スコープは3段階
- ・Dim / Private / Public の意味
- ✅ Public変数を書いてはいけない場所
- ・Sub や Function の中に書いている
- ・なぜ参照できないのか
- ・正しい書き方(NG → OK)
- ✅ モジュールの種類による決定的な違い
- ・Excel VBAの主なモジュール種類
- ✅ 標準モジュールに書いたPublic変数
- ・標準モジュールとは
- ・正しい例
- ・なぜ標準モジュールが最適なのか
- ✅ シートモジュールに書いたPublic変数の落とし穴
- ・シートモジュールとは
- ・一見正しく見えるが…
- ・何が問題か
- ・実務での問題点
- ✅ ThisWorkbookに書いたPublic変数の注意点
- ・ThisWorkbookのPublic変数
- ・参照方法
- ・使いどころは限定的
- ✅ クラスモジュールに書いたPublic変数
- ・クラスのPublicは「インスタンスの公開メンバー」
- ・使うにはインスタンスが必要
- ✅ Public変数が参照できない代表的な勘違い
- ・Publicなら自動で共有される
- ・どのモジュールでも同じ
- ・エラーはVBAの不具合
- ✅ 実務で安全なPublic変数の書き方(設計指針)
- ・基本ルール
- ・おすすめ構成例
- ✅ Public変数を使いすぎないための考え方
- ・Publicは便利だが危険
- ・代替案
- ✅ RPA(UiPath)連携時の注意点
- ✅ よくある質問(実務編)
- ・Public変数が突然 Nothing / 0 になる
- ・ブックを閉じたら消える?
- ✅ まとめ:Public変数が参照できない本当の理由
✅ Public変数が参照できない現象とは
※まず「何が起きているのか」を整理します。
・よくある症状
次のようなコードを書いた経験はないでしょうか。
Public gCount As Long
そして別のプロシージャで、
MsgBox gCount
ところが実行すると、
- 変数が定義されていません
- オブジェクトが必要です
- 参照できない
といったエラーが出る。
Public と書いているのに使えない
これが混乱の出発点です。
・Public変数の問題は「文法」ではない
重要なのは、
この問題の多くは
- スペルミス
- 型の問題
ではありません。
VBAのルール上「見えない場所」に書いている
これが根本原因です。
✅ VBAにおける「スコープ(有効範囲)」の基本
※ここを理解しないと、Public変数は扱えません。
・VBAの変数スコープは3段階
Excel VBAでは、変数の有効範囲(スコープ)は大きく3つに分かれます。
- プロシージャレベル
- モジュールレベル
- グローバル(プロジェクト)レベル
Public変数が関係するのは、
②と③ です。
・Dim / Private / Public の意味
簡単に整理すると、次の通りです。
Dim:書いた場所のスコープに依存Private:そのモジュール内のみPublic:正しく書けば、プロジェクト全体
ただし、
Publicは「どこに書くか」で意味が変わる
という点が最大の落とし穴です。
✅ Public変数を書いてはいけない場所
※ここが一番重要です。
・Sub や Function の中に書いている
最も多いミスがこれです。
Sub Sample()
Public gCount As Long
End Sub
このコードは、
文法的には書けてしまう ため、
初心者ほど混乱します。
しかし、この Public gCount は、
- グローバル変数にはならない
- Sub の中のローカル変数扱い
になり、
他のプロシージャから参照できません。
・なぜ参照できないのか
VBAでは、
- Sub / Function の中
= プロシージャスコープ
と決まっています。
その中に書いた Public は、
「Public風に見えるだけ」 で、
実際には外に公開されません。
・正しい書き方(NG → OK)
❌ NG例
Sub Sample()
Public gCount As Long
End Sub
⭕ OK例
Public gCount As Long
Sub Sample()
gCount = 10
End Sub
Sub の外に書く
これが鉄則です。
✅ モジュールの種類による決定的な違い
※ここを理解していないと、正しく書いても参照できません。
・Excel VBAの主なモジュール種類
Excel VBAには、次のようなモジュールがあります。
- 標準モジュール
- シートモジュール
- ThisWorkbook モジュール
- クラスモジュール
Public変数は、
どのモジュールに書くか によって、
見え方が変わります。
✅ 標準モジュールに書いたPublic変数
※最も安全で、最も推奨される方法です。
・標準モジュールとは
- 挿入 → 標準モジュール
で作成されるモジュールです。
実務で使う Public変数の9割以上はここに書くべき です。
・正しい例
' 標準モジュール
Public gUserName As String
Public gTotalCount As Long
このように書くと、
- すべての標準モジュール
- すべてのシートモジュール
- ThisWorkbook
から参照できます。
・なぜ標準モジュールが最適なのか
- スコープが明確
- 依存関係が少ない
- 意図が分かりやすい
Public変数の「置き場所」として最も安定
それが標準モジュールです。
✅ シートモジュールに書いたPublic変数の落とし穴
※ここが次に多い失敗パターンです。
・シートモジュールとは
- Sheet1
- Sheet2
など、
Excelの各シートに紐づいたモジュールです。
・一見正しく見えるが…
' Sheet1 モジュール
Public gCount As Long
この変数は、
- Sheet1 の インスタンスに属するメンバー
として扱われます。
・何が問題か
他のモジュールからは、
gCount
では参照できません。
正しくは、
Sheet1.gCount
と書く必要があります。
・実務での問題点
- 呼び出しが冗長になる
- シート名変更の影響を受ける
- グローバル変数として直感的でない
そのため、
グローバル用途のPublic変数を
シートモジュールに書くのは非推奨 です。
✅ ThisWorkbookに書いたPublic変数の注意点
※シートモジュールと似ていますが、別物です。
・ThisWorkbookのPublic変数
' ThisWorkbook
Public gPath As String
これも、
ThisWorkbook オブジェクトのメンバー
として扱われます。
・参照方法
ThisWorkbook.gPath
と書かないと参照できません。
・使いどころは限定的
- ブック固有の情報
- 外部から触らせたくない状態
など、
意図的にスコープを限定したい場合 には使えます。
ただし、
「どこからでも使う変数」には向きません。
✅ クラスモジュールに書いたPublic変数
※Publicの意味が完全に変わります。
・クラスのPublicは「インスタンスの公開メンバー」
' Class Module
Public Count As Long
これは、
- グローバル変数ではない
- クラスのプロパティ
です。
・使うにはインスタンスが必要
Dim obj As New MyClass
obj.Count = 10
Public=どこからでも使える
ではない典型例です。
参考:【VBA】クラスモジュールの使用方法をわかりやすく変数の呼び出す
✅ Public変数が参照できない代表的な勘違い
※ほぼ全員が一度はやります。
・Publicなら自動で共有される
→ ❌ 書く場所が重要です。
・どのモジュールでも同じ
→ ❌ モジュールの種類で意味が変わります。
・エラーはVBAの不具合
→ ❌ 仕様通りの挙動です。
✅ 実務で安全なPublic変数の書き方(設計指針)
※「使える」より「壊れない」が重要です。
・基本ルール
- 標準モジュールに書く
- Sub / Function の外に書く
- 本当に必要なものだけ Public にする
・おすすめ構成例
' modGlobal
Public gUserId As String
Public gIsAdmin As Boolean
Public gProcessCount As Long
グローバル変数専用モジュール を作ると、
意図が明確になり、保守性が大きく向上します。
✅ Public変数を使いすぎないための考え方
※実務ではここが評価ポイントです。
・Publicは便利だが危険
- どこからでも変更できる
- 追跡が難しい
- バグの温床になりやすい
・代替案
- 引数で渡す
- 戻り値で返す
- プロパティ化する
「とりあえずPublic」から卒業する
これが中級者への分岐点です。
✅ RPA(UiPath)連携時の注意点
※Public変数問題が顕在化しやすい環境です。
- 実行順が一定でない
- 初期化されていない
- 想定外のタイミングで参照される
そのため、
- 初期化処理を明示
- Public変数の数を絞る
- 標準モジュールに集約
という設計が必須になります。
✅ よくある質問(実務編)
・Public変数が突然 Nothing / 0 になる
→ マクロ停止・エラーでリセットされています。
Publicでも 状態は保持されません。
参考:【VBA】Nothingとは?オブジェクト変数の初期化と解放をわかりやすく解説
・ブックを閉じたら消える?
→ 消えます。
Public変数は メモリ上の一時情報 です。
✅ まとめ:Public変数が参照できない本当の理由
- Public変数は「どこに書くか」で意味が変わる
- Sub / Function 内に書くのはNG
- 標準モジュールが最も安全
- シート / ThisWorkbook / クラスでは参照方法が変わる
- Publicは最小限に抑えるのが実務的
Excel VBAのPublic変数問題は、
スコープと配置を正しく理解した瞬間に一気に解決します。
「なぜ参照できないのか」で悩む時間を減らし、
意図通りに動くVBA設計 を、ぜひ身につけてください。