VBAローカルウィンドウの使い方|変数の値を一覧で確認してデバッグを効率化

スポンサーリンク

VBAでマクロを作っていて「この変数、今どんな値が入ってるの?」と確認したくなること、よくありますよね。

MsgBoxで1つずつ表示させる方法だと、変数が増えるたびにコードが煩雑になります。Debug.Printも便利ですが、変数が10個も20個もあると追いきれません。

そんなときに頼りになるのが ローカルウィンドウ です。表示するだけで、プロシージャ内のすべての変数と値が一覧で見えます。この記事では、表示方法からステップ実行との組み合わせ、他のデバッグウィンドウとの使い分けまで解説していきますね。

NOTE

VBEの起動方法や画面の見方は「VBE画面の見方」で解説しています。Alt + F11 でVBEを起動し、「挿入」→「標準モジュール」でコードを書く準備ができます。対象環境はExcel 2016以降(Microsoft 365含む)です。

  1. VBAのローカルウィンドウとは?
    1. ローカルウィンドウで確認できること
    2. ローカルウィンドウが特に役立つ場面
  2. ローカルウィンドウの表示方法
    1. メニューから表示する
    2. ショートカットキーはある?
  3. ローカルウィンドウの基本的な使い方
    1. サンプルコードで動作を確認する
    2. 表示される内容を読み解く
    3. 配列の中身を展開して確認する
    4. 列幅の調整
  4. ステップ実行との組み合わせが最強
    1. ステップ実行とは
    2. ステップ実行 + ローカルウィンドウの手順
    3. ブレークポイントと組み合わせる
  5. ローカルウィンドウの実践活用パターン
    1. 型の不一致エラーを特定する
    2. ループの途中経過をモニタリングする
    3. オブジェクト変数のプロパティを一覧確認する
  6. デバッグウィンドウ3種の使い分け
    1. 3種類のデバッグウィンドウ比較
    2. 場面別おすすめの使い方
  7. ローカルウィンドウのよくあるトラブルと対処法
  8. Dictionary オブジェクトの中身をローカルウィンドウで確認する
  9. 値を直接編集して「仮の値」でデバッグする
  10. コールスタックを使ってプロシージャ間のデバッグをする
  11. For Each ループでオブジェクトを繰り返すときの変数追跡
  12. ユーザー定義型(Type)の中身をローカルウィンドウで展開する
  13. クラスモジュールのインスタンス変数を確認する
  14. ローカルウィンドウで「変数が見えない」ときの原因チェックリスト
    1. マクロが実行中か、完全に止まっているかを確認する
    2. 値が「Empty」と表示されるとき
    3. オブジェクト変数が「Nothing」と表示されるとき
    4. モジュールレベル変数が見当たらないとき
    5. Option Explicit を入れていない場合の落とし穴
    6. ByRef 引数は呼び出し元の変数と連動する
  15. まとめ
    1. この記事で紹介したVBA関連記事

VBAのローカルウィンドウとは?

ローカルウィンドウは、VBE(Visual Basic Editor)に搭載されている デバッグ用のウィンドウ です。実行中のプロシージャ(Sub〜End Sub)に含まれる すべての変数の名前・値・データ型 を自動的に一覧表示してくれます。VBAの変数の使い方がまだ不安な方は、先にそちらを確認しておくと理解がスムーズです。

難しい設定は一切不要です。ウィンドウを表示しておくだけで、マクロが一時停止したタイミングで変数の状態がズラッと並びます。

ローカルウィンドウで確認できること

ローカルウィンドウには3つの列があり、変数の状態をひと目で把握できます。

列名表示される内容確認できること
変数名どんな変数が宣言されているか
変数に入っている値想定どおりの値が入っているか(クリックで直接編集可。Enterで確定、Escで取消)
データ型(Integer, String など)型の不一致がないか

たとえば「数値のつもりで計算しているのに、実は文字列型だった」というバグは、型の列を見れば一発で分かります。VBAを始めたばかりの頃、この手の型ミスで何時間も悩んだ経験がある方は多いのではないでしょうか。

ローカルウィンドウが特に役立つ場面

