TL;DR —
Workbook_Openはイベントプロシージャです:ファイルが開き終わった 瞬間に Excel が代わりに呼び出してくれるので、ボタンもユーザー操作もなしにマクロが 自分から走ります。成否を分けるのは 2 つ。まず、コードはThisWorkbookオブジェクトに置かなければなりません — 標準のModuleではなく。Module1に 貼り付ければ、それは単に一度も発火しません。次に、マクロが有効なときにしか 走りません — かつファイルがマクロ有効ブック(.xlsm/.xlsb)である必要が あります。ユーザーがマクロをブロックしたまま開くと、何も起きず、エラーも 表示されません。
' このコードは ThisWorkbook オブジェクトに置きます(プロジェクトエクスプローラーで
' "ThisWorkbook" をダブルクリック — Module1 ではありません)。
Private Sub Workbook_Open()
Worksheets("Dashboard").Activate
Range("A1").Select
MsgBox "Welcome back — data last refreshed " & Format(Now, "dd mmm, hh:nn")
End Sub
ほとんどのマクロは、ボタンやショートカット、あるいは [マクロ] ダイアログを待ちます。
イベントマクロは違います:あなたはそれを呼び出しません — 登録するのです。そして
何かが起きたときに Excel が走らせます。Workbook_Open は、多くの人が最初に出会う
イベントです。「ファイルを開くたびにこれをする」というのは、それほどよくある要望
だからです:ダッシュボードに飛ぶ、クエリを更新する、UI を整える、開いたログを刻む。
同時に、最も「発火させられない」と悩まれるイベントでもあります — ほぼいつも、この
記事が見逃しようもなくする 2 つの理由のどちらかによって。
この記事で学べること
- 考え方の軸 — 実行するマクロではなく、登録するイベントハンドラー
- すべてを決めるたった 1 つのルール — コードは
ThisWorkbookに置く - 無言で一度も走らない理由 — マクロのセキュリティと、間違ったファイル形式
Workbook_Openと旧来のAuto_Open、そしてどちらを使うか- イベントコードが速く落ちにくくあるべき理由 — 開くたびにユーザーを出迎えるから
考え方の軸:実行するマクロではなく、登録するイベントハンドラー
通常のマクロは、あなたが発動する動詞です:ボタンを押すと Sub RefreshData が
走ります。イベントプロシージャはその逆です — 一度書いて、決まった場所に正確な
名前で置くと、あとはExcelがいつ呼ぶかを決めます。Workbook_Open を走らせるのは
あなたではありません。あなたは Excel に「このブックが開いたら、これをして」と
約束し、Excel がその約束を代わりに守るのです。
これは「このコードをどこに置くか」の考え方をひっくり返します。通常のマクロなら、
置き場所はほとんど問題になりません。イベントでは、置き場所こそが登録です。
Excel は Workbook_Open をただ 1 か所 — そのブック自身のコードモジュール、
ThisWorkbook と呼ばれる場所 — だけで探し、それ以外では探しません。名前と場所の
両方が揃って、契約のすべてになります。
すべてを決めるルール:コードは ThisWorkbook に置く
これは、Workbook_Open が「動かない」ときのナンバーワンの理由です:コードが標準
モジュールに貼り付けられていた、というものです。Workbook_Open はブック
オブジェクトのメンバーなので、そのハンドラーはブックのコードモジュール —
ThisWorkbook — に置かねばなりません。Module1 ではありません。
プロジェクトエクスプローラー(VBA エディターで Ctrl+R)
└─ VBAProject (YourFile.xlsm)
├─ Microsoft Excel Objects
│ ├─ Sheet1 (Sheet1) ← ワークシートのイベントはここ
│ └─ ThisWorkbook ← Workbook_Open はここに置く(ダブルクリック)
└─ Modules
└─ Module1 ← ここに置いた Workbook_Open は絶対に発火しない
骨組みを毎回正しく作る手っ取り早い方法があります:ThisWorkbook のコードペインを
開き、左側の(オブジェクト)ドロップダウンで Workbook を選び、右側の
(プロシージャ)ドロップダウンで Open を選びます。すると Excel が正確な
シグネチャを書いてくれます:
Private Sub Workbook_Open()
End Sub
シグネチャは固定です。Private Sub Workbook_Open() — 引数なし、綴りは正確に、
ThisWorkbook の中に。名前を変えたり、パラメーターを足したり、移動したりすれば、
それはイベントハンドラーであることをやめ、ただの(決して呼ばれない)サブに
なります。ルールはこうです:自動実行マクロが発火しないなら、まず置き場所を
確認する — 9 割がた、ThisWorkbook ではなく Module に入っています。
無言で走らない理由のルール:マクロが有効でなければならない
正しい場所にあってさえ、Workbook_Open が走るのは、Excel がマクロの実行を
許されているときだけです — そして許されていないとき、警告もエラーもありません。
3 つのことが、静かにそれをオフにします:
- ファイルがマクロ有効ではない。 VBA が生き残れるのは
.xlsmか.xlsbの 中だけです。コードを持つブックを素の.xlsxとして保存すると、Excel はWorkbook_Openを含むすべてのマクロを — 一瞬のプロンプトだけで — 剥ぎ取ります。 イベントは単に消えてなくなります。 - セキュリティでマクロが無効。 ユーザーがファイルを開いて保護ビューのままに したり、「コンテンツの有効化」バナーを有効にせず素通りしたりすると、マクロは 走らないので、イベントも発火しません。
- アプリケーションレベルでイベントがオフ。 以前のどこかのコードが
Application.EnableEvents = Falseを設定して戻さなかった場合、ブックと ワークシートのイベントは、そのセッションの間ずっと抑制されたままです。
設計上の教訓が効いてきます:データの正しさを Workbook_Open だけに依存させては
いけません。 利便性には最適です — シートに飛ぶ、表示を更新する — が、ユーザーが
マクロをオフにして開けば、あなたの「必ず走る」コードは走りませんでした。それは
体験を良くする「あると嬉しい」ものとして扱い、保証としては扱わないこと。(目的が
ただユーザーにセキュリティバナーを越えてもらうことなら、Excel でマクロを有効に
する方法 を参照してください。)
Workbook_Open 対 Auto_Open:遺物ではなくイベントを使う
開いたときにコードを走らせる方法は 2 つ見かけますが、両者は同じものではありません:
Auto_Openは旧来(Excel 5/95 時代)の仕組みです。標準 Module に置かれる 素のSub Auto_Open()です。後方互換のために今も動きますが、遺物です。Workbook_Openは現代的なイベントで、ThisWorkbookに置かれます。
両者は、痛い形で違います:
Workbook_Open(イベント) |
Auto_Open(旧来) |
|
|---|---|---|
| 置き場所 | ThisWorkbook |
標準の Module |
Workbooks.Open(コードで開く)で発火 |
する | しない(.RunAutoMacros が必要) |
| 両方あるとき | 先に走る | あとに走る |
| ステータス | 現行・推奨 | 後方互換のみ |
覚えておくべき 1 つ:別のマクロが Workbooks.Open "Report.xlsm" であなたの
ファイルを開くと、Workbook_Open は発火しますが、Auto_Open はしません
(wb.RunAutoMacros xlAutoOpen を明示的に呼ばない限り)。この違いだけで、
自動化パイプラインが Auto_Open で壊れる理由になります。Workbook_Open を
書くこと。Auto_Open に手を伸ばすのは、とても古いファイルを保守するときだけに。
開くたびを台無しにしないルール:速く、落ちにくく
Workbook_Open はユーザーが何かをできるようになる前に走ります — なので、それが
何をしようと、ユーザーはそれを「ファイルが開くのにかかる時間」そして「ファイルが
そもそもきれいに開くかどうか」として体験します。2 つの習慣が、それを行儀よく
保ちます:
Private Sub Workbook_Open()
On Error GoTo Fail ' 開く処理をユーザーの目の前でクラッシュさせない
Application.ScreenUpdating = False
Worksheets("Dashboard").Activate
Range("A1").Select
Application.ScreenUpdating = True
Exit Sub
Fail:
Application.ScreenUpdating = True ' エラー時でも、状態は必ず元に戻す
MsgBox "Startup skipped: " & Err.Description, vbExclamation
End Sub
- 必ずエラー処理で包む。 ここで処理されないエラーは、ユーザーがファイルを開いた
瞬間に生の VBA エラーを顔面に突きつけ、
ScreenUpdatingやEnableEventsの ような設定をオフのまま残しかねません。ハンドラーの中で状態を元に戻しましょう。 (これは VBA On Error で扱うのと同じ心得です。) - 重い処理はここから外すか、見えるようにする。
Workbook_Openの中の遅い クエリや大きなループは、フリーズしたファイルとまったく同じに見えます。処理が どうしても避けられないなら、状態メッセージを見せるか、ユーザーが自分で押す ボタンの後ろに移しましょう。
Workbook_Open は、ブックイベントという一族の一員です —
Workbook_BeforeClose、Workbook_BeforeSave、Workbook_SheetChange — どれも
ThisWorkbook に置かれます。そのシートレベルの親戚は、シートの内側で起きること
に反応します:セルが編集されたときの Worksheet_Change、
そしてカーソルが動いたときの
Worksheet_SelectionChange です。
ExcelMaster の活用
Workbook_Open を組み上げるのは、鋭い縁のある小さな儀式です:正しいオブジェクト、
正確な名前、マクロ有効なファイル、エラー処理、開く処理を止めない。どれか 1 つでも
間違えると、症状は同じ、あの役に立たない「何も起きなかった」です。
ExcelMaster
なら、代わりに結果を説明できます。「このファイルを開くたびに、ダッシュボード
シートに飛んで、ピボットを更新して」と言えば、ハンドラーを書き、それを
ThisWorkbook に置き、失敗が開く処理をクラッシュさせないように包みます。ファイルは
あなたのもので、一行残らず読めます — けれど、マクロが Module1 に着地したせいで
無言で走るのを拒む、あの部分は飛ばせるのです。
よくある質問
Excel で Workbook_Open のコードはどこに書きますか?
標準モジュールではなく、ThisWorkbook オブジェクトの中です。VBA エディター
(Alt+F11)を開き、プロジェクトの「Microsoft Excel Objects」の下にある
ThisWorkbook を見つけ、ダブルクリックして、そこに Private Sub Workbook_Open()
を置きます。Module1 に置いた Workbook_Open サブは見た目こそ同じですが、決して
発火しません。Excel はこのイベントを、ブック自身のコードモジュールでしか探さない
からです。
Workbook_Open マクロが走らないのはなぜですか?
ほぼいつも 3 つのうちのどれかです:コードが ThisWorkbook ではなく Module に
ある。ファイルが .xlsm ではなく .xlsx(すべてのマクロが剥がれる)で保存された。
あるいはユーザーがマクロを無効にしたまま開き、「コンテンツの有効化」をクリック
しなかった。まず置き場所を確認してください — もっともよくある原因です。以前の
コードが Application.EnableEvents = False を残していないかも確かめましょう。
Workbook_Open と Auto_Open の違いは何ですか?
Workbook_Open は ThisWorkbook に置かれる現代的なイベントです。Auto_Open は
標準モジュールに置かれる旧来のマクロです。実務上の要となる違い:Workbook_Open は
別のマクロ(Workbooks.Open)でファイルが開かれたときにも発火しますが、
Auto_Open は RunAutoMacros を呼ばない限り発火しません。Workbook_Open を使い、
Auto_Open は古いファイルの保守用にだけ残しましょう。
マクロがファイルを開いたとき、Workbook_Open は走りますか?
はい。コードが Workbooks.Open "Report.xlsm" を実行すると、そのブックの
Workbook_Open は通常どおり発火します。もし特にそれを抑えたいなら — たとえば
自動バッチ処理で — Workbooks.Open の呼び出しの前に
Application.EnableEvents = False を設定し、あとで True に戻します。
Workbook_Open を走らせずにブックを開くには?
ファイルを開く間 Shift キーを押し続けると、その一回の開く操作については
Workbook_Open をスキップできます。コードからなら、Workbooks.Open の前に
Application.EnableEvents = False を設定し、あとで True に戻します。どちらも、
起動マクロが暴れていて、直すためにファイルの中に入る必要があるときに役立ちます。
検証環境
検証環境: Excel 365 (Windows 11), VBA 7.1 — 最終確認 2026-08-02。
関連ガイド: VBA Worksheet_Change · VBA Worksheet_SelectionChange · VBA On Error · VBA Workbook · Enable Macros in Excel
