VBAのエラー処理が効かない4つの原因|On Errorを書いてもマクロが止まる

スポンサーリンク

「実行時エラー ‘1004’」のダイアログが出て、Excel のマクロが途中で止まる。慌てて On Error Resume Next を1行貼ったら、今度は何も処理されない空振りマクロになった。VBA でエラー処理を覚えるとき、この2つはほぼ全員が通る失敗です。

厄介なのは、エラー処理(エラーハンドリング)を書いた「後」の状態なんです。何も書いていないマクロなら「まだ守っていない」と自覚できます。

でも一度書いてしまうと、守れているつもりで配布できてしまいますよね。事故に気づくのが数ヶ月遅れることもあります。

落ちた後の Excel が変な状態で残るケースも多いです。画面が更新されない、自動計算が手動のまま、シートを触ってもイベントが動かない。原因はエラーではなく、後始末を書いていないことにあります。

この記事では、VBA のエラーハンドリングを2本立てで整理しました。前半は On Error の書き分けを決定表1つに圧縮。

後半は「書いたのに効かない4つの落とし穴」と、落とさず終わらせる実務パターン5選を紹介します。そのままコピーして自分のマクロに貼れる形にしてありますよ。

  1. VBAのOn Errorは3つだけ|1分で決まる書き分け決定表
    1. On Error GoTo / Resume Next / GoTo 0 の役割を1行ずつ
    2. 【決定表】止める・続ける・そもそも起こさせない の3択で選ぶ
    3. Exit Sub とセットにする最小テンプレート
    4. Err.Number・Err.Description で「何が起きたか」を受け取る
  2. エラー処理を書いたのに効かない・空振りする4つの落とし穴
    1. 【落とし穴1】VBEの「エラー トラップ」設定が On Error より優先されることがある
    2. 【落とし穴2】Exit Sub 忘れで、正常時までエラーメッセージが出る
    3. 【落とし穴3】On Error GoTo 0 の解除漏れと「ハンドラ処理中は二度目を拾えない」問題
    4. 【落とし穴4】Err.Clear 漏れでループの2件目以降が誤判定になる
  3. 落とさず終わらせる実務パターン5選
    1. 【パターン1】ファイルが無くても止めずに知らせる
    2. 【パターン2】シートの有無で分岐する(Resume Next を1行だけに閉じる)
    3. 【パターン3】ループ内で1件だけ飛ばして最後まで回す
    4. 【パターン4】途中で落ちても画面更新・自動計算を必ず元に戻す
    5. 【パターン5】エラー内容をログに残して後から追う
  4. よくある質問(FAQ)
    1. On Error GoTo を書いたのにエラーで止まります
    2. On Error Resume Next は絶対に使ってはいけないの?
    3. On Error GoTo 0 を書き忘れるとどうなりますか?
    4. 別の Sub を呼び出したとき、エラー処理は引き継がれますか?
    5. VBAに Try-Catch はありますか?
    6. エラー処理を入れるとマクロは遅くなりますか?
  5. まとめ

VBAのOn Errorは3つだけ|1分で決まる書き分け決定表

冒頭でも触れたとおり、VBA のエラー処理は「エラーハンドリング」とも呼ばれます。仰々しい響きですが、覚える構文は3つだけ。文法はここで打ち止めにして、記事の主役である落とし穴と実務パターンへ進みましょう。

On Error GoTo / Resume Next / GoTo 0 の役割を1行ずつ

構文やること
On Error GoTo ラベルエラーが起きたら、指定したラベルの行へ処理を飛ばす
On Error Resume Nextエラーが起きた行を飛ばして、次の行から実行を続ける
On Error GoTo 0いま有効になっているエラー処理を無効に戻す

ラベルというのは ErrHandler: のように、行の先頭に名前とコロンを書いた目印のこと。ジャンプ先の住所だと思ってください。ラベルから下に続く、エラー時だけ通る処理のかたまりが「エラーハンドラ」です。

