「ファイルを開いたら自動でマクロが動くはずなのに、なぜか実行されない」――Auto_Open や Workbook_Open を設定したのに動かないというトラブルは、VBAを使い始めた人がほぼ必ず直面します。原因は「マクロが無効になっている」だけではなく、ファイル形式・記述場所・セキュリティ設定・呼び出し方の違いなど複数の要因が絡み合っています。本記事では、自動実行マクロが動かない原因をすべて洗い出し、確認・修正の手順からベストプラクティスまで、コード付きで徹底解説します。
目次
- Auto_OpenとWorkbook_Openの違い――まずここを整理する
- 原因1:マクロのセキュリティ設定でマクロが無効になっている
- 原因2:ファイル形式が .xlsx のままでマクロが保存されていない
- 原因3:Workbook_Openの記述場所が間違っている
- 原因4:Auto_Openの記述場所・名前が間違っている
- 原因5:アドインとして開かれているときの挙動の違い
- 原因6:ブックの保護・シートの保護によってマクロが止まる
- 原因7:Workbooks.Openで開いたときにWorkbook_Openが動かない
- 自動実行されない原因を切り分けるデバッグ手順
- 自動実行マクロの正しい書き方とベストプラクティス
- Auto_Open / Workbook_Open チェックリスト
- まとめ
Auto_OpenとWorkbook_Openの違い――まずここを整理する
Excelでファイルを開いたときにマクロを自動実行する方法は主に2つあります。どちらを使うかによって、記述場所・動作タイミング・優先順位がすべて異なります。ここを混同しているだけで「動かない」になるケースが非常に多いです。
| Auto_Open | Workbook_Open | |
|---|---|---|
| 記述場所 | 標準モジュール(Module1 など) | ThisWorkbook モジュール(必須) |
| 種類 | 通常のSubプロシージャ | Workbookオブジェクトのイベントプロシージャ |
| 実行タイミング | ブックが開いた後(やや遅い) | ブックが開く直後(早い) |
| 優先順位 | Workbook_Openより後に実行 | Auto_Openより先に実行 |
| Workbooks.Openで開いた場合 | 実行されない(後述) | 実行される |
| 推奨度 | △ 後方互換のために残っている旧来の方法 | ◎ 現在の標準的な書き方 |
結論:現在のVBA開発では Workbook_Open を使うのが標準です。Auto_Open は古いExcel(Excel 4.0マクロ時代)との互換性のために残っているもので、新規に書く場合は Workbook_Open を使います。
' ========================================
' Workbook_Open の正しい書き方(ThisWorkbookモジュールに記述)
' ========================================
' ※ VBAエディタの左ペインで「ThisWorkbook」をダブルクリックして開いたモジュールに書く
Private Sub Workbook_Open()
' ブックを開いたときに自動で実行したい処理を書く
MsgBox "ブックを開きました。", vbInformation
' シートの初期化
Sheets("メニュー").Activate
' 日付の自動入力
Sheets("ログ").Cells(1, 1).Value = Now()
End Sub
' ========================================
' Auto_Open の書き方(標準モジュールに記述)
' ========================================
' ※ 標準モジュール(Module1など)に記述する
Sub Auto_Open()
MsgBox "Auto_Openが実行されました。", vbInformation
End Sub
原因1:マクロのセキュリティ設定でマクロが無効になっている
最も頻繁に起きる原因です。Excelのセキュリティ設定によってマクロがブロックされていると、Workbook_Open も Auto_Open もいっさい実行されません。ファイルを開いたときに 「セキュリティの警告 マクロが無効にされました」というバーが表示されている場合は、これが原因です。
確認と修正の手順
まず、ファイルを開いたときに黄色い警告バーが表示されているか確認します。表示されている場合は「コンテンツの有効化」をクリックすることでマクロが有効になり、Workbook_Open が実行されます。ただし、これは1回の操作であり、次回開いたときも同じ操作が必要です。
毎回「コンテンツの有効化」を押さずに済むようにするには、信頼済み場所(トラステッドロケーション)にファイルを保存するか、マクロのセキュリティレベルを変更します。
' ========================================
' 【確認】現在のマクロセキュリティ設定をVBAで確認する
' ========================================
Sub CheckMacroSecurity()
Dim secLevel As Long
secLevel = Application.AutomationSecurity
Select Case secLevel
Case msoAutomationSecurityLow
Debug.Print "セキュリティレベル: 低(すべてのマクロを有効)"
Case msoAutomationSecurityByUI
Debug.Print "セキュリティレベル: UIの設定に従う(通常はこれ)"
Case msoAutomationSecurityForceDisable
Debug.Print "セキュリティレベル: 強制無効(Workbooks.Open時に多い)"
End Select
' セキュリティセンターの設定値(0〜4)も確認できる
' 0: すべて無効, 1: 通知付きで無効(既定), 2: デジタル署名付きのみ有効, 3: すべて有効
Debug.Print "TrustCenter設定: " & Application.AutoCorrect.ReplaceTextFromSpellChecker
End Sub
セキュリティレベルの変更は「ファイル → オプション → セキュリティセンター → セキュリティセンターの設定 → マクロの設定」から行います。業務用途では「警告を表示してすべてのマクロを無効にする」(既定)に設定し、ファイルを信頼済みの場所に保存する方法が推奨されます。
信頼済み場所に登録してセキュリティ警告を出なくする
' ========================================
' 現在のブックが信頼済み場所に保存されているか確認する
' ========================================
Sub CheckTrustedLocation()
Dim tl As TrustedLocation
Dim wbPath As String
Dim found As Boolean
wbPath = ThisWorkbook.Path
found = False
Dim i As Long
For i = 1 To Application.TrustCenter.TrustedLocations.Count
Set tl = Application.TrustCenter.TrustedLocations(i)
If InStr(1, wbPath, tl.Path, vbTextCompare) > 0 Then
found = True
Debug.Print "✓ 信頼済み場所に含まれています: " & tl.Path
Exit For
End If
Next i
If Not found Then
Debug.Print "✗ このブックのフォルダは信頼済み場所に登録されていません。"
Debug.Print " ブックのパス: " & wbPath
MsgBox "このブックのフォルダは信頼済み場所に登録されていません。" & vbCrLf & vbCrLf & _
"「セキュリティセンター → 信頼済みの場所」に以下を追加してください:" & vbCrLf & _
wbPath, vbExclamation
End If
Set tl = Nothing
End Sub
原因2:ファイル形式が .xlsx のままでマクロが保存されていない
「マクロを書いて保存したのに、次に開いたら消えていた」「Workbook_Openを書いたのに動かない」――このケースで非常に多いのが、ファイルを .xlsx 形式で保存してしまっている問題です。
.xlsx はマクロを含められないファイル形式です。マクロを書いたブックは必ず .xlsm(マクロ有効ブック) として保存しなければなりません。.xlsx で保存しようとするとExcelが警告を出しますが、「はい(.xlsx として保存)」を選んでしまうとマクロはすべて削除されます。
| 拡張子 | 正式名称 | マクロの保存 | 自動実行 |
|---|---|---|---|
.xlsx | Excelブック | ✗ 不可 | ✗ 不可 |
.xlsm | Excelマクロ有効ブック | ✓ 可 | ✓ 可 |
.xlsb | Excelバイナリブック | ✓ 可 | ✓ 可 |
.xls | Excel 97-2003 ブック | ✓ 可(旧形式) | ✓ 可 |
.xla / .xlam | Excelアドイン | ✓ 可 | △ 挙動が異なる(後述) |
' ========================================
' 現在のブックのファイル形式を確認する
' ========================================
Sub CheckFileFormat()
Dim fmt As XlFileFormat
fmt = ThisWorkbook.FileFormat
Select Case fmt
Case xlOpenXMLWorkbook ' 51 : .xlsx
MsgBox "このブックは .xlsx 形式です。" & vbCrLf & vbCrLf & _
"マクロを保存するには .xlsm 形式で保存し直してください。" & vbCrLf & _
"「ファイル → 名前を付けて保存 → ファイルの種類: Excelマクロ有効ブック」", _
vbExclamation
Case xlOpenXMLWorkbookMacroEnabled ' 52 : .xlsm
MsgBox "✓ このブックは .xlsm 形式です。マクロを保存できます。", vbInformation
Case xlExcel8 ' 56 : .xls
MsgBox "このブックは .xls 形式(Excel 97-2003)です。マクロを保存できます。", vbInformation
Case xlOpenXMLTemplateMacroEnabled ' .xltm
MsgBox "このブックは .xltm 形式(マクロ有効テンプレート)です。", vbInformation
Case Else
MsgBox "ファイル形式コード: " & fmt & vbCrLf & _
"マクロが保存できない形式の可能性があります。", vbExclamation
End Select
End Sub
注意:拡張子を .xlsm に手動でリネームしてもマクロは保存されません。必ずExcelの「名前を付けて保存」から「Excelマクロ有効ブック(*.xlsm)」を選択して保存し直してください。
原因3:Workbook_Openの記述場所が間違っている
「Workbook_Open を書いたのに動かない」という場合、最も多い原因が記述場所の誤りです。Workbook_Open はイベントプロシージャであり、必ず「ThisWorkbook」モジュールに記述しなければなりません。標準モジュール(Module1など)に書いても絶対に自動実行されません。
' ========================================
' ✗ 間違い:標準モジュール(Module1)に書いている
' → これは「ただのSubプロシージャ」であり、自動実行されない
' ========================================
' Module1 に記述してしまっている例(動かない)
Sub Workbook_Open() ' ← 標準モジュールに書いても自動実行されない
MsgBox "これは動きません"
End Sub
' ========================================
' ✓ 正しい:ThisWorkbookモジュールに書く
' → VBAエディタ左ペインの「ThisWorkbook」をダブルクリックして開くモジュール
' ========================================
' ThisWorkbook モジュールに記述する正しい例
Private Sub Workbook_Open() ' ← Private Sub にするのが正式
MsgBox "正しく自動実行されます"
End Sub
ThisWorkbookモジュールに正しく記述するための手順
' ========================================
' VBAエディタでThisWorkbookモジュールを開く手順
' ========================================
'
' 1. Alt + F11 でVBAエディタを開く
'
' 2. 左ペイン(プロジェクトエクスプローラー)を確認する
' ※ 表示されていなければ Ctrl + R で表示
'
' 3. プロジェクトツリーの中の「Microsoft Excel Objects」を展開する
'
' 4.「ThisWorkbook」をダブルクリックして開く
' ※「Sheet1」「Sheet2」などは"シートモジュール"であり別物
'
' 5. コードウィンドウ上部の2つのドロップダウンを確認する
' 左側:「Workbook」を選択
' 右側:「Open」を選択
' → 自動的に Private Sub Workbook_Open() / End Sub の枠が挿入される
'
' 6. その中に処理を書く
Private Sub Workbook_Open()
' ここに処理を書く
Call InitializeApp
End Sub
シートモジュールに誤って書いてしまうケース
' ========================================
' ✗ よくある誤り:シートモジュール(Sheet1など)に書いてしまう
' ========================================
'
' VBAエディタ左ペインで「Sheet1」をダブルクリックして開いたモジュールに
' Workbook_Open を書いても、これはシートオブジェクトのモジュールであり、
' Workbookのイベントとして認識されないため自動実行されない。
' Sheet1モジュールに書いた場合(動かない)
Private Sub Workbook_Open() ' ← ThisWorkbookでないため無効
MsgBox "シートモジュールでは動きません"
End Sub
' ✓ 正しい場所:ThisWorkbookモジュールに書く
' (上記の手順でThisWorkbookを開いてから記述する)
原因4:Auto_Openの記述場所・名前が間違っている
Auto_Open は Workbook_Open とは逆で、必ず標準モジュールに記述します。ThisWorkbookモジュールや シートモジュールに書いても動きません。また、プロシージャ名のスペルが完全一致していることが必須です。
' ========================================
' Auto_Openの正しい書き方(標準モジュールに記述)
' ========================================
' ✓ 正しい:標準モジュール(Module1など)に書く
Sub Auto_Open() ' ← スペル・大文字小文字・アンダースコアに注意
MsgBox "Auto_Openが実行されました"
End Sub
' ========================================
' Auto_Openが動かない典型的なスペルミス
' ========================================
' ✗ 以下はすべて動かない(名前が違うため)
Sub AutoOpen() ' アンダースコアがない
MsgBox "動きません"
End Sub
Sub Auto_open() ' 小文字の "o"(Excelは区別しないが混乱の元)
MsgBox "動きますが、可読性が下がる"
End Sub
Sub auto_open() ' すべて小文字(動作はするが非推奨)
MsgBox "動きますが、非推奨"
End Sub
Auto_Open と Workbook_Open を両方書いた場合:両方が存在すると、Workbook_Open が先に実行され、その後 Auto_Open が実行されます。同じ処理が2回実行されないよう注意してください。通常はどちらか一方だけを使います。
' ========================================
' Auto_OpenとWorkbook_Openが両方ある場合の実行順序を確認する
' ========================================
' --- ThisWorkbook モジュール ---
Private Sub Workbook_Open()
Debug.Print "1. Workbook_Open が実行された: " & Format(Now(), "HH:mm:ss")
' ← こちらが先に実行される
End Sub
' --- 標準モジュール ---
Sub Auto_Open()
Debug.Print "2. Auto_Open が実行された: " & Format(Now(), "HH:mm:ss")
' ← こちらが後から実行される
End Sub
' イミディエイトウィンドウ出力例:
' 1. Workbook_Open が実行された: 10:00:01
' 2. Auto_Open が実行された: 10:00:01
原因5:アドインとして開かれているときの挙動の違い
ブックを .xlam(アドイン形式)として保存・登録した場合、Workbook_Open は実行されますが、動作に特有の注意点があります。また、ThisWorkbook.IsAddin プロパティの値によって挙動が変わる場合があります。
' ========================================
' アドインとして動作しているかを確認する
' ========================================
Sub CheckIsAddin()
If ThisWorkbook.IsAddin Then
Debug.Print "このブックはアドインとして動作しています。"
Debug.Print "シートはExcel上から非表示になっています。"
Else
Debug.Print "このブックは通常のブックとして動作しています。"
End If
End Sub
' ========================================
' アドインでのWorkbook_Open 実装例
' ========================================
' --- ThisWorkbook モジュール ---
Private Sub Workbook_Open()
' アドインの場合、シートへのアクセスはThisWorkbook.Sheets経由で行う
' Application.ActiveSheet などは使えない場合がある
If ThisWorkbook.IsAddin Then
' アドインとして読み込まれたときの初期化
Call RegisterCustomMenu ' カスタムメニューの登録など
Debug.Print "アドインが読み込まれました: " & ThisWorkbook.Name
Else
' 通常ブックとして開かれたときの処理
Call InitializeWorkbook
End If
End Sub
' アドインが閉じられるときの後処理
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If ThisWorkbook.IsAddin Then
Call UnregisterCustomMenu ' メニューの登録解除
End If
End Sub
原因6:ブックの保護・シートの保護によってマクロが止まる
Workbook_Open 自体は実行されていても、その中でシートを操作するコードがエラーで止まっているケースがあります。ブックの保護やシートの保護が有効になっていると、セルへの書き込みや構造変更の操作がエラーになります。
' ========================================
' 保護の状態を確認してから操作するパターン
' ========================================
Private Sub Workbook_Open()
Dim ws As Worksheet
On Error GoTo ErrorHandler
' --- ブックの保護を確認 ---
If ThisWorkbook.ProtectStructure Then
Debug.Print "ブックの構造が保護されています。シートの追加・削除はできません。"
' 必要なら解除する(パスワードが必要な場合がある)
' ThisWorkbook.Unprotect Password:="パスワード"
End If
' --- 各シートの保護を確認してから書き込む ---
Set ws = ThisWorkbook.Sheets("ログ")
If ws.ProtectContents Then
' シートが保護されている場合は一時解除してから書き込む
ws.Unprotect Password:="pass" ' パスワードがある場合
ws.Cells(1, 1).Value = Now()
ws.Protect Password:="pass" ' 書き込み後に再度保護
Else
ws.Cells(1, 1).Value = Now()
End If
GoTo CleanUp
ErrorHandler:
MsgBox "Workbook_Open中にエラーが発生しました。" & vbCrLf & _
"エラー " & Err.Number & ": " & Err.Description, vbCritical
CleanUp:
Set ws = Nothing
End Sub
' ========================================
' 保護の状態を一覧表示する診断用プロシージャ
' ========================================
Sub DiagnoseProtection()
Dim ws As Worksheet
Dim msg As String
msg = "【ブック保護の状態】" & vbCrLf
msg = msg & "構造の保護: " & ThisWorkbook.ProtectStructure & vbCrLf
msg = msg & "ウィンドウの保護: " & ThisWorkbook.ProtectWindows & vbCrLf & vbCrLf
msg = msg & "【各シートの保護状態】" & vbCrLf
For Each ws In ThisWorkbook.Sheets
msg = msg & ws.Name & ": "
If ws.ProtectContents Then
msg = msg & "保護あり"
Else
msg = msg & "保護なし"
End If
msg = msg & vbCrLf
Next ws
MsgBox msg, vbInformation, "保護の診断結果"
Set ws = Nothing
End Sub
原因7:Workbooks.Openで開いたときにAuto_Openが動かない
VBAのコードから Workbooks.Open でファイルを開いた場合、Auto_Open は実行されません。一方 Workbook_Open は実行されます。これはExcelの仕様です。また、Workbooks.Open に渡すオプションによっては Workbook_Open も意図的に無効化できます。
' ========================================
' Workbooks.Openの各オプションと自動実行マクロへの影響
' ========================================
Sub OpenFileSamples()
Dim filePath As String
filePath = "C:\Users\user\Documents\sample.xlsm"
' ---- パターン1:通常の開き方(Workbook_Openは実行される)----
Workbooks.Open Filename:=filePath
' → Workbook_Open: 実行される
' → Auto_Open: 実行されない(Workbooks.Open経由の制限)
' ---- パターン2:マクロ実行を完全に無効にして開く ----
' Application.AutomationSecurityを一時的に変更する
Dim prevSecurity As MsoAutomationSecurity
prevSecurity = Application.AutomationSecurity
Application.AutomationSecurity = msoAutomationSecurityForceDisable
Workbooks.Open Filename:=filePath ' Workbook_Openも実行されない
Application.AutomationSecurity = prevSecurity ' 設定を元に戻す必須!
Debug.Print "マクロ無効で開きました(Workbook_Openも実行されません)"
' ---- パターン3:Workbooks.OpenでAuto_Openを手動で呼ぶ ----
Dim wb As Workbook
Set wb = Workbooks.Open(Filename:=filePath)
' Auto_Openが必要な場合は手動で呼ぶ
Application.Run "'" & wb.Name & "'!Auto_Open"
Set wb = Nothing
End Sub
' ========================================
' Workbooks.Openで開いた後にWorkbook_Openを強制的に実行する
' ========================================
Sub ForceRunWorkbookOpen()
Dim wb As Workbook
Dim filePath As String
filePath = "C:\Users\user\Documents\target.xlsm"
' マクロ無効で開いた後(バッチ処理などで使う)
Application.AutomationSecurity = msoAutomationSecurityForceDisable
Set wb = Workbooks.Open(Filename:=filePath)
Application.AutomationSecurity = msoAutomationSecurityByUI
' Workbook_Openに相当する処理を手動で呼ぶ
Application.Run "'" & wb.Name & "'!Module1.InitializeApp"
Set wb = Nothing
End Sub
自動実行されない原因を切り分けるデバッグ手順
「動かない」と感じたときに、原因を素早く特定するための手順を解説します。上から順に確認していくことで、大半のケースで原因を特定できます。
手順1:マクロが有効になっているか確認する
' ========================================
' 手順1:マクロが有効かをVBAエディタで確認する
' ========================================
'
' ファイルを開いたときに以下のどちらかが起きていないか確認する:
'
' A) 黄色い警告バーが表示されている
' → 「コンテンツの有効化」をクリックしていないとマクロは動かない
'
' B) VBAエディタ(Alt + F11)が開けない
' → マクロが完全にブロックされている可能性がある
'
' → 解決策: ファイルを信頼済みの場所に移動するか、
' セキュリティセンターの設定を変更する
' この確認用マクロを手動で実行できれば、マクロ自体は有効になっている
Sub Step1_CheckMacroEnabled()
MsgBox "マクロは有効です。自動実行の設定に問題があります。", vbInformation
End Sub
手順2:ファイル形式と記述場所を確認する
' ========================================
' 手順2:設定の総合診断を行う
' ========================================
Sub DiagnoseAutoRunSetup()
Dim msg As String
Dim hasOK As Boolean
Dim hasNG As Boolean
msg = "【自動実行マクロの診断結果】" & vbCrLf & vbCrLf
hasOK = True
' --- ファイル形式チェック ---
msg = msg & "■ ファイル形式: "
Select Case ThisWorkbook.FileFormat
Case xlOpenXMLWorkbookMacroEnabled, xlExcel8, xlOpenXMLTemplateMacroEnabled
msg = msg & "✓ マクロを保存できる形式(" & ThisWorkbook.Name & ")" & vbCrLf
Case Else
msg = msg & "✗ .xlsx などマクロ非対応形式です。.xlsm で保存し直してください。" & vbCrLf
hasOK = False
End Select
' --- Workbook_Open の存在チェック ---
msg = msg & vbCrLf & "■ Workbook_Open の確認:" & vbCrLf
Dim vbComp As Object
Dim vbMod As Object
Dim found As Boolean
found = False
For Each vbComp In ThisWorkbook.VBProject.VBComponents
If vbComp.Name = "ThisWorkbook" Then
Set vbMod = vbComp.CodeModule
Dim lineCount As Long
lineCount = vbMod.CountOfLines
Dim lineText As String
Dim j As Long
For j = 1 To lineCount
lineText = vbMod.Lines(j, 1)
If InStr(lineText, "Workbook_Open") > 0 And _
InStr(lineText, "Sub") > 0 Then
found = True
Exit For
End If
Next j
End If
Next vbComp
If found Then
msg = msg & " ✓ ThisWorkbookモジュールにWorkbook_Openが見つかりました。" & vbCrLf
Else
msg = msg & " △ ThisWorkbookモジュールにWorkbook_Openが見つかりません。" & vbCrLf
msg = msg & " 標準モジュールに書いている場合はAuto_Openを確認してください。" & vbCrLf
End If
' --- 信頼済み場所チェック ---
msg = msg & vbCrLf & "■ 信頼済み場所: "
Dim tl As TrustedLocation
Dim tlOK As Boolean
tlOK = False
On Error Resume Next
Dim k As Long
For k = 1 To Application.TrustCenter.TrustedLocations.Count
Set tl = Application.TrustCenter.TrustedLocations(k)
If InStr(1, ThisWorkbook.Path, tl.Path, vbTextCompare) > 0 Then
tlOK = True
Exit For
End If
Next k
On Error GoTo 0
If tlOK Then
msg = msg & "✓ 信頼済みの場所に保存されています。" & vbCrLf
Else
msg = msg & "△ 信頼済みの場所に未登録です。警告バーが表示される可能性があります。" & vbCrLf
End If
MsgBox msg, vbInformation, "診断結果"
Set tl = Nothing
Set vbMod = Nothing
End Sub
手順3:Workbook_Openを手動で実行して動作確認する
' ========================================
' 手順3:Workbook_Openを手動で呼び出して動作確認する
' ========================================
'
' VBAエディタでThisWorkbookモジュールを開き、
' Workbook_Open の中にカーソルを置いてF5キーで手動実行する。
'
' → 手動実行で動く場合:自動実行の設定(セキュリティ・形式・場所)に問題がある
' → 手動実行でもエラーが出る場合:コードそのものに問題がある
' コードから手動で呼び出す場合
Sub ManuallyCallWorkbookOpen()
' ThisWorkbookのWorkbook_Openイベントを直接呼び出す
Call ThisWorkbook.Workbook_Open_Test ' Publicにした場合
' または Application.Run を使う
Application.Run "ThisWorkbook.Workbook_Open"
End Sub
' ========================================
' Workbook_Open内でOn Error GoToを必ず使い、
' エラーが起きてもメッセージが出るようにする
' ========================================
Private Sub Workbook_Open()
On Error GoTo ErrorHandler ' ← これがないと黙って止まる
' メイン処理
Call InitializeWorkbook
Exit Sub
ErrorHandler:
' エラーメッセージを必ず表示する
MsgBox "Workbook_Open でエラーが発生しました。" & vbCrLf & vbCrLf & _
"エラー番号: " & Err.Number & vbCrLf & _
"内 容: " & Err.Description, vbCritical, "自動実行エラー"
End Sub
自動実行マクロの正しい書き方とベストプラクティス
「動けばいい」ではなく、保守しやすく・トラブルが起きにくい自動実行マクロの書き方を解説します。
ベストプラクティス1:Workbook_Openは薄く保ち、処理は別プロシージャに委譲する
' ========================================
' Workbook_Open は「呼び出し口」だけにして
' 実際の処理は別プロシージャに書く
' ========================================
' --- ThisWorkbook モジュール ---
Private Sub Workbook_Open()
On Error GoTo ErrorHandler
' 処理本体は標準モジュールの関数に委譲する
' → テスト・再実行・保守がしやすくなる
modInitialize.InitializeApp
Exit Sub
ErrorHandler:
MsgBox "起動時の初期化処理でエラーが発生しました。" & vbCrLf & vbCrLf & _
"エラー " & Err.Number & ": " & Err.Description, vbCritical
End Sub
' --- 標準モジュール(modInitialize)---
Public Sub InitializeApp()
On Error GoTo ErrorHandler
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' === 初期化処理 ===
' 1. 必須シートの存在確認
Call CheckRequiredSheets
' 2. メニューシートをアクティブにする
Sheets("メニュー").Activate
' 3. 起動日時をログに記録する
Call LogStartup
' 4. ユーザー名を表示
Sheets("メニュー").Range("B2").Value = Environ("USERNAME")
Sheets("メニュー").Range("B3").Value = Format(Now(), "yyyy/mm/dd HH:mm")
' =================
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Exit Sub
ErrorHandler:
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
MsgBox "InitializeApp でエラーが発生しました: " & Err.Description, vbCritical
End Sub
' 必須シートの存在確認
Private Sub CheckRequiredSheets()
Dim requiredSheets As Variant
Dim i As Long
Dim missing As String
Dim ws As Worksheet
requiredSheets = Array("メニュー", "データ入力", "集計", "ログ")
missing = ""
For i = 0 To UBound(requiredSheets)
On Error Resume Next
Set ws = ThisWorkbook.Sheets(requiredSheets(i))
On Error GoTo 0
If ws Is Nothing Then
missing = missing & "・" & requiredSheets(i) & vbCrLf
End If
Set ws = Nothing
Next i
If Len(missing) > 0 Then
MsgBox "以下のシートが見つかりません:" & vbCrLf & missing & vbCrLf & _
"ブックの構成を確認してください。", vbCritical
' 必要に応じてここで処理を中断させる
End If
End Sub
' 起動ログの記録
Private Sub LogStartup()
Dim wsLog As Worksheet
On Error Resume Next
Set wsLog = ThisWorkbook.Sheets("ログ")
On Error GoTo 0
If wsLog Is Nothing Then Exit Sub
Dim nextRow As Long
nextRow = wsLog.Cells(wsLog.Rows.Count, 1).End(xlUp).Row + 1
wsLog.Cells(nextRow, 1).Value = Format(Now(), "yyyy/mm/dd HH:mm:ss")
wsLog.Cells(nextRow, 2).Value = Environ("USERNAME")
wsLog.Cells(nextRow, 3).Value = "起動"
Set wsLog = Nothing
End Sub
ベストプラクティス2:Workbook_BeforeCloseも合わせて実装する
' ========================================
' 開くときと閉じるときをセットで実装する
' ========================================
' --- ThisWorkbook モジュール ---
Private Sub Workbook_Open()
On Error GoTo ErrorHandler
modInitialize.InitializeApp
Exit Sub
ErrorHandler:
MsgBox "起動エラー: " & Err.Description, vbCritical
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
On Error GoTo ErrorHandler
' 未保存の変更があれば確認する
If ThisWorkbook.Saved = False Then
Dim answer As Long
answer = MsgBox("変更が保存されていません。保存してから閉じますか?", _
vbYesNoCancel + vbQuestion)
Select Case answer
Case vbYes : ThisWorkbook.Save
Case vbNo ' 保存せず閉じる(何もしない)
Case vbCancel : Cancel = True : Exit Sub ' キャンセル
End Select
End If
' 終了ログの記録
Call modInitialize.LogShutdown
Exit Sub
ErrorHandler:
MsgBox "終了処理でエラーが発生しました: " & Err.Description, vbCritical
End Sub
ベストプラクティス3:Application.AutomationSecurityをリセットし忘れない
' ========================================
' Workbooks.Open でマクロ無効化する場合は
' 必ず元の設定に戻す
' ========================================
Sub SafeOpenWithoutMacros()
Dim filePath As String
Dim prevSecurity As MsoAutomationSecurity
Dim wb As Workbook
filePath = "C:\data\target.xlsm"
' 現在の設定を保存
prevSecurity = Application.AutomationSecurity
On Error GoTo ErrorHandler
' マクロを無効にして開く
Application.AutomationSecurity = msoAutomationSecurityForceDisable
Set wb = Workbooks.Open(Filename:=filePath)
' 何らかの処理
Debug.Print wb.Name & " を開きました(マクロ無効)"
GoTo CleanUp
ErrorHandler:
MsgBox "ファイルを開く際にエラーが発生しました: " & Err.Description, vbCritical
CleanUp:
' ← 必ずここで元の設定に戻す(エラー時も実行される)
Application.AutomationSecurity = prevSecurity
Set wb = Nothing
End Sub
Auto_Open / Workbook_Open チェックリスト
自動実行マクロが動かないときや、新しく実装するときに以下のリストで確認してください。
- ファイルを開いたときに黄色い警告バーが表示されていないか(表示されている場合は「コンテンツの有効化」が必要)
- ブックのファイル形式が .xlsm または .xlsb または .xls になっているか(.xlsxではマクロが保存・実行されない)
Workbook_Openを使う場合、必ずThisWorkbookモジュールに記述されているか(標準モジュール・シートモジュールでは動かない)Auto_Openを使う場合、必ず標準モジュールに記述されているか(ThisWorkbookモジュールでは動かない)Auto_Openのプロシージャ名にスペルミス・アンダースコアの漏れがないかWorkbook_OpenとAuto_Openを両方書いていないか(両方ある場合は処理が2回実行される)Workbooks.Openでファイルを開いている場合、Auto_Openは動かないことを理解しているかApplication.AutomationSecurity = msoAutomationSecurityForceDisableがリセットされずに残っていないか- ブックやシートに保護がかかっており、
Workbook_Open内の操作がエラーになっていないか Workbook_Open内にOn Error GoTo ErrorHandlerがあり、エラーが黙って止まらないようになっているか- 手動で
Workbook_OpenまたはInitializeAppをF5で実行して動作確認したか - ファイルが信頼済みの場所に保存されているか(毎回「コンテンツの有効化」が必要な場合は未登録の可能性がある)
まとめ
Excelマクロの自動実行が動かない原因は、「マクロが無効」という単純なものから、「記述場所の誤り」「ファイル形式の誤り」「Workbooks.Open の仕様」まで多岐にわたります。本記事の要点をまとめます。
- Workbook_Open はThisWorkbookモジュールに、Auto_Openは標準モジュールに記述する。場所が違うと絶対に自動実行されない
- ファイルは .xlsm 形式で保存する。.xlsx のままではマクロが保存されず、自動実行もできない
- セキュリティ警告バーが出ている場合は「コンテンツの有効化」が必要。毎回必要になる場合は信頼済みの場所への登録を検討する
- Workbooks.Open で開いた場合、Auto_Open は実行されない。Workbook_Open は実行されるが、
AutomationSecurityの設定によっては無効化される - Workbook_Open 内には必ず On Error GoTo ErrorHandler を書く。エラーが黙って止まると「動いていない」と誤認しやすい
- Workbook_Open は薄く保ち、処理は標準モジュールに委譲する。これにより手動でのテスト・再実行・保守が格段に楽になる
- 切り分けは「手動で Workbook_Open を実行して動くか」から始める。手動で動けば設定の問題、手動でもエラーならコードの問題と判断できる
「ファイルを開いてもマクロが動かない」という状況は、このチェックリストに沿って確認すれば必ず原因を特定できます。そして再発防止のために、Workbook_Open を正しい場所に配置し、エラーハンドラを組み込み、ファイルを適切な場所に保存する習慣をつけることが根本的な解決策です。