Excel VBAでブックを静かに開く安全な方法
Excel VBAで複数のブックを順番に処理すると、次のような確認画面でマクロが止まることがあります。
- 外部リンクを更新するか
- 読み取り専用を推奨するか
- 保存せず閉じてよいか
- 開いたブックのイベントやマクロを実行するか
ただし、Application.DisplayAlerts = Falseだけで「すべての警告を消す」のは安全ではありません。Excelが既定の回答を自動選択するため、意図せず上書きする可能性もあります。
この記事では、リンク更新・イベント・マクロ・画面更新を分けて制御し、エラーが起きてもExcelの設定を元に戻す方法をまとめます。
まず知っておきたい4つの設定
| 設定 | 役割 | 注意点 |
|---|---|---|
Application.DisplayAlerts |
通常の確認メッセージを抑制する | セキュリティ警告には効かない。Excelが既定の回答を選ぶ |
Application.EnableEvents |
Workbook_Openなどのイベントを止める |
処理後に必ず元の値へ戻す |
Application.ScreenUpdating |
画面の再描画を止める | 警告やマクロを止める機能ではない |
Application.AutomationSecurity |
VBAから開くファイルのマクロ実行を制御する | 開く直前に設定し、直後に元へ戻す |
それぞれ目的が違います。特に、ScreenUpdating = Falseは画面のちらつき軽減と高速化のための設定で、警告抑制にはなりません。
実務向けのサンプル
次のコードは、対象ブックを「リンクを更新せず、読み取り専用で、マクロとイベントを動かさず」に開きます。
Option Explicit
Public Sub ProcessWorkbookQuietly()
Dim targetPath As String
Dim wb As Workbook
' Excel全体に影響する設定なので、変更前の値を保存する
Dim oldDisplayAlerts As Boolean
Dim oldEnableEvents As Boolean
Dim oldScreenUpdating As Boolean
Dim oldAutomationSecurity As MsoAutomationSecurity
Dim errorNumber As Long
Dim errorSource As String
Dim errorDescription As String
targetPath = "C:\work\sample.xlsx"
If Len(Dir$(targetPath)) = 0 Then
Err.Raise vbObjectError + 1000, , _
"ファイルが見つかりません: " & targetPath
End If
oldDisplayAlerts = Application.DisplayAlerts
oldEnableEvents = Application.EnableEvents
oldScreenUpdating = Application.ScreenUpdating
oldAutomationSecurity = Application.AutomationSecurity
On Error GoTo ErrorHandler
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
' VBAから開くファイルのマクロを無効化する
Application.AutomationSecurity = msoAutomationSecurityForceDisable
Set wb = Workbooks.Open( _
Filename:=targetPath, _
UpdateLinks:=0, _
ReadOnly:=True, _
IgnoreReadOnlyRecommended:=True, _
AddToMru:=False)
' セキュリティ設定の影響範囲を短くするため、開いた直後に戻す
Application.AutomationSecurity = oldAutomationSecurity
' ここにブックごとの処理を書く
Debug.Print wb.Worksheets(1).Range("A1").Value
wb.Close SaveChanges:=False
Set wb = Nothing
CleanUp:
Application.AutomationSecurity = oldAutomationSecurity
Application.ScreenUpdating = oldScreenUpdating
Application.EnableEvents = oldEnableEvents
Application.DisplayAlerts = oldDisplayAlerts
If errorNumber <> 0 Then
Err.Raise errorNumber, errorSource, errorDescription
End If
Exit Sub
ErrorHandler:
errorNumber = Err.Number
errorSource = Err.Source
errorDescription = Err.Description
On Error Resume Next
If Not wb Is Nothing Then
wb.Close SaveChanges:=False
End If
On Error GoTo 0
GoTo CleanUp
End Sub
コードのポイント
1. Workbook型で受け取る
Workbooks.Openの戻り値はWorkbookです。
Dim wb As Workbook
Set wb = Workbooks.Open(Filename:=targetPath)
Worksheetでは受け取れません。開いたブックを変数に入れておけば、ActiveWorkbookに依存せず、安全に操作して閉じられます。
2. Dir$には変数をそのまま渡す
If Len(Dir$(targetPath)) = 0 Then
' ファイルが存在しない
End If
Dir$("targetPath")と書くと、変数の中身ではなく「targetPath」という名前のファイルを探してしまいます。
なお、フォルダーの存在確認にはvbDirectoryを指定します。
If Len(Dir$("C:\work", vbDirectory)) = 0 Then
MsgBox "フォルダーが見つかりません。"
End If
3. 外部リンクはUpdateLinks:=0で更新しない
Workbooks.OpenのUpdateLinksを省略すると、リンク更新を確認する画面が表示される場合があります。
Set wb = Workbooks.Open( _
Filename:=targetPath, _
UpdateLinks:=0)
現在のMicrosoft Learnでは、主に次の値が説明されています。
| 値 | 動作 |
|---|---|
0 |
外部参照を更新しない |
3 |
外部参照を更新する |
外部リンク先を信用できるか不明なファイルを自動処理する場合は、まず0で開くのが無難です。
4. イベント停止とマクロ無効化は別物
Application.EnableEvents = Falseは、Workbook_OpenやWorksheet_Changeなどのイベントを止めます。しかし、プログラムから開いたファイルのマクロ全般を安全に無効化する設定ではありません。
マクロを無効にして開く場合は、AutomationSecurityを使います。
Dim oldSecurity As MsoAutomationSecurity
oldSecurity = Application.AutomationSecurity
Application.AutomationSecurity = msoAutomationSecurityForceDisable
Set wb = Workbooks.Open(Filename:=targetPath, UpdateLinks:=0)
Application.AutomationSecurity = oldSecurity
Microsoft Learnでは、この設定をファイルを開く直前に変更し、開いた直後に戻すよう案内しています。
msoAutomationSecurityForceDisableでも、Excel 4.0マクロは無効化されません。該当ファイルでは確認画面が表示されることがあります。
5. DisplayAlerts = Falseは万能ではない
DisplayAlerts = Falseにすると、Excelは確認画面を表示せず、既定の回答を選びます。たとえば、保存先に同名ファイルがある状態でSaveAsすると、確認なしで上書きされるケースがあります。
そのため、次の方針がおすすめです。
- 必要な区間だけ
Falseにする - 上書き先の存在を事前確認する
- エラー時も変更前の値へ戻す
- セキュリティ警告は
AutomationSecurityで扱う
読み取り専用の確認を出さない
元ファイルを変更しない処理なら、ReadOnly:=Trueを明示します。
Set wb = Workbooks.Open( _
Filename:=targetPath, _
UpdateLinks:=0, _
ReadOnly:=True, _
IgnoreReadOnlyRecommended:=True)
-
ReadOnly:=True: 読み取り専用で開く -
IgnoreReadOnlyRecommended:=True: 「読み取り専用を推奨」の確認を表示しない -
AddToMru:=False: 最近使ったファイルへ追加しない
編集結果を保存する必要がある場合は、ReadOnly:=Falseにして、最後をwb.Close SaveChanges:=Trueへ変更します。上書き前にバックアップや保存先確認も入れてください。
設定は「Trueに戻す」ではなく「元の値に戻す」
別の処理が先にEnableEvents = Falseにしていた可能性があります。そのため、終了時に一律でTrueへ変更するより、開始時の値を保存して復元するほうが安全です。
また、エラー処理がないコードでは、途中で失敗したときにイベントや画面更新が無効のまま残ることがあります。サンプルではErrorHandlerから必ずCleanUpを通し、設定を復元しています。
それでも表示される可能性がある画面
「静かに開く」設定を組み合わせても、すべてのファイルを完全に無人で開けるとは限りません。
- パスワード入力
- 保護ビューやファイルブロック
- 破損ファイルの回復確認
- Excel 4.0マクロに関する確認
- アドインや外部データ接続に固有の画面
信頼できないファイルを扱う場合は、警告を消すことより、隔離した環境で開く・読み取り専用にする・マクロを無効化することを優先してください。
まとめ
-
Workbooks.OpenはWorkbook型で受け取る - リンクを更新しないなら
UpdateLinks:=0 -
EnableEventsとAutomationSecurityは役割が違う -
DisplayAlerts = Falseではセキュリティ警告を無効化できない - Excel全体の設定は、エラー時も変更前の値へ戻す
- 対象ブックだけを
wb.Closeで閉じる
大量処理では、ファイルを開くコードそのものより「失敗してもExcelの状態を壊さない後始末」が重要です。