VBAを書いていると、どうしても避けられないのが「エラーで止まる」問題です。
- 途中でエラーが出て処理が止まる
- 画面更新OFFのまま固まったように見える
- イベントOFFのまま別マクロが動かなくなる
- 原因が分からず、結局「動かないマクロ」になる
そこで重要になるのが On Error(エラーが出たときの動き方を決める命令)です。
この記事では、初心者でも使える「安全に止まる」「必ず後片付けする」ための実践テンプレをまとめます。
結論:安全なVBAは「Finally(後片付け)」を必ず作る
VBAで安全に処理する最大のコツはこれです。
- 処理前に設定変更したら(画面更新OFFなど)
- 処理が成功しても失敗しても
- 必ず元に戻す
この「必ず戻す場所」をこの記事では Finally(ファイナリー) と呼びます。
(プログラミングでよく使われる言い方で、“最後に必ずやる処理”の意味です)
On Errorの基本(この3つを覚えればOK)
① On Error GoTo ラベル(おすすめ)
エラーが起きたら、指定した場所にジャンプします。
On Error GoTo ErrHandler
② On Error Resume Next(注意して使う)
エラーが起きても止まらず、次の行へ進みます。
On Error Resume Next
便利ですが、バグを見逃しやすいので「存在チェック」など限定用途で使うのが安全です。
③ On Error GoTo 0(エラー処理を解除)
エラー処理を通常状態に戻します。
On Error GoTo 0
【最重要】安全テンプレ:成功しても失敗しても「必ず元に戻す」
まずはこれをテンプレとして保存してください。
画面更新・自動計算・イベントなどを触るマクロの事故(戻し忘れ)を防げます。
Option Explicit
Sub SafeTemplate()
Dim prevCalc As XlCalculation
Dim prevScreen As Boolean
Dim prevEvents As Boolean
On Error GoTo Finally
' 現在設定を退避(元に戻すため)
prevCalc = Application.Calculation
prevScreen = Application.ScreenUpdating
prevEvents = Application.EnableEvents
' 高速化などの設定変更
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
' ===== ここにメイン処理を書く =====
' 例:大量のセル更新、ファイル処理、集計など
' ================================
Finally:
' 必ず元に戻す(ここが一番重要)
Application.ScreenUpdating = prevScreen
Application.Calculation = prevCalc
Application.EnableEvents = prevEvents
' エラーがあれば通知(エラーがないときは何もしない)
If Err.Number <> 0 Then
MsgBox "エラーが発生しました。" & vbCrLf & _
"番号:" & Err.Number & vbCrLf & _
"内容:" & Err.Description, vbExclamation
End If
End Sub
ポイント
- エラーが出ても
Finally:に必ず来る - その結果、ScreenUpdatingなどが「戻らない事故」を防げる
Err.Numberを見て、エラー時だけMsgBox表示できる
実践1:シートが無いときに落ちない(SheetExistsの作り方)
シート名が違っているだけで、実行時エラー9(インデックスが有効範囲にありません)になります。
そのため、事前に「存在チェック」を入れるのが安全です。
Option Explicit
Function SheetExists(ByVal sheetName As String, Optional ByVal wb As Workbook) As Boolean
Dim ws As Worksheet
If wb Is Nothing Then Set wb = ThisWorkbook
On Error Resume Next
Set ws = wb.Worksheets(sheetName)
On Error GoTo 0
SheetExists = Not (ws Is Nothing)
End Function
使い方
Sub Sample_SheetCheck()
If SheetExists("集計") = False Then
MsgBox "「集計」シートが見つかりません。", vbExclamation
Exit Sub
End If
Worksheets("集計").Range("A1").Value = "OK"
End Sub
ここで On Error Resume Next を使う理由
存在しないシートを参照した瞬間にエラーが出ますが、存在チェックの場面では「エラーを無視して判定」したいからです。
ただし、使う範囲はこのように狭く限定するのがポイントです。
実践2:Findで見つからなくても落ちない(Nothingチェック)
Findは見つからないと Nothing を返します。
そのまま .Row などを使うと実行時エラーになります。
Sub Sample_FindSafe()
Dim c As Range
Set c = Range("A:A").Find(What:="東京", LookIn:=xlValues, LookAt:=xlPart)
If c Is Nothing Then
MsgBox "「東京」が見つかりませんでした。", vbInformation
Exit Sub
End If
MsgBox "見つかった行:" & c.Row, vbInformation
End Sub
実践3:ファイルが無いときに落ちない(Dirで事前チェック)
ファイルを開く処理は、パス間違いで止まりがちです。
開く前に存在チェックすると安全です。
Sub Sample_FileCheck()
Dim path As String
path = "C:\temp\test.xlsx"
If Dir(path) = "" Then
MsgBox "ファイルが見つかりません:" & path, vbExclamation
Exit Sub
End If
Workbooks.Open path
End Sub
On Error Resume Next を「安全に使う」ルール
Resume Next は便利ですが、使い方を間違えるとエラーを見逃して原因不明になります。
安全に使うルールはシンプルです。
- 使う範囲を最小限にする(数行だけ)
- 使った直後に
On Error GoTo 0で戻す - 必要なら
Err.Numberを確認して分岐する
例:エラーが出たかどうかで分岐する
Sub Sample_CheckErrNumber()
On Error Resume Next
Dim ws As Worksheet
Set ws = Worksheets("存在しないシート")
If Err.Number <> 0 Then
' エラーが起きた
Err.Clear
On Error GoTo 0
MsgBox "シートが存在しません。", vbExclamation
Exit Sub
End If
On Error GoTo 0
MsgBox ws.Name
End Sub
よくある事故:EnableEventsやScreenUpdatingが戻らない
エラーで止まると、次の状態になりやすいです。
- 画面が更新されない(ScreenUpdating=Falseのまま)
- 数式が更新されない(Calculation=Manualのまま)
- イベントが動かない(EnableEvents=Falseのまま)
だからこそ、この記事で紹介した「Finallyテンプレ」で
成功・失敗に関係なく元に戻すのが最重要です。
まとめ:On Errorは「握りつぶす」ではなく「安全に終わらせる」ために使う
- 基本は On Error GoTo で「後片付け(Finally)」へ
- Resume Next は存在チェックなど限定用途で
- 設定変更したら「必ず元に戻す」を習慣化
- エラー内容(Err.Number / Err.Description)を出すと原因特定が速い
この考え方を身につけるだけで、VBAは一気に「止まらない」「事故らない」マクロになります。
ぜひテンプレとして保存して、すべてのマクロに使ってみてください。


コメント