VBAの処理を可視化して読み解くには?呼び出し関係と読み書きするシートを1枚の図にする
VBAの処理の可視化とは、プロシージャどうしの呼び出しと、それぞれが読み書きするシートを線でつなぎ、1枚の図にすることです。止まったときに、どの処理がどのシートに書いたかから逆にたどれます。架空の受注集計マクロ(788行)を解析ツールにかけると、呼び出し79本のうち72本、シートの読み書き38組のうち33組を自動で拾えました。マクロの守りの実験です(2026年10月時点)。
読み解きから直す・置き換えるまでの流れと費用はExcelマクロの引き継ぎのページにまとめています。
要点
- マクロの処理の図は、呼び出しと読み書きするシートを線でつなぎ、止まったときに見る場所を絞るためのものです。
- 架空の受注集計マクロ788行では、名前で呼ぶ呼び出し72本を解析ツールがすべて拾いました。
- Application.RunとOnTimeに名前を文字で渡す呼び出しと、イベントで動く呼び出しの計7本は1本も拾えませんでした。
- ツールが「どこからも呼ばれない」とした4つのうち3つは使われていたので、消す前に名前を文字で検索します。
目次
マクロの処理を図にすると、何が分かるのですか?
止まったときに、どの処理のどの行から見ればよいかが分かります。図に描くのは、プロシージャの呼び出しと、各プロシージャが読むシート・書くシートの2種類の線です。マクロの守りのExcelマクロの引き継ぎでは、この図を最初の資料にします。
このページは、処理を図にする方法だけを扱います。引き継ぎ書に書く項目は12項目のひな形、全体の進め方は6段階の手順にあります。
モジュールが10を超えるマクロを開くと、どこから読めばよいか迷います。行の上から読んでも、処理の順番にはなっていません。入口からの線と、シートへの線があれば、読む範囲を数か所に絞れます。描く線と、それで答えられる問いは次のとおりです。
| 線の種類 | つなぐもの | 答えられる問い |
|---|---|---|
| 入口 | ボタン・ブックを開いたときなど → プロシージャ | このボタンを押すと、どこから始まるか |
| 呼び出し | プロシージャ → プロシージャ | この処理を直すと、どこに影響するか |
| 読む | シート → プロシージャ | このシートの列を変えると、どの処理が困るか |
| 書く | プロシージャ → シート | このシートの数字は、どの処理が作ったか |
呼び出し関係とシートの読み書きは、どうやって数えるのですか?
ブックからVBAのコードを取り出し、プロシージャの名前とシートの名前が出てくる行を数えます。取り出しには、Officeのファイルを読むPythonのツール、oletoolsのolevbaを使いました。olevbaは、ブックを開いたときなどに自動で動くマクロも「AutoExec」として示します。
呼び出しとシートの数え方は自作です。文字列とコメントを除いた行の語が、ほかのプロシージャの名前なら線を引きます。同じ名前のPrivateのプロシージャが2つのモジュールにあるときは、呼んだ側のモジュールのものを選びます。要点は次の数行です(call_graph.py)。
for tok in TOK.findall(strip(raw)): # 文字列とコメントを除いた語
if tok == p['name']:
continue # 関数名 = 値 は戻り値の代入
t = resolve(p['module'], tok) # 同じモジュール → Public の順に探す
if t and t != p['id']:
calls.add((p['id'], t))
シートは Sheets("…") と Worksheets("…")、それを入れた変数、Withの中の行、シートのコード名から数えます。代入の左辺か、ClearContentsなどの対象になったシートを「書く」にしました。
解析ツールは、呼び出しをどこまで拾えたのですか?
名前で呼ぶ呼び出しは72本すべて拾い、名前を文字で渡す呼び出しとイベントの7本は1本も拾えませんでした。マクロの守りで、架空の受注集計マクロを書き、解析ツールの結果を手で追った一覧と突き合わせた結果です。
サンプルは、標準モジュール10・ThisWorkbook・シート1の計12モジュール、788行、プロシージャ45個です。ボタン3つとイベント4つが入口で、前任者のマクロでよく見る書き方を混ぜました。正解の一覧は、コードを1行ずつ読んで書きました。
シートの読み書きは38組のうち33組を拾い、読み書きの別も33組すべて合っていました。拾えなかった線と、余分に出た線は次のとおりです。
| 拾えなかった・余分に出た線 | 本数 | サンプルの書き方 |
|---|---|---|
| Application.Run に名前をつないで渡す | 2本 | Application.Run "帳票_" & 出力形式 |
| Application.OnTime に名前を渡す | 2本 | 30分ごとの自動保存 |
| セルへの書き込みや保存で動くイベント | 3本 | 取り込みで Worksheet_Change が動く |
| シート名を設定シート・月・引数から作る | 5組 | Sheets(nm) |
| 別のブックのシートを数えた(余分) | 2組 | マスタのブックの「得意先」 |
限界もあります。サンプルは自分で書いた架空のもので、Excelでは動かさず、モジュールのテキストを解析しました。
ツールが拾えない呼び出しは、どう見つけますか?
Application.Run、OnTime、OnAction と、シートやブックのイベントを、VBEの検索(Ctrl+F)で探して手で線を足します。この3つは、呼び先のプロシージャ名を文字列で受け取るので、名前の語として現れません(Microsoft Learn)。
Worksheet_Change などのイベントを持つシートでは、ほかの処理がセルへ値を書いた所が呼び出しの元です。サンプルでは、CSVの取り込みと月次の繰り越しが、受注入力シートのイベントを動かしていました。Microsoftの説明の例でも、イベントの中でセルへ書く前は、Application.EnableEventsをFalseにしています。
いちばん気をつけるのは「どこからも呼ばれない」という判定です。ツールは4つのプロシージャを未使用としましたが、本当に使われていないのは「旧_集計」1つでした。帳票の2つと30分ごとの保存は、文字列で呼ばれていたからです。
未使用の印が付いたプロシージャは、名前をブック全体で文字として検索してから外します。ボタンに登録したマクロもコードの外にあるので、右クリックの「マクロの登録」で確かめます。
マクロが止まったとき、図のどこから見ればよいですか?
おかしな値が出たシートから始め、そのシートに書くプロシージャへ線を逆にたどります。たとえば出荷指示シートが空なら、書いているのは「出力_出荷指示」の1つだけなので、そこの抽出の条件から見ます。
次に、同じシートを読む処理を確かめます。サンプルでは、帳票のPDF・印刷と、基幹システムへのCSVの3つでした。書く処理を直したら、読む処理を複製のブックで動かし、結果が変わっていないかを見ます。
エラーで止まったときは、VBEで止まった行のプロシージャを図で探し、入口までの道を確かめます。どのボタンから来たかが分かれば、同じ操作を複製で再現できます。引き継ぎ書に図を貼るときの項目はVBAの引き継ぎ書のひな形にあります。
図にした呼び出しのうち、実行時に止まる行の読み方は実行時エラー1004・9・13・91の読み方に、部品の参照が切れた場合は参照設定の記事にあります。
このサイトで相談するには?
マクロの守りでは、作った人がいないマクロを解析ツールで数え、手で追った線を足して、処理の図にします。何をどう頼むか決まっていなくても大丈夫です。御社のやり方に合わせて、進め方を一緒に考えます。
準備は要りません。無料で相談するからお送りください。
よくある質問
- 解析ツールにかけると、マクロが動いてしまいませんか?
- いいえ。今回の解析は、VBAのコードを文字として読んで数えるだけで、Excelを起動していません。データの入ったシートにも触れません。
- 社外のサービスにコードを送らずに図にできますか?
- はい。olevbaと自作の解析は手元のPCで動きます。788行の解析は0.83〜0.94秒(3回)で終わりました。
- 何千行のマクロでも、同じように拾えますか?
- 分かりません。今回は788行の架空のサンプルです。手で確かめる量は行数より、名前を文字で渡す書き方とイベントの数で決まります。
- 図を作れば、引き継ぎ書はいりませんか?
- いいえ。図が示すのは、どこを見ればよいかまでです。動かし方や止まったときの戻し方、直してよい所は、人が引き継ぎ書に書きます。
この記事の実験・計算の条件
架空の受注集計マクロ788行・12モジュール、呼び出し79本。解析は3回で0.83〜0.94秒。2026年10月16日。
出典
- oletools のドキュメント「olevba」(OfficeのファイルからVBAのコードを取り出して解析するPythonのツール)(2026年10月16日確認)
- GitHub「Vba2Graph」README(olevbaの出力からVBAの呼び出しグラフを作るツール。短所に静的解析の限界)(2026年10月16日確認)
- Microsoft Learn「Application.Run method (Excel)」(2026年10月16日確認)
- Microsoft Learn「Application.OnTime method (Excel)」(2026年10月16日確認)
- Microsoft Learn「Worksheet.Change event (Excel)」(2026年10月16日確認)
- Microsoft Learn「Shape.OnAction property (Excel)」(2026年10月16日確認)