【VBA】グローバル変数とローカル変数の注意点|スコープ設計と実務的な使い分け

VBA では、変数の宣言位置によって “どこから使えるか(スコープ)” が変わります。
特に グローバル変数(Public) と ローカル変数(Dim) の使い方を誤ると、予期しない値の上書きやバグにつながりやすく注意が必要です。

この記事では、グローバル変数とローカル変数の違い、使うべき場面、そして実務的な注意点まで詳しく解説します。


スポンサーリンク

1. グローバル変数とは(Public で宣言)

グローバル変数とは、どのモジュールからでもアクセスできる変数のことです。
標準モジュールの先頭で Public 付きで宣言します。

'標準モジュールの先頭
Public UserName As String
Public TotalCount As Long

どのプロシージャからでも読み書き可能:

Sub SetValue()
    UserName = "Yamada"
End Sub

Sub ShowValue()
    MsgBox UserName
End Sub

● グローバル変数のメリット

  • 複数の処理で共通利用できる
  • 引数で受け渡ししなくてよい

● グローバル変数のデメリット(ここが最大の注意点)

  • どこからでも書き換え可能 → 値の変化が追いづらい
  • 名前の競合(同名変数)によるバグの原因
  • 外部から意図せず参照されるリスク
  • ファイルをまたぐと特に動作が読みにくい

実務では、グローバル変数の乱用は強く非推奨です。


スポンサーリンク

2. ローカル変数とは(Dim や Private で宣言)

ローカル変数とは、プロシージャの中だけで有効な変数です。

Sub Sample()
    Dim message As String
    message = "これはローカル変数です"
    MsgBox message
End Sub

他のプロシージャからはアクセスできません。

● ローカル変数のメリット

  • 予期せぬ書き換えを防止できる
  • スコープが限定されるため安全
  • コードの読みやすさが向上する
  • デバッグが容易

● デメリット

  • 他プロシージャへ値を渡す場合は引数が必要
    → しかし、これをメリットと捉えるべき(依存関係を明確にするため)

実務では ローカル変数が基本、グローバル変数は例外的に使用する が原則です。


スポンサーリンク

3. Static 変数との違い

VBAには「ローカルだけど値を保持する」Static 変数があります。

Sub Counter()
    Static cnt As Long
    cnt = cnt + 1
    MsgBox cnt
End Sub

プロシージャを呼ぶたびに cnt の値が増えていきます。

● Static の利用シーン

  • 繰り返し処理の回数カウント
  • 状態をローカルに保ちたいとき
  • グローバル変数を使うほどではない軽い状態保持

Static はグローバル変数の代わりとして有効ですが、使いすぎると挙動が複雑になるため適度に使用します。


スポンサーリンク

4. 実務で気をつけたいグローバル変数の落とし穴

●(1)名前の衝突による意図しない上書き

別モジュールに同名の変数があると意図しない値を参照することがあります。

対策:グローバル変数は接頭辞(g_)を付けるなど命名規則を統一

Public g_UserName As String

●(2)大規模化すると“どこで値が変わったか”追えなくなる

プロジェクトが大きくなるほどグローバル変数はバグの原因になります。

対策:値を変更する処理を専用の Public Sub にまとめる

Public g_Flag As Boolean

Public Sub SetFlag(value As Boolean)
    g_Flag = value
End Sub

●(3)イベントや他の処理が想定外に書き換える

Worksheet_Change などのイベントで変数が変わると、動作が読めなくなります。

対策:本当に必要な値のみグローバルにする


●(4)複数ファイルで同じグローバル名を使うと混乱する

特にアドイン(xlam)を併用している場合に起こりやすい。

対策:
モジュール名+変数名を prefix にするなど、絶対に衝突しない名前にする。


スポンサーリンク

5. 正しい変数管理の設計指針(結論)

安全・保守性の観点から次の原則を推奨します。


✔ 原則1:変数は“必要な範囲の最小スコープ”で持つ

  • プロシージャ内で完結 → ローカル(Dim)
  • モジュール内で共通 → Private
  • 全体で共通 → Public(最終手段)

✔ 原則2:グローバル変数は極力使わない

グローバルは便利ですが、バグの原因になりがちです。


✔ 原則3:どうしてもグローバルが必要なら名前に規則を

g_ / glb_ / Global_ など
プロジェクト全体で規則を統一するとトラブルが激減します。


✔ 原則4:値の受け渡しは“引数”を基本とする

プロシージャの独立性が上がり、保守しやすくなります。


スポンサーリンク

6. まとめ

項目グローバル変数ローカル変数
使える範囲全モジュールプロシージャ内のみ
メリット簡単に共有できる安全・追跡しやすい
デメリット上書きリスク大、バグの温床引数が必要
推奨度低(例外時のみ)高(基本これ)

基本:ローカル変数、例外時だけグローバル。
これが VBA での変数管理の最適解です。

コメント

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