ローカルウィンドウは、次のようなケースで威力を発揮します。

  • 変数が多いプロシージャのデバッグ: 5個以上の変数があると、Debug.Printで全部追うのは大変です
  • 配列やオブジェクトの中身確認: 展開表示で要素を1つずつ確認できます
  • 型の不一致によるエラー調査: 「型が一致しません」エラーの原因特定に最適です
  • ループ中の値の変化を追跡: ステップ実行と組み合わせて1行ずつ確認できます

ローカルウィンドウの表示方法

ローカルウィンドウはデフォルトでは非表示になっていることが多いです。表示する方法を確認しましょう。

メニューから表示する

VBE画面の上部にあるメニューバーから 「表示」→「ローカル ウィンドウ」 を選択します。VBE画面の下部にローカルウィンドウが表示されます。

ショートカットキーはある?

残念ながら、ローカルウィンドウにはデフォルトのショートカットキーが割り当てられていません。イミディエイトウィンドウCtrl + G)のように一発では開けないので、メニューから表示する方法を覚えておきましょう。

一度表示すれば、VBEを閉じるまでローカルウィンドウは表示されたままです。毎回メニューから開く必要はありませんよ。

TIP

会社の共有PCでは、前に使った人がウィンドウのレイアウトを変えていることがあります。ローカルウィンドウが見つからないときは、画面の端に小さく畳まれていないか確認してみてください。メニューの「表示」から再表示すれば元通りになります。

ローカルウィンドウの基本的な使い方

ここからが本題です。実際にサンプルコードを使って、ローカルウィンドウの使い方を体験してみましょう。

サンプルコードで動作を確認する

まずは以下のコードをVBEの標準モジュールに貼り付けてください。

Sub LocalWindowSample()
    Dim i As Integer      '--- カウンター変数 ---
    i = 4

    Dim sCategory As String  '--- カテゴリ名 ---
    sCategory = "食べ物"

    Dim vFruits As Variant   '--- 果物リスト(配列) ---
    vFruits = Array("りんご", "いちご", "ばなな")

    Stop  '--- ここでマクロが一時停止する ---
End Sub

最後の Stop はプログラムを一時停止させるステートメントです。この行に到達した時点でマクロの実行が止まり、ローカルウィンドウに変数の状態が表示されます。

表示される内容を読み解く

ローカルウィンドウを表示した状態でこのマクロを実行(F5)すると、Stop の行で一時停止します。このとき、ローカルウィンドウには以下のような内容が表示されます。

i4Integer
sCategory食べ物String
vFruits Variant()

ウィンドウの左上には実行中のプロシージャ名が表示されます。たとえば 「VBAProject.Module1.LocalWindowSample」 のような並びです。「プロジェクト名.モジュール名.プロシージャ名」の順番で読めます。

配列の中身を展開して確認する

配列変数(上の例では vFruits)は、変数名の左に表示される 「+」マーク をクリックすると中身を展開できます。

展開すると、このように要素が1つずつ表示されます。

vFruits(0)りんごString
vFruits(1)いちごString
vFruits(2)ばななString

配列の中身を確認するのに For ループで Debug.Print を書く必要がありません。展開するだけで全要素が見えるのはとても便利ですよね。

オブジェクト変数(Range 型や Worksheet 型など)も同じように展開できます。ValueRowColumn といったプロパティが一覧で見えます。「このRangeオブジェクト、何行目を指してるんだっけ?」というときにサッと確認できますよ。

なお、モジュールレベル変数(DimPrivate でモジュール先頭に宣言した変数)は、ローカルウィンドウ先頭の展開可能なエントリの中に表示されます。

列幅の調整

環境によっては、値や型の表示が列に収まりきらず途中で切れてしまうことがあります。そんなときは、列見出しの境界線(「式」と「値」の間など)をマウスでドラッグすると列幅を調整できますよ。

ステップ実行との組み合わせが最強

ローカルウィンドウが最も威力を発揮するのは ステップ実行(F8) との組み合わせです。

ステップ実行とは

ステップ実行とは、コードを 1行ずつ 実行していくデバッグ方法です。VBEで F8 キーを押すたびに1行ずつ処理が進みます。

通常の実行(F5)ではマクロが一瞬で完了してしまうので、途中経過を確認できません。ステップ実行なら「この行を実行したら変数はどう変わるか」を1行ごとに追跡できます。

ステップ実行 + ローカルウィンドウの手順

実際の使い方を見てみましょう。以下のコードで試してみてください。