On Error GoTo 00 は、行番号でもラベル名でもありません。「いま有効なエラー処理を無効に戻す」ための専用の書き方です。コードの中に 0: というラベルを用意する必要はありませんよ。

なお、これらが効く相手は実行時エラー(マクロを動かしている最中に発生するエラー)だけ。実行前の文法チェックで出るコンパイルエラーや、動くけれど結果が違う論理エラーは対象外です。

【決定表】止める・続ける・そもそも起こさせない の3択で選ぶ

やりたいことを3択に落とすと、選ぶ構文は自動的に決まります。

やりたいこと使う構文必ずセットで書くもの
エラーが出たら処理を止めて、原因を知らせたいOn Error GoTo ラベルExit Sub とラベル位置の処理
失敗しても構わない処理を、1〜2行だけ通したいOn Error Resume Next直後の On Error GoTo 0 と結果判定
そもそもエラーを起こさせたくない事前チェック(Dir / IsNumeric / Is NothingOption Explicit などの予防的な書き方

迷ったら3行目を先に検討してください。ファイルの有無やセルの中身は、事前にチェックすれば大半が弾けます。エラーを起こしてから拾うより、起こさせないほうがコードは短くなるんです。

変数の打ち間違いを予防するなら、【VBA】Option Explicitで変数の宣言を強制する方法もあわせてどうぞ。

Exit Sub とセットにする最小テンプレート

On Error GoTo を使うときの最小形がこれです。3つのブロックの並び順まで含めて、まるごと覚えてしまってください。

Sub SampleTemplate()
    On Error GoTo ErrHandler

    '--- ① 通常の処理をここに書く ---
    ThisWorkbook.Worksheets("Sheet1").Range("A1").Value = "OK"

    '--- ② 正常時はここで抜ける(これが無いと③に流れ込む) ---
    Exit Sub

ErrHandler:
    '--- ③ エラーが起きたときだけ通う場所 ---
    MsgBox "処理を中断しました" & vbCrLf & _
           "[" & Err.Number & "] " & Err.Description
End Sub

ポイントは②の Exit Sub。これが無いと、正常に終わったときも③のメッセージが出てしまいます。理由は【落とし穴2】で詳しく見ていきましょう。

ハンドラの中では、Resume 系の書き方で「どこから再開するか」も選べます。

書き方再開する場所主な用途
Exit Subプロシージャを抜けるエラー時は中止して終わらせる
Resumeエラーが起きた行原因を直してもう一度試す
Resume Nextエラーが起きた行の次その行だけ飛ばして続ける
Resume ラベル指定したラベル後始末の処理へ合流させる

プロシージャとは Sub 〜 End Sub で囲まれたひとかたまりの処理のこと。この単位が、後で出てくるスコープの話につながります。

Err.Number・Err.Description で「何が起きたか」を受け取る

エラーの中身は Err オブジェクトから取り出します。ハンドラの中で参照するのが基本の使い方です。

Sub ShowErrorInfo()
    On Error GoTo ErrHandler

    Dim n As Long
    n = CLng("abc")   '数値に変換できずエラーになる行

    Exit Sub

ErrHandler:
    MsgBox "番号: " & Err.Number & vbCrLf & _
           "内容: " & Err.Description & vbCrLf & _
           "発生元: " & Err.Source
End Sub

Err.Number がエラー番号、Err.Description が説明文です。Err.Source には発生元の名前が入ります。3つ並べて表示しておくと、利用者から状況を聞き取るときに話が早くなりますよ。

ひとつ注意点があります。Err が持っているのは直近1件の情報だけ。次のエラーが起きたり別のプロシージャを呼んだりすると上書きされます。

必要な値は変数に控えておきましょう。この作法は、後で紹介する【パターン5】のログ出力でも使います。

番号ごとの意味と直し方(実行時エラー13・1004・9・91・438など)は本記事では扱いません。姉妹記事のVBAマクロのエラー解決ガイドにまとめてあります。

NOTE

コードを書く場所は VBE(Visual Basic Editor)です。Excel で Alt + F11 を押して開き、「挿入 → 標準モジュール」を選んで貼り付けてください。各ウィンドウの役割はVBEの画面の見方を図解で解説にまとめています。保存はマクロ有効ブック(.xlsm)で。.xlsx のまま保存するとコードが消えてしまいます。

エラー処理を書いたのに効かない・空振りする4つの落とし穴

ここからが本題です。On Error は書いた瞬間に万能になる魔法ではありません。書き方や環境しだいで、効かなかったり、かえって被害を広げたりします。

現場で繰り返し見かける原因を4つに絞りました。「症状 → 確認 → 対処」の順に並べてあるので、いま困っている症状から読んでも大丈夫ですよ。

なお、エラーがどの行で起きているか特定できていない段階なら、先に原因の場所を突き止めましょう。手順はExcelマクロのVBAデバッグ方法で解説しています。

【落とし穴1】VBEの「エラー トラップ」設定が On Error より優先されることがある

まず疑ってほしいのが、コードではなく VBE 側の設定です。

症状: 同じコードなのに、自分の PC だけエラーの行で止まる。同僚の環境では On Error GoTo がちゃんと効いている。この「環境によって挙動が違う」というパターンが特徴です。

確認: VBE のメニューから「ツール → オプション」を開きます。「全般」タブに「エラー トラップ」という設定があるので、そこがどれになっているか見てください。この設定の選び方によっては、On Error を書いていてもエラーの行で中断することがあります。

対処: 設定を切り替えて同じマクロをもう一度実行し、挙動が変わるか比べてみましょう。変わるなら原因はコードではなく設定側です。自分で変えた覚えがなくても、過去のデバッグ作業の名残で切り替わっている場合があります。

対応バージョン: 本記事は Excel for Windows のデスクトップ版(Microsoft 365 / 2021 / 2019)を前提にしています。VBE の「ツール → オプション」にある項目名やタブ構成は、Excel のバージョンや言語環境で表示が異なることがあります。Mac 版の VBE はメニュー構成が異なり、Excel for the web では VBA 自体が動作しません。

そもそもマクロを実行しようとしてもブロックされる場合は、この設定とは別の問題です。Excelマクロが実行できない・ブロックされる5つの原因と対処法を先に確認してみてください。

【落とし穴2】Exit Sub 忘れで、正常時までエラーメッセージが出る

こちらは逆に、エラーが起きていないのにエラー扱いされるパターンです。

Sub BadExample_NoExitSub()
    On Error GoTo ErrHandler

    ThisWorkbook.Worksheets("Sheet1").Range("A1").Value = "OK"
    '--- ここに Exit Sub が無い ---

ErrHandler:
    MsgBox "エラー: " & Err.Description   '正常時にも表示されてしまう
End Sub

VBA はラベルを「壁」として扱いません。上から順に実行していき、ErrHandler: の行もただの目印として素通りします。正常に処理が終わっても、そのまま下のハンドラへ流れ込んでしまうわけです。

このとき Err.Description は空文字列なので、「エラー: 」という中身の無いメッセージだけが出ます。配布先から「よく分からないエラーが出る」と連絡が来る典型例。実際にはエラーは起きていません。

WARNING

On Error GoTo ラベル を書いたら、ハンドラの直前に必ず Exit Sub を置いてください。Function の中なら Exit Function です。この1行の有無で、正常時の挙動がまるごと変わります。

【落とし穴3】On Error GoTo 0 の解除漏れと「ハンドラ処理中は二度目を拾えない」問題

この落とし穴は2つの症状に分かれます。どちらも「書いたのに守られていない」状態を作ります。

解除漏れは、On Error Resume Next を張ったまま先へ進んでしまうケースです。

Sub Trap_GoTo0Missing()
    Dim ws As Worksheet

    On Error Resume Next
    Set ws = ThisWorkbook.Worksheets("売上データ")
    '--- ここに On Error GoTo 0 が無い ---

    ws.Range("A1").Value = 100      'ws が Nothing でもダイアログが出ない
    ThisWorkbook.Save               '保存に失敗しても気づけない
End Sub

シートの存在チェックのつもりで書いた1行が、Sub の最後まで効き続けています。以降はどこで何が失敗しても無言で通過。「エラーが出ないから動いている」と思い込んだまま、空のシートを出力し続けるマクロが出来上がります。

対処はシンプルで、試したい処理の直後に On Error GoTo 0 を書くだけ。囲む範囲は1〜2行に閉じてくださいね。

もうひとつは、ハンドラの処理中に起きた二度目のエラーを拾えない問題です。

Sub Trap_HandlerIsOneShot()
    On Error GoTo ErrHandler

    Worksheets("存在しないシートA").Activate   '① 1つ目のエラー

    Exit Sub

ErrHandler:
    '--- ハンドラの中で起きた2つ目のエラーは、このハンドラでは拾えない ---
    Worksheets("存在しないシートB").Activate   '② ここで止まる
    MsgBox "この行までは届きません"
End Sub

エラーハンドラは、①でジャンプしてきた時点から「処理中」の状態に入ります。この処理中の間は、同じプロシージャで発生した新しいエラーを受け取れません。②で止まるのはそのためです。

受け取れなかったエラーは、呼び出し元のプロシージャへ渡される仕組み。上の例のようにマクロを直接実行した場合は渡す先が無いので、未処理エラーのダイアログが出て止まります。

処理中が解けるのは、Resume 系のステートメントか Exit Sub などに到達したとき。裏を返せば、ハンドラの中で Resume を使って本流に戻せば、エラー処理は再び有効な状態に戻ります。

対処は2つです。ハンドラの中には落ちにくい処理だけを置くこと。ログ書き込みのように失敗しうる処理なら、その周りだけ On Error Resume Next で守ります。

スコープ(有効範囲)もここで押さえておきましょう。On Error GoTo で指定するラベルは、同じプロシージャの中に無ければコンパイルエラーになります。

エラー処理の有効範囲はプロシージャ単位。Sub を分けた瞬間、呼び出し先には呼び出し先のエラー処理が必要になります。

【落とし穴4】Err.Clear 漏れでループの2件目以降が誤判定になる

ループの中で On Error Resume NextErr.Number を組み合わせる。この書き方で非常によく起きるバグです。

Sub Trap_ErrClearMissing()
    Dim i As Long
    Dim n As Long

    On Error Resume Next
    For i = 2 To 10
        n = CLng(Cells(i, "A").Value)

        If Err.Number <> 0 Then
            Cells(i, "B").Value = "ERR"
            '--- Err.Clear が無いので、以降ずっと ERR 扱いになる ---
        Else
            Cells(i, "B").Value = n * 2
        End If
    Next i
    On Error GoTo 0
End Sub

Err は、次に上書きされるかクリアされるまで前の情報を持ち続けます。A列の3行目で1件エラーが出たとしましょう。すると4行目以降は正常な数値でも、Err.Number <> 0 が成立してしまいます。

結果として、B列は途中から全部「ERR」で埋まります。データ側は正常なのに出力だけがおかしい、という一番気づきにくい壊れ方ですよね。

対処は、判定した直後に Err.Clear を書くこと。1件ごとに情報をリセットしてから次の反復へ進めば、誤判定は起きません。

NOTE

Err がリセットされるタイミングは、公式の資料でも説明の粒度に幅があります。ハンドラ内の Exit SubResume Next でリセットされる、という記述があります。一方で On Error 文の実行そのものでリセットされる、という記述も存在します。ループの中で毎回 Err.Number を見る書き方なら、明示的な Err.Clear を入れておきましょう。安全側に倒す設計です。

落とさず終わらせる実務パターン5選

ここからは、そのままコピーして使えるパターンを5つ紹介します。共通のねらいは「落ちない」ではなく、落ちても後始末まで済ませて終わることです。

エラーをゼロにするのは現実的ではありません。他人が触ったブックを処理する以上、想定外はいつか起きます。だからこそ、起きた後の終わり方を設計しておきましょう。

【パターン1】ファイルが無くても止めずに知らせる

Workbooks.Open は、ファイルが無いときに実行時エラーで止まります。基本形は、事前チェックとハンドラの二重構え。

Sub Pattern1_FileNotFound()
    Const FILE_PATH As String = "C:reportssales.xlsx"
    Dim wb As Workbook

    '--- ① まず存在チェックで弾く ---
    If Dir(FILE_PATH) = "" Then
        MsgBox "ファイルが見つかりません: " & FILE_PATH
        Exit Sub
    End If

    '--- ② 開く処理はハンドラで守る ---
    On Error GoTo ErrHandler
    Set wb = Workbooks.Open(FILE_PATH)

    MsgBox "開きました: " & wb.Name
    wb.Close SaveChanges:=False

    Exit Sub

ErrHandler:
    MsgBox "ファイルを開けませんでした。" & vbCrLf & _
           "[" & Err.Number & "] " & Err.Description
End Sub

Dir の事前チェックだけでは足りません。ファイルが存在していても、他のユーザーが開いていたり権限が無かったりすると失敗するからです。だから②のハンドラを残してあります。

メッセージにはファイルのパスを入れておくのがおすすめ。共有フォルダの移動が原因だった、というケースを一発で切り分けられますよ。

【パターン2】シートの有無で分岐する(Resume Next を1行だけに閉じる)

シートの取得は On Error Resume Next の正当な使いどころです。ただし囲むのは1行だけにします。

Sub Pattern2_SheetNotFound()
    Dim ws As Worksheet

    '--- Resume Next で囲むのはこの1行だけ ---
    On Error Resume Next
    Set ws = ThisWorkbook.Worksheets("売上データ")
    On Error GoTo 0

    If ws Is Nothing Then
        MsgBox "シート『売上データ』が見つかりません。" & vbCrLf & _
               "シート名を確認してください。"
        Exit Sub
    End If

    ws.Range("A1").Value = "更新済み"
End Sub

Set に失敗すると wsNothing のまま残ります。だから結果の判定は Err.Number ではなく Is Nothing で行うのが素直。

3行のブロックで開いて閉じる。この形を守るかぎり、On Error Resume Next は危険な構文ではありません。

【パターン3】ループ内で1件だけ飛ばして最後まで回す

100件処理して1件だけ不正な値がある。そんなときに全体を止めないパターンです。

Sub Pattern3_SkipInLoop()
    Dim ws As Worksheet
    Dim i As Long, lastRow As Long
    Dim n As Long

    Set ws = ThisWorkbook.Worksheets("売上データ")
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

    For i = 2 To lastRow
        On Error Resume Next
        n = CLng(ws.Cells(i, "A").Value)

        If Err.Number = 0 Then
            ws.Cells(i, "B").Value = n * 2
        Else
            ws.Cells(i, "B").Value = "ERR"
            Err.Clear                  'ここを忘れると次の行も ERR になる
        End If
        On Error GoTo 0
    Next i

    MsgBox "処理が完了しました(" & (lastRow - 1) & "件)"
End Sub

1回の反復でやることは4つ。

  1. On Error Resume Next でエラー無視を開始する
  2. 変換を試す
  3. Err.Number で判定し、失敗なら Err.Clear でリセットする
  4. On Error GoTo 0 で解除して次の行へ進む

飛ばした行に「ERR」と印を残しておくのがコツです。後から目視で拾えますし、件数が多ければフィルターでも抽出できますよね。

【パターン4】途中で落ちても画面更新・自動計算を必ず元に戻す

処理を速くするために ScreenUpdatingCalculation を切る書き方は定番です。ところが途中でエラーが起きると、切ったまま Excel が残ってしまいます。

画面が更新されない、数式を編集しても再計算されない、シートを変更してもイベントマクロが動かない。ユーザーからは「Excel が壊れた」ように見えます。

これらの設定は、エラーで中断したときに自動で元へ戻るとは限りません。実務では戻らない前提で書きましょう。

Sub Pattern4_SafeCleanup()
    Dim prevCalc As XlCalculation
    prevCalc = Application.Calculation   '元の設定を控えておく

    On Error GoTo Cleanup

    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Application.Calculation = xlCalculationManual

    '--- ここに本来の重い処理を書く ---
    ThisWorkbook.Worksheets("集計").Range("A1").Value = "処理中"

Cleanup:
    '--- 正常時もエラー時も必ずここを通す ---
    Application.Calculation = prevCalc
    Application.EnableEvents = True
    Application.ScreenUpdating = True

    If Err.Number <> 0 Then
        MsgBox "処理を中断しました" & vbCrLf & _
               "[" & Err.Number & "] " & Err.Description
    End If
End Sub

このコードだけは、あえて Exit Sub を置いていません。正常に終わったときも Cleanup: を通したいからです。【落とし穴2】の意図的な例外だと理解してください。

その代わり、エラーの有無は Cleanup: の中で Err.Number を見て判定しています。この形なら、後始末は必ず1回だけ実行されます。

CalculationxlCalculationAutomatic で固定していない点もポイント。元の値を控えて戻すことで、手動計算で運用しているブックを勝手に変えてしまう事故を防げます。

後始末を入れる前のマクロが落ちて画面が固まったままなら、応急処置もありますよ。イミディエイトウィンドウに Application.ScreenUpdating = True と打てば戻せます。

使い方はVBAイミディエイトウィンドウの使い方へ。マクロ自体が止まらないときはExcelマクロが止まらない時の強制終了4ステップを参照してください。

【パターン5】エラー内容をログに残して後から追う

他人に配布するマクロでは、エラーの記録が最大の武器になります。「エラーが出ました」という報告だけでは、こちらは何もできませんからね。

Sub Pattern5_ErrorLog()
    On Error GoTo ErrHandler

    '--- 通常処理 ---
    Workbooks.Open ThisWorkbook.Path & "sales.xlsx"

    Exit Sub

ErrHandler:
    '--- ① Err の中身を先に変数へ控える ---
    Dim errNum As Long, errDesc As String
    errNum = Err.Number
    errDesc = Err.Description

    '--- ② ログ書き込みは Resume Next で守る ---
    Dim logPath As String, ff As Integer
    logPath = ThisWorkbook.Path & "error.log"

    On Error Resume Next
    ff = FreeFile
    Open logPath For Append As #ff
    Print #ff, Format(Now, "yyyy-mm-dd hh:nn:ss") & vbTab & _
               "Pattern5_ErrorLog" & vbTab & _
               errNum & vbTab & errDesc
    Close #ff
    On Error GoTo 0

    MsgBox "処理に失敗しました。" & vbCrLf & _
           "error.log を管理者に送ってください。"
End Sub

日時・プロシージャ名・エラー番号・説明をタブ区切りで追記しています。Excel で開けばそのまま列に分かれるので、発生頻度の集計も簡単。Open した以上は Close を忘れないでくださいね。

ログ書き込みが失敗しても止まらないよう、On Error Resume Next で囲んでいます。【落とし穴3】で触れた、ハンドラの中を守る書き方です。

エラー番号と説明を先に変数へ控えているのもポイント。On Error を実行すると、Err の中身がリセットされる場合があるからです。

自分だけで使うマクロなら、ファイル出力までは不要です。Debug.Print でイミディエイトウィンドウに出す軽い方法でも十分ですよ。

よくある質問(FAQ)

On Error GoTo を書いたのにエラーで止まります

原因は大きく3つに分かれます。

  • VBE の「エラー トラップ」設定が影響している
  • ハンドラの中で2つ目のエラーが起きている
  • 別のプロシージャの中でエラーが起きている

まず環境を疑ってください。他の人の PC では止まらないなら、【落とし穴1】の設定を確認します。自分の PC だけの問題ではないなら、【落とし穴3】のハンドラ内エラーを疑いましょう。

On Error Resume Next は絶対に使ってはいけないの?

そんなことはありません。シートやファイルの存在確認のように、「失敗しても次へ進みたい」処理では正当な選択肢です。

危ないのは構文そのものではなく、囲む範囲が広いこと。1〜2行だけに閉じて、直後に On Error GoTo 0 で解除する。この形を守れば、パターン2やパターン3のように安全に使えます。

On Error GoTo 0 を書き忘れるとどうなりますか?

そのプロシージャを抜けるまで、エラー処理の設定が効き続けます。On Error Resume Next のまま進むと、以降のエラーがすべて無言で握りつぶされる状態に。

ただし、プロシージャを抜ければ設定は自動的に無効になります。他の Sub にまで漏れ出すわけではありません。とはいえ影響範囲を目で追えなくなるので、書く習慣にしておきましょう。

別の Sub を呼び出したとき、エラー処理は引き継がれますか?

引き継がれない前提で書いてください。On Error Resume Next は、別のプロシージャが呼び出された時点で効果が続きません。呼び出し先でもエラーを無視したいなら、その中で改めて書く必要があります。

On Error GoTo のラベルも同じプロシージャ内に限定されます。ハンドラが処理中の状態で新しいエラーが起きた場合は、制御が呼び出し元へ戻ります。

呼び出し元に有効なハンドラがあれば、そちらが起動する仕組み。ただし細かい挙動は条件で変わるため、呼び出し先にも受け皿を書くのが確実です。

VBAに Try-Catch はありますか?

VBA に Try-Catch 構文はありません。代わりに On Error GoTo ラベルExit Sub、そしてラベル位置の処理を使います。この3つの組み合わせで、同じことを実現できます。

本記事の最小テンプレートが、そのまま Try-Catch に相当する形です。Cleanup: を使うパターン4は Finally に近い役割。そう考えると、対応関係が分かりやすいのではないでしょうか。

エラー処理を入れるとマクロは遅くなりますか?

エラーが起きないかぎり、体感できるほどの差はまず出ません。気にするとしたら、ループの中で On Error を毎回呼び直す構成くらいですね。

数万行規模のデータで速度が気になるなら、事前チェック方式に切り替えてみてください。IsNumeric などで先に弾く形です。決定表の3行目「そもそも起こさせない」に寄せる発想ですね。

まとめ

VBA のエラー処理でつまずくポイントは、文法そのものではありません。On Error を書いた後に何が起きるかを知らないまま、配布してしまうことです。

  • 書き分けは3択: 止める(On Error GoTo)/続ける(On Error Resume Next を1〜2行に閉じる)/起こさせない(事前チェック)
  • 効かない原因の筆頭: VBE の「エラー トラップ」設定、Exit Sub 忘れ、On Error GoTo 0 の解除漏れ、Err.Clear 漏れ
  • ハンドラは処理中に二度目を拾えない: ハンドラの中には落ちにくい処理だけを置く
  • 後始末まで書いて完成: ScreenUpdatingCalculation は戻らない前提で Cleanup: に集約する

まずはパターン4の後始末テンプレートを、いま手元にあるマクロへ1本入れてみてください。落ちたときに Excel が変な状態で残らなくなるだけでも、配布先からの問い合わせはぐっと減るはずです。

エラー番号ごとの原因と直し方はVBAマクロのエラー解決ガイドへ。VBA を体系的に身につけたい方は、入門ハブのExcelのVBAで仕事を自動化する方法もあわせて読んでみてくださいね。

タイトルとURLをコピーしました