Excel VBA を学んでいくと、多くの人がつまずくポイントが 「ローカル変数とグローバル変数の違い」 です。変数はプログラムにとって最も重要な要素のひとつですが、「どこで使えるのか(スコープ)」を正しく理解していないと、思わぬバグを生んだり、処理がうまく動かなかったり、値が初期化されたりとさまざまなトラブルが発生します。
特に Excel VBA の実務現場では、複数の Sub や Function を組み合わせた構造のマクロを使うことが多く、変数スコープの理解は必須です。ローカル変数・グローバル変数を正しく使い分けられるようになると、マクロが安定し、保守性が高まり、エラーも大幅に減らせます。
この記事では、初心者から実務者まで役立つように、例・コード・図解的説明・注意点・応用テクニックを交えながら 変数スコープを完全に理解できる内容 を体系的に整理しました。
目次
- ✅ ローカル変数とは?(Sub/Functionの内部だけで使える変数)
- ・ローカル変数の基本
- ・ローカル変数の特徴
- ・実務でのメリット
- ・ローカル変数の典型例(初心者がよく使うパターン)
- ❗ ローカル変数でも「Static」を付けると動作が変わる
- ✅ グローバル変数(パブリック変数)とは?
- ・グローバル変数の基本
- ・グローバル変数が有効になる範囲(スコープ)
- ・グローバル変数のメリット
- ・グローバル変数のデメリット
- ❗ 実務でグローバル変数を使うと起こる典型的トラブル
- ・トラブル①:思わぬSubで値が書き換わる
- ・トラブル②:同じ名前の変数と干渉
- ・トラブル③:値が初期化されて処理が止まる
- ・トラブル④:Option Explicitと相性が悪い場合がある
- ✅ 実務での正しい使い分け(最重要)
- ✔ 原則:ローカル変数を優先する
- ✔ グローバル変数を使うべき例は非常に少ない
- ✅ ローカル変数・グローバル変数のコード比較
- ・良くない例(グローバル依存)
- ・良い例(ローカル変数と引数で処理)
- ❗ スコープを視覚的に理解する(図解イメージ)
- ✔ 変数スコープを決めるキーワード一覧
- ✓ Private変数も理解すべき(中級者向け)
- ✅ Sub間の値受け渡しは “引数” を使うのが最適
- ❗ グローバル変数を使わざるを得ないケース
- ✔ グローバル変数の命名規則(実務向け)
- ❗ RPA(UiPath/PAD)と連携する場合の注意点
- ✔ ChatGPT でマクロ作成する場合も注意
- 🧪 実務でよくあるスコープミス例と改善版
- ▼誤った例
- ▼改善例
- 🧠 変数スコープを理解するとコードは劇的に改善する
- ✅ まとめ:ローカル変数・グローバル変数は“使う場所”が重要
- ● ローカル変数
- ● グローバル変数(Public)
- ● 使い分けの原則
✅ ローカル変数とは?(Sub/Functionの内部だけで使える変数)
・ローカル変数の基本
ローカル変数とは、宣言したプロシージャ(Sub or Function)の内部でのみ有効な変数 のことです。
Sub Sample()
Dim x As Long ' ローカル変数
x = 10
Debug.Print x
End Sub
この x は 「Sample 内だけ」 で使用できます。他の Sub や Function からは参照できません。
・ローカル変数の特徴
- Sub/Function が終わると自動的に破棄される
- 同じ名前の変数を別の Sub の中で使っても問題にならない
- メモリ使用量が少ない
- 安全性が高い(外部から変更できない)
- 予期せぬ上書きのリスクが少ない
・実務でのメリット
ローカル変数は「その処理の中だけで必要な値」を扱うため、
実務では基本的にローカル変数が最も安全です。
例:カウンタ、セルの値、行番号、列番号、範囲、ループの値 など。
・ローカル変数の典型例(初心者がよく使うパターン)
Sub CountRows()
Dim lastRow As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
Debug.Print lastRow
End Sub
lastRow はこの Sub 内のみで利用されます。
❗ ローカル変数でも「Static」を付けると動作が変わる
Static count As Long
count = count + 1
Debug.Print count
Static 変数は Sub を抜けても値が保持されます。
- 通常のローカル:Sub が終わる → 値が消える
- Static ローカル:Sub が終わっても値が残る
カウンタや状態管理に使われますが、濫用注意。
✅ グローバル変数(パブリック変数)とは?
・グローバル変数の基本
グローバル変数とは:
- モジュールの先頭に
PublicまたはGlobalを付けて宣言- プロジェクト全体、どの Sub/Function からも参照できる
という非常に強力な変数です。
Public total As Long ' グローバル変数
すべてのモジュールから参照できます。
・グローバル変数が有効になる範囲(スコープ)
- Excel ブック(VBAプロジェクト)全体
- 任意のモジュール
- 任意のSub・Function
つまり、どこからでもアクセスできてしまいます。
・グローバル変数のメリット
- 値を複数の Sub で共有できる
- データの受け渡しが不要(引数無しでOK)
- 状態管理が容易(フラグ管理など)
・グローバル変数のデメリット
- 外部から簡単に書き換えられる
- 値の変化がどこで起きたか追いづらい
- マクロ全体が複雑になる
- 名前の競合・予期しない上書きが起きる
- デバッグが困難になる
特に、大規模化するとバグの温床になります。
参考:【VBA】Variant型とは?便利だが危険な理由と使いどころ|実務で失敗しないための徹底ガイド
❗ 実務でグローバル変数を使うと起こる典型的トラブル
・トラブル①:思わぬSubで値が書き換わる
複数の人が書いたVBAでは頻発。
・トラブル②:同じ名前の変数と干渉
例:ローカル変数と同名だと混乱する。
・トラブル③:値が初期化されて処理が止まる
Excel がクラッシュ → 再計算 → 値が空になる。
・トラブル④:Option Explicitと相性が悪い場合がある
誤って同名のローカルを宣言すると意図しない動作。
✅ 実務での正しい使い分け(最重要)
✔ 原則:ローカル変数を優先する
ほとんどの処理はローカルで完結します。
✔ グローバル変数を使うべき例は非常に少ない
- 設定値(環境変数)
- デバッグ中のフラグ
- ユーザーフォーム間での値共有
- あるいは「明確な意図」のあるデータ保持
その他はできる限り 引数と戻り値で処理すべき です。
✅ ローカル変数・グローバル変数のコード比較
・良くない例(グローバル依存)
Public count As Long
Sub A()
count = count + 1
End Sub
Sub B()
count = count + 1
End Sub
どこから変更されたか分からなくなる。
・良い例(ローカル変数と引数で処理)
Sub Main()
Dim count As Long
count = AddOne(count)
count = AddOne(count)
End Sub
Function AddOne(ByVal i As Long) As Long
AddOne = i + 1
End Function
処理構造が明確で安全。
❗ スコープを視覚的に理解する(図解イメージ)
- ローカル変数:箱の中だけ(Subの中)で有効
- グローバル変数:建物全体(プロジェクト全体)で有効
ローカルは閉じた世界、グローバルは開かれた世界です。
✔ 変数スコープを決めるキーワード一覧
| キーワード | スコープ | 説明 |
|---|---|---|
| Dim | プロシージャ内部 | ローカル変数 |
| Static | プロシージャ内部で保持 | 値が保持される特別なローカル |
| Private | モジュール内 | モジュールレベル変数 |
| Public | プロジェクト全体 | グローバル変数 |
| Global | プロジェクト全体 | Publicとほぼ同じ(古い用法) |
✓ Private変数も理解すべき(中級者向け)
Private x As Long
- モジュール内だけ
- ローカルより少し広いスコープ
- Public より安全
とても便利で実務でも多用されます。
✅ Sub間の値受け渡しは “引数” を使うのが最適
Sub Main()
Dim total As Long
total = GetTotal(10, 20)
Debug.Print total
End Sub
Function GetTotal(a As Long, b As Long) As Long
GetTotal = a + b
End Function
グローバル変数に頼らなくても、安全にデータを渡せます。
❗ グローバル変数を使わざるを得ないケース
- 設定情報(ログ保存先、初期ディレクトリ)
- ユーザーフォームと標準モジュール間の値共有
- 大規模Excelアプリでの状態管理
- 他モジュールへの通知(イベント的用途)
ただし、使う場合は 名前ルールの徹底 が必要です。
✔ グローバル変数の命名規則(実務向け)
Public gUserName As String
Public gSettingFolder As String
Public gFlgDebug As Boolean
先頭に「g」を付けると識別しやすいです。
❗ RPA(UiPath/PAD)と連携する場合の注意点
- 値が意図せずリセットされるとフローが停止
- Variant/Empty の扱いで誤作動
- Excelの再計算で値初期化
- マクロ呼び出し時にスコープが乱れる
RPA連携では ローカル変数+引数 にすることが推奨です。
✔ ChatGPT でマクロ作成する場合も注意
AI が書くコードはよく:
- グローバル変数を多用
- Dim を省略
- 変数スコープを明示しない
という問題があります。
記事を読んだ読者は、
「AIが作成したコードの改善ポイント」も理解できるようになります。
🧪 実務でよくあるスコープミス例と改善版
▼誤った例
Public lastRow As Long
Sub A()
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
End Sub
Sub B()
MsgBox lastRow
End Sub
他の処理で書き換えられると、結果が大きく狂う。
▼改善例
Sub Main()
Dim lastRow As Long
lastRow = GetLastRow
MsgBox lastRow
End Sub
Function GetLastRow() As Long
GetLastRow = Cells(Rows.Count, 1).End(xlUp).Row
End Function
関数で返す形にすると安全。
🧠 変数スコープを理解するとコードは劇的に改善する
- マクロが壊れにくくなる
- 他の人と共同開発しやすくなる
- 影響範囲が見えるためバグが減る
- 大規模化に耐えられる
中級者に進む上で避けて通れない知識です。
✅ まとめ:ローカル変数・グローバル変数は“使う場所”が重要
最後にこの記事の内容を整理します。
● ローカル変数
- Sub/Function 内でのみ有効
- 最も安全で推奨
- 基本はすべてローカルで書くべき
● グローバル変数(Public)
- プロジェクト全体で参照できる
- 強力だが危険
- 設定値など限定用途でのみ使用推奨
● 使い分けの原則
- 基本はローカル
- 必要な時だけPublic
- 値の受け渡しは引数が最良
- Staticは状態保持にのみ使用
スコープを正しく理解すると、
あなたのVBAコードは安全性・再利用性・保守性が一気に向上します。