Sub StepExecutionSample()
    Dim total As Long   '--- 合計値 ---
    Dim i As Long       '--- カウンター ---

    total = 0

    For i = 1 To 5
        total = total + i * 100
    Next i

    MsgBox "合計: " & total
End Sub

手順:

  1. ローカルウィンドウを表示しておく(メニュー「表示」→「ローカル ウィンドウ」)
  2. コード内の任意の行にカーソルを置く
  3. F8 キーを押してステップ実行を開始する
  4. F8 を押すたびに1行ずつ進み、ローカルウィンドウの値がリアルタイムで更新される

値が変化した変数は赤くハイライト表示されるので、どこが変わったか一目で分かります。

ループの1周目で i = 1total = 100 に変わり、2周目で i = 2total = 300 になる。この変化の流れがローカルウィンドウに表示されるので、処理の動きが手に取るように分かります。

「ループの3周目で値がおかしくなる」といったバグも、ステップ実行 + ローカルウィンドウなら発見が簡単です。

ブレークポイントと組み合わせる

ステップ実行だと最初から1行ずつ進めることになります。「100行目あたりから確認したい」という場合は、ブレークポイント を設定しましょう。

コードの行番号の左余白をクリックするか、確認したい行にカーソルを置いて F9 を押します。ブレークポイントが設定された行は赤く強調表示されるのが目印です。

マクロを F5 で実行すると、ブレークポイントの行で自動的に一時停止します。そこからは F8 でステップ実行に切り替えて、ローカルウィンドウで変数の変化を追えます。

TIP

ブレークポイントは複数設定できます。もう一度 F9 を押すと解除されます。すべてのブレークポイントを一括解除したいときは、メニューの 「デバッグ」→「すべてのブレークポイントの解除」 を選択してください。

ローカルウィンドウの実践活用パターン

基本的な使い方がわかったところで、実務で役立つ活用パターンを紹介します。

型の不一致エラーを特定する

VBAを書いていてよく遭遇する 「実行時エラー ’13’: 型が一致しません」 というエラー。ローカルウィンドウを使えば原因の特定がスムーズです。

Sub TypeMismatchSample()
    Dim price As Long      '--- 単価 ---
    Dim quantity As Variant '--- 数量(セルから取得) ---
    Dim total As Long       '--- 合計 ---

    price = 1000
    quantity = Range("A1").Value  '--- セルの値を取得 ---

    total = price * quantity  '--- ここでエラーが出るかも ---
End Sub

セルA1に文字列(たとえば「未入力」)が入っていると、掛け算の行で型エラーが発生します。エラーが出たらローカルウィンドウを確認してみてください。

  • quantity の列に「未入力」と表示される
  • quantity の列に「String」と表示される

「数値のつもりが文字列だった」ことが一目瞭然です。原因が分かれば、If文IsNumeric を組み合わせて事前チェックを入れるなどの対策がすぐに打てますよね。

ループの途中経過をモニタリングする

ループ処理で「途中から値がおかしくなる」というケースは、ブレークポイント + ローカルウィンドウが最適です。

Sub LoopMonitorSample()
    Dim i As Long        '--- 行カウンター ---
    Dim lastRow As Long  '--- 最終行 ---
    Dim sName As String  '--- 取得した名前 ---

    lastRow = Cells(Rows.Count, 1).End(xlUp).Row

    For i = 2 To lastRow
        sName = Cells(i, 1).Value

        '--- 名前が空のセルがあるとここで問題が起きる ---
        Cells(i, 2).Value = Left(sName, 3)
    Next i
End Sub

ブレークポイントをループ内に設定してステップ実行すれば、i が何行目のときに sName が空になるか、ローカルウィンドウですぐに分かります。

オブジェクト変数のプロパティを一覧確認する

Range 型や Worksheet 型のオブジェクト変数も、ローカルウィンドウで展開して中身を確認できます。

Sub ObjectInspectSample()
    Dim rng As Range '--- 対象セル範囲 ---
    Set rng = Range("A1:C10")

    Stop  '--- ここで一時停止 ---
End Sub

Stop で停止した状態で、ローカルウィンドウの rng の左にある「+」をクリックしてみてください。Rows.Count(10)、Columns.Count(3)、Address($A$1:$C$10)といったプロパティが一覧で見えます。

イミディエイトウィンドウ?rng.Address のように1つずつ打ち込む方法もあります。ただ、複数のプロパティをまとめて確認したいときはローカルウィンドウのほうが効率的です。

デバッグウィンドウ3種の使い分け

VBEにはローカルウィンドウ以外にもデバッグ用のウィンドウがあります。それぞれ得意分野が異なるので、場面に応じて使い分けましょう。

3種類のデバッグウィンドウ比較

比較項目ローカルウィンドウイミディエイトウィンドウウォッチウィンドウ
表示対象すべての変数(自動)手動で指定した値手動で指定した変数
設定の手間なし(表示するだけ)都度コマンド入力ウォッチ式の追加が必要
条件指定できないできない条件に合致したら自動停止が可能
値の変更一部可能(値の列を直接編集)自由に変更可能できない
向いている場面全変数をまとめて確認ちょい試し・値の書き換え特定の変数を条件付きで監視

場面別おすすめの使い方

使い分けに迷ったら、次の基準で選んでみてください。

  • 「全部の変数をざっと確認したい」ローカルウィンドウ。設定不要で一覧が出るので、最初に見るウィンドウとして最適です
  • 「1つの値をサッと確認したい」「コードの断片を試したい」イミディエイトウィンドウ?変数名 と打つだけでOKです
  • 「この変数が特定の値になった瞬間を捉えたい」ウォッチウィンドウ。条件付き中断機能が強力です

実際のデバッグでは、ローカルウィンドウで全体を俯瞰するのがおすすめです。怪しい変数はウォッチウィンドウに登録して重点監視すると効率的ですよ。

ローカルウィンドウのよくあるトラブルと対処法

使っていて「あれ?」となるケースをまとめました。

[faq q=”ローカルウィンドウに変数が何も表示されません。” a=”マクロが一時停止中でないと表示されません。StopステートメントやF8キーのステップ実行でマクロを一時停止してから確認してください。”]
[faq q=”変数の値が「Empty」と表示されます。” a=”変数に値が代入される前の行で止まっているためです。F8キーで代入行を実行してから確認してください。”]
[faq q=”ローカルウィンドウが見当たりません。” a=”非表示になっているか、画面端に畳まれています。VBEのメニュー「表示」→「ローカル ウィンドウ」で再表示できます。”]
[faq q=”文字列の値が途中で切れています。” a=”Value列は先頭255文字まで表示されます。全文を確認するにはイミディエイトウィンドウで「?変数名」と入力してEnterを押してください。”]
[faq q=”配列の中身が表示されません。” a=”配列が初期化されていない可能性があります。配列への代入後に一時停止して確認してください。”]
[faq q=”ローカルウィンドウを表示するとマクロが遅くなりますか?” a=”ほとんど影響しません。VBAを書くときは常にローカルウィンドウを表示しておくことをおすすめします。”]

NOTE

ローカルウィンドウの表示はマクロの実行速度にはほとんど影響しません。表示しっぱなしにしておいても問題ないので、VBAを書くときは常に表示しておくのがおすすめです。

Dictionary オブジェクトの中身をローカルウィンドウで確認する

業務でデータの集計や重複チェックに使われる Dictionary オブジェクト も、ローカルウィンドウで中身を確認できます。キーと値のペアを保持するため「今どんなデータが溜まっているのか」が見えにくいのですが、展開表示を使えば一気に把握できますよ。

以下のサンプルコードを標準モジュールに貼り付けて実行(F5)してみてください。

Sub DictionarySample()
    Dim d As Object
    Set d = CreateObject("Scripting.Dictionary")

    d.Add "りんご", 120   '--- キー:商品名 / 値:単価 ---
    d.Add "いちご", 300
    d.Add "ばなな", 90

    Stop  '--- ここで一時停止 ---
End Sub

Stop で停止したら、ローカルウィンドウの d の左にある「+」マークをクリックして展開してみましょう。次のような項目が確認できます。

  • d.Count: 登録されている件数(この例では 3
  • d.Keys: キーの配列。さらに展開すると「りんご」「いちご」「ばなな」が並びます
  • d.Items: 値の配列。展開すると「120」「300」「90」が見えます

ただし、KeysItems は別々の配列として展開されるため、「どのキーにどの値が対応しているか」を一覧で突き合わせるのは少し手間です。キーと値のペアをまとめて確認したいときは、For Each で回しながら イミディエイトウィンドウDebug.Print する方法のほうが向いているケースもあります。状況に応じて使い分けてみてくださいね。

値を直接編集して「仮の値」でデバッグする

ローカルウィンドウの 「値」列はクリックして直接編集できます。停止中に値の上をクリックして入力し、Enter で確定、Esc でキャンセルです。

Sub EditValueSample()
    Dim n As Integer
    n = 5

    Stop  '--- ここで n の値を書き換えてみる ---

    If n = 0 Then
        MsgBox "ゼロ除算を回避しました"
    Else
        MsgBox 100 / n
    End If
End Sub

Stop で止めたあと n の値を 0 に書き換えれば、「特定の値が来たときだけ起きるエラー」をその場で再現できます。逆に、エラー状態の変数を正常値に書き換えてその先のコードを動かす、といった使い方も便利です。なお編集できるのは Integer・String・Boolean などのプリミティブ型のみで、オブジェクト型の値は変更できません。

コールスタックを使ってプロシージャ間のデバッグをする

マクロが大きくなると、あるSubが別のSubを呼び出す「入れ子」の構造になります。こうしたケースでは「今どの関数から呼ばれているのか」を把握することがデバッグの鍵になります。

Sub CalcTotal()
    Dim total As Long
    total = CalcRow(3) + CalcRow(5)
    MsgBox total
End Sub

Function CalcRow(ByVal price As Long) As Long
    Dim qty As Long
    qty = 10
    Stop  '--- ここで一時停止 ---
    CalcRow = price * qty
End Function

CalcRow の中で停止したとき、ローカルウィンドウ上部左側の プロシージャ名のドロップダウン を開くと、呼び出し階層(コールスタック)を切り替えられます。呼び出し元の CalcTotal を選べば、その時点での CalcTotal 側の変数を確認できます。

より明示的に階層を見たいときは、メニューの 「デバッグ」→「コール スタック」(Ctrl + L で呼び出し順を一覧表示できます。「どの関数から、どんな引数で呼ばれたか」が分かるため、引数の渡し方ミスを発見しやすくなりますよ。変数の宣言や引数の扱いに不安がある方は、VBAの変数の使い方 もあわせて確認しておくと安心です。

For Each ループでオブジェクトを繰り返すときの変数追跡

For Each〜Next ループ でセル範囲やシートを繰り返す場合も、ローカルウィンドウで各イテレーションの変数の状態を追えます。

Sub ForEachSample()
    Dim ws As Worksheet   '--- ループ変数(ワークシート)---
    Dim total As Long     '--- 合計行数 ---

    total = 0

    For Each ws In ThisWorkbook.Worksheets
        total = total + ws.UsedRange.Rows.Count
        Stop  '--- 各シートを処理後に一時停止 ---
    Next ws

    MsgBox "全シートの合計行数: " & total
End Sub

Stop で止まるたびにローカルウィンドウの ws を展開すると、その周で処理しているシートの Name(シート名)・Index(シート番号)・UsedRange.Address(使用範囲)が確認できます。数値カウンターの i と違い、オブジェクトのプロパティ単位で状態を把握できるのが For Each × ローカルウィンドウの強みです。

デバッグが終わったら Stop を削除してください。「3周目だけ止まってほしい」という場合は Stop を書かず、ウォッチウィンドウ の条件付き中断(total >= 300 など)を使うほうが効率的です。

ユーザー定義型(Type)の中身をローカルウィンドウで展開する

業務VBAで「商品マスタの1行ぶんをひとまとめにして扱いたい」というときに便利なのが ユーザー定義型(Type) です。配列やDictionaryと違ってフィールド名で値を取り出せるので、可読性が高くなります。ローカルウィンドウは、このユーザー定義型の中身も配列と同じように展開して確認できますよ。

以下のサンプルコードを標準モジュールに貼り付けてみてください。

'--- 商品データ用のユーザー定義型 ---
Type ProductInfo
    Code As String      '--- 商品コード ---
    ProdName As String  '--- 商品名 ---
    Price As Long       '--- 単価 ---
    InStock As Boolean  '--- 在庫有無 ---
End Type

Sub UserDefinedTypeSample()
    Dim p As ProductInfo
    p.Code = "A001"
    p.ProdName = "りんごジュース"
    p.Price = 180
    p.InStock = True

    Stop  '--- ここで一時停止 ---
End Sub

Stop で停止したらローカルウィンドウの p の左にある「+」をクリックしてください。次のように展開されます。

p.CodeA001String
p.ProdNameりんごジュースString
p.Price180Long
p.InStockTrueBoolean

フィールド名と値・型がきれいに並ぶので、Debug.Print p.Code & "/" & p.ProdName & "/" & p.Price のように1つずつ書き出す必要がありません。フィールドが10個あっても、ワンクリックで全部見えますよ。

ユーザー定義型を配列にまとめた場合(Dim arr(1 To 100) As ProductInfo など)も同じように展開できます。arr(1) を展開すれば1番目の商品の全フィールドが、arr(2) を展開すれば2番目の商品の全フィールドが見えます。マスタ系の処理を作るときは、Typeとローカルウィンドウの組み合わせを覚えておくとデバッグがかなり楽になります。

TIP

ネストしたユーザー定義型(Typeの中にTypeを持つ構造)でも展開は階層的に動きます。たとえば ProductInfo の中に SupplierInfo 型のフィールドがあれば、p.Supplier をさらに「+」で開いてフィールドを確認できます。複雑なデータ構造ほどローカルウィンドウの威力が際立ちます。

なお、Typeのフィールド名は Name のようなVBA予約語や Worksheet.Name と衝突しやすい名前を避けるのがおすすめです。上のサンプルで Name を使わず ProdName にしているのも、トラブルを避けるためです。VBAの変数の使い方 の記事も合わせて読むと、Typeの宣言・代入の基本がより理解しやすくなりますよ。

クラスモジュールのインスタンス変数を確認する

オブジェクト指向で書いたVBAでも、ローカルウィンドウは活躍します。クラスモジュールで作ったインスタンスは、Range や Worksheet と同じようにオブジェクト変数として「+」で展開できますよ。

まずクラスモジュールを1つ追加します。VBEのプロジェクトエクスプローラーで右クリック→「挿入」→「クラスモジュール」を選び、プロパティウィンドウで (オブジェクト名)Employee に変更してください。

'--- クラスモジュール: Employee ---
Public EmpID As String      '--- 社員ID ---
Public EmpName As String    '--- 氏名 ---
Public Salary As Long       '--- 月給 ---

Private mBonusRate As Double  '--- ボーナス係数(内部用) ---

Public Property Let BonusRate(ByVal v As Double)
    mBonusRate = v
End Property

Public Property Get BonusRate() As Double
    BonusRate = mBonusRate
End Property

Public Function AnnualIncome() As Long
    AnnualIncome = Salary * 12 + CLng(Salary * mBonusRate)
End Function

標準モジュール側で次のように呼び出します。

Sub ClassInspectSample()
    Dim emp As Employee
    Set emp = New Employee

    emp.EmpID = "E001"
    emp.EmpName = "山田 太郎"
    emp.Salary = 300000
    emp.BonusRate = 2.5

    Stop  '--- ここで一時停止 ---

    MsgBox emp.EmpName & " の年収: " & emp.AnnualIncome
End Sub

Stop で停止して emp の「+」をクリックすると、EmpIDEmpNameSalary といったPublicプロパティの値・型が一覧で見えます。BonusRate のように Property Get/Let で公開している項目も、Getプロパティの戻り値として表示されますよ。

クラスのメソッド内部で停止した場合は、ローカルウィンドウに Me という特別な行が現れます。これは「自分自身のインスタンス」を表していて、Me を展開すれば自クラスの全プロパティが確認できます。デバッグ中に「あれ、今このメソッドはどのインスタンスから呼ばれてる?」と迷ったら、Me を見れば一発で分かります。

NOTE

Privateで宣言した内部変数(上の例の mBonusRate)は、外部のSubから停止した場合は直接見えないことがあります。クラス内部のメソッドで停止した場合は Me の階層に表示されるので、内部状態を確認したいときはクラスメソッド側でブレークするのがおすすめです。

ローカルウィンドウで「変数が見えない」ときの原因チェックリスト

「ローカルウィンドウを表示したのに変数が出ない」「展開したらEmptyやNothingばかりで何も分からない」というケース、けっこうあります。原因のパターンと対処法をまとめておきますね。

マクロが実行中か、完全に止まっているかを確認する

ローカルウィンドウは マクロが一時停止中 のときだけ変数を表示します。F5で普通に実行している間や、すでに End Sub まで終わってしまった後は何も表示されません。

  • 対処: 確認したい行に Stop を書くか、F9 でブレークポイントを設定してから実行する
  • 一時停止中はVBEのタイトルバーに「[中断]」と表示されるのが目印です

値が「Empty」と表示されるとき

EmptyVariant型の変数に何も代入されていない状態 を示します。

Sub EmptyCheckSample()
    Dim x As Variant
    Stop  '--- ここで x を見るとEmpty ---
    x = 100
End Sub

Stopx = 100 に移動すれば、x の値は 100 と表示されます。「代入前の行で止まっていないか」をまず疑ってみてください。

オブジェクト変数が「Nothing」と表示されるとき

Range や Worksheet などのオブジェクト変数は、Set で値をセットしないと Nothing のまま表示されます。

Sub NothingCheckSample()
    Dim ws As Worksheet
    Stop  '--- ここで ws は Nothing ---
    Set ws = ThisWorkbook.Worksheets(1)
End Sub

Set で停止すれば、ws を展開してプロパティが見えます。逆に、処理途中で Set ws = Nothing を実行した後はもう中身が見えなくなる点にも注意してくださいね。

モジュールレベル変数が見当たらないとき

DimPublic をモジュールの先頭で宣言した変数(モジュールレベル変数)は、プロシージャ内の変数と 別のエントリ に表示されます。ローカルウィンドウの先頭近くに、モジュール名の付いた展開可能な行があるはずです。「+」で開けばモジュールレベル変数の一覧が出ます。

'--- モジュール先頭で宣言(モジュールレベル変数) ---
Public gCounter As Long

Sub IncrementSample()
    Dim localVar As Long  '--- こちらはプロシージャ変数 ---
    gCounter = gCounter + 1
    localVar = gCounter * 10

    Stop  '--- localVar はすぐ見えるが gCounter はモジュール側エントリ ---
End Sub

「変数が見当たらない」と感じたら、まずモジュール側のエントリを開いてみる癖をつけておくと安心です。

Option Explicit を入れていない場合の落とし穴

モジュールの先頭に Option Explicit を書いていないと、タイプミスした変数名が 新しい変数として自動で作られてしまう ことがあります。ローカルウィンドウを見て「あれ、知らない変数が増えてる?」と思ったら、変数名のスペルミスが疑わしいです。

  • 対処: モジュール先頭に Option Explicit を必ず書く。VBEの「ツール」→「オプション」で「変数の宣言を強制する」にチェックを入れておくと、新しいモジュールには自動で挿入されます

ByRef 引数は呼び出し元の変数と連動する

ByRef(参照渡し)で受け取った引数は、ローカルウィンドウ上では 呼び出し先の引数名 で表示されます。値を書き換えると呼び出し元の変数も書き換わるので、「思っていた変数と中身が違う」というときは参照渡しを疑ってみてください。

Sub CallerSample()
    Dim n As Long
    n = 10
    Call AddTen(n)  '--- 参照渡しで n が呼び出される ---
    Stop            '--- ここで n は 20 になっている ---
End Sub

Sub AddTen(ByRef value As Long)
    value = value + 10  '--- 呼び出し元の n も書き換わる ---
End Sub

参照渡しと値渡しの違いに不安がある方は、ローカルウィンドウで実際の動きを確認してみると一気に理解が進みますよ。詳しい画面構成は VBE画面の見方 もあわせて参考にしてみてください。

まとめ

ローカルウィンドウは、VBAのデバッグ作業をぐっと効率化してくれる便利なツールです。

ポイントをおさらいしておきましょう。

  • 表示方法: VBEのメニュー「表示」→「ローカル ウィンドウ」を選択
  • 自動表示: 設定不要でプロシージャ内のすべての変数を一覧表示
  • 3つの列: 「式」(変数名)・「値」(現在の値)・「型」(データ型)
  • 配列・オブジェクトの展開: 「+」マークで中身を展開して確認
  • ステップ実行(F8)との組み合わせ: 1行ずつ実行しながら値の変化を追跡
  • ブレークポイント(F9): 確認したい箇所まで一気に実行して停止

MsgBoxで1つずつ確認していた方は、ローカルウィンドウに切り替えるだけでデバッグがかなり快適になるはずです。まずはこの記事のサンプルコードをコピーして、実際に動かしてみてくださいね。

この記事で紹介したVBA関連記事

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