自習室管理人ブログ
カテゴリー一覧を見る

VBAの実行時エラーの読み方と対処法

VBAの実行時エラーの読み方と対処法|VBA エラー 対処 Excel VBA・マクロ

マクロを実行した瞬間に「実行時エラー ’91’」と表示され、何が悪いのかまったく見当がつかない——VBAを書き始めた人がぶつかる壁のひとつです。エラーコードの番号は出ているのに、その意味が読み取れないと、どこを直せばいいかもわかりません。

この記事では、VBAの実行時エラーが「なぜ起きるのか」「エラーコードは何を意味するのか」「どうデバッグするか」「On Error構文でどう制御するか」を順に整理します。読み終えると、エラー画面を見ても落ち着いて原因を絞り込めるようになります。

この記事のポイント

  • 実行時エラーはコンパイルエラーと違い、マクロが動き出してから発生します。エラーダイアログの「番号」と「メッセージ」の両方を読むことが対処の出発点です
  • この記事では、エラー91・9・1004・13の4つを取り上げます。それぞれ「オブジェクト未設定」「範囲外参照」「Excelオブジェクト操作の失敗」「型の不一致」に関わるエラーで、それぞれの原因と確かめ方を順に説明します
  • On Error GoToでエラーを受け止め、Err.NumberとErr.Descriptionで原因を特定する構造を最初から書いておくと、データ破損リスクを大幅に減らせます
  1. VBAの実行時エラーとは?コンパイルエラーとの違い
    1. 実行時エラーが出るタイミングと表示画面の見方
    2. エラーコードとエラーメッセージの構造
  2. よく遭遇するエラーコード別の原因と対処
    1. 実行時エラー91:オブジェクト変数またはWithブロック変数が設定されていません
    2. 実行時エラー9:インデックスが有効範囲にありません
    3. 実行時エラー1004:アプリケーション定義またはオブジェクト定義のエラー
    4. 実行時エラー13:型が一致しません
  3. エラーが出たときどうデバッグすればよいか?
    1. デバッグモードで問題行を特定する手順
    2. イミディエイトウィンドウとウォッチ式の使い方
  4. On Error構文でエラーを制御する書き方
    1. On Error GoTo ラベル:エラー発生時に処理を分岐させる
    2. On Error Resume Next の使いどころと注意点
  5. VBAマクロにエラーハンドリングが必須な理由とデータ破損リスク
    1. エラー放置がデータ破損につながるリスク
  6. よくある質問
    1. Q. コンパイルエラーと実行時エラーはどう違いますか?
    2. Q. エラー番号だけわかっても原因が特定できないのですが?
    3. Q. On Error GoTo と On Error Resume Next はどちらを使えばよいですか?
    4. Q. Err.Number が 0 のときはどういう意味ですか?
    5. Q. エラーハンドリングを書かずにマクロを配布してしまいました。どうすればよいですか?
  7. まとめ
  8. 参考サイト

VBAの実行時エラーとは?コンパイルエラーとの違い

VBAのエラーは、出るタイミングによって「コンパイルエラー」「実行時エラー」「論理エラー」の3つに分けて考えると整理しやすくなります。それぞれ対処方法が異なるため、まず種類を区別することが、冷静な対処への第一歩です。

種類 発生タイミング 原因の例 On Errorで防げるか
コンパイルエラー 実行前(コード解析時) 構文の誤り・End Subの欠落・宣言していない変数(Option Explicit がある場合) ❌ コードの修正が必要
実行時エラー マクロ実行中 シート未存在・型の不一致 ✅ On Errorで処理可能
論理エラー 実行中(メッセージなし) 計算式の間違い・条件分岐のバグ ❌ テスト・デバッグで発見

Microsoft Learn「On Error ステートメント」によると、On Error ステートメントは実行時エラーが起きたときの動きを決めるものです。コンパイルエラーは実行前の段階で見つかるのでコードを直し、論理エラーはテストとデバッグで見つけます。

無人のピアノで一部が沈んだ鍵盤
イメージ

実行時エラーが出るタイミングと表示画面の見方

実行時エラーは、構文に問題がないコードでも、マクロが動き出した後に発生します。存在しないシートを参照した、変数に想定外の型のデータが入ってきた——そうした「実行時の状況」と「コードの期待値」がずれたとき、Excelはその場で処理を止めます。

表示されるダイアログには「実行時エラー ‘番号’: メッセージ」という形式で情報が出ます。エクセル事務ハック「VBAの実行時エラーとは?」によると、ダイアログの「デバッグ」ボタンをクリックすると、エラーが発生したコード行が黄色でハイライトされます。このハイライトがデバッグの出発点です。

「終了」を押すと、マクロはそのまま止まります。どこで止まったかを確かめたいときは、「デバッグ」を押してください。

エラーコードとエラーメッセージの構造

エラーダイアログに表示される「番号」と「メッセージ」はセットで読むものです。番号だけ見ても、メッセージだけ読んでも、原因の特定には不十分です。

Microsoft Learn「On Error ステートメント」によると、エラー情報はErrオブジェクトに格納されており、次の3つのプロパティで取り出せます。

  • Err.Number:エラー番号(例: 91、9、1004)
  • Err.Description:エラーの説明文(日本語のメッセージ)
  • Err.Source:エラーが発生したオブジェクト名

エラー処理ルーチンの中でErr.Numberの値をSelect Caseで分岐させると、エラーの種類に応じた対処を自動化できます。エラーダイアログを読む際は、番号でパターンを絞り込んでからメッセージで状況を確認する順に進めると、原因特定が速くなります。

暗い機械の操作盤にともる赤い警告灯
イメージ

よく遭遇するエラーコード別の原因と対処

VBAの実行時エラーには多くの種類があります。この記事では、代表的な91・9・1004・13の4つを取り上げます。へるぱそねっと「実行時エラー番号 一覧」では、実務で遭遇しやすい21種のエラーが一覧になっています。まずはこの4種の対処パターンを押さえておくと、エラー画面を見たときに原因を絞り込みやすくなります。

丸い端子のプラグと縦長の差し込み口
イメージ

実行時エラー91:オブジェクト変数またはWithブロック変数が設定されていません

エラー91は「オブジェクト変数にSetでインスタンスを割り当てる前に、そのオブジェクトのプロパティやメソッドを呼び出した」ときに発生します。

典型的なケースは次のとおりです。

Dim ws As Worksheet
Debug.Print ws.Name  ' ← ws は Nothing のまま → エラー91

wsにはWorksheetオブジェクトが「まだ入っていない」状態です。対処は、使う前に必ずSetで代入することです。

Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")  ' ← 先にSetで代入
Debug.Print ws.Name

Findメソッドの戻り値を受け取るときも同様です。Findが一致するセルを見つけられなかった場合はNothingを返すため、結果を使う前にIf result Is Nothing Thenで確認する習慣が、エラー91の防止につながります。

実行時エラー9:インデックスが有効範囲にありません

エラー9は「存在しないシート名・シートインデックス・配列の範囲外の添え字を指定した」ときに出ます。

代表的な発生パターンは2つです。

  • シート名の指定ミス:Sheets("データ")と書いたが、実際のシート名が「データ一覧」だった
  • 配列の範囲外アクセス:Dim arr(5) As Longで宣言した配列にarr(6)でアクセスした

VBAオフィスの解説記事では、エラー9の再現コードとして「ブック内に存在しないシート名を指定して Select を呼ぶ」パターンが示されています。対処は、シート名のつづり(全角・半角や前後の空白を含む)を確かめることと、使う前にそのシートがあるかを確かめる処理をはさむことです。

Sub ActivateIfExists()
    Dim sheetName As String
    Dim ws As Worksheet
    Dim found As Boolean
    sheetName = "データ"

    For Each ws In ThisWorkbook.Worksheets
        If ws.Name = sheetName Then
            ws.Activate
            found = True
            Exit For
        End If
    Next ws

    If Not found Then
        MsgBox "シート「" & sheetName & "」が見つかりません。"
    End If
End Sub

Microsoft Learn「シート オブジェクト」によると、Sheets にはグラフ シートとワークシートの両方が入ります。Worksheet 型の変数で Sheets を回すと、グラフ シートのあるブックでは型が合わずに止まるため、ここでは Worksheets を使っています。

実行時エラー1004:アプリケーション定義またはオブジェクト定義のエラー

エラー1004は、原因が多岐にわたるエラーです。Microsoft Learn の説明によると、このメッセージは、Excel などのホスト アプリケーションが定義したエラーである可能性があります。そのため、メッセージだけでは原因を特定できません。

VBA実行時エラー1004の原因と解決方法完全ガイドでは、エラー1004の発生パターンを整理しています。主なものは次のとおりです。

  • ファイルが存在しないパスでWorkbooks.Openを呼んだ
  • 非アクティブなシートに対してSelectを呼んだ
  • コピー元とコピー先のセル範囲のサイズが一致しない
  • 保護されたシートに書き込もうとした
  • 定義されていない名前付き範囲を参照した
  • セルの行番号・列番号に、シートの範囲外の値(0 など)を指定した

デバッグの手順として、まずデバッグボタンでハイライトされた行を確認し、そのメソッドの引数(ファイルパス・シート名・セル範囲)をDebug.Printでイミディエイトウィンドウに出力して、実際の値を目で確認するのが最も確実です。

寝室の床に並ぶ縞模様と無地の靴下
イメージ

実行時エラー13:型が一致しません

エラー13は「変数に代入しようとした値の型が、変数の宣言型と合わない」ときに発生します。たとえば、Long型の変数に文字列「ABC」を代入しようとすると、このエラーが出ます。

セルの値を変数に受け取る処理でよく起きるパターンです。

Sub ErrorSample13()
    Dim price As Long
    price = Range("A1").Value  ' ← A1 が「ABC」など数値として読めない文字列 → エラー13
End Sub

なお、A1 に何も入っていない(空の)ときはエラーにならず、price には 0 が入ります。空のセルの値は Empty で、Empty は数値として使うと 0 になるためです。根拠は Microsoft Learn のXlRangeValueDataTypeとVariant データ型の説明です。空のセルを見落とすと 0 のまま計算が進むので注意してください。

一方、数式で「””」(空の文字列)を返しているセルは、見た目は空でも値は文字列なので、エラー13になります。

対処は2つあります。ひとつはIsNumeric()やIsEmpty()で値を確認してから代入する方法です。もうひとつは受け取る変数をVariant型にして、代入後に型チェックする方法です。実務ではセルに予期しない型が入ることが多いです。数値を扱うコードには必ずIsNumericのチェックをはさんでください。

将棋盤のマスに置かれた一枚の駒
イメージ

エラーが出たときどうデバッグすればよいか?

エラーが出た後、「なんとなくコードを眺める」だけでは原因にたどり着けないことがほとんどです。VBAエディターには、問題箇所を効率よく絞り込むためのデバッグ機能が備わっています。手順を知っておくと、調査時間が大幅に短くなります。

デバッグモードで問題行を特定する手順

エラーダイアログの「デバッグ」ボタンを押すと、エラーが発生した行が黄色くハイライトされた状態でVBAエディターが開きます。ここからデバッグを進める手順は次のとおりです。

  1. ハイライト行を確認する:どのオブジェクト・メソッド・変数でエラーが起きたかが最初の手がかりになります
  2. F8キーでステップ実行する:コードを1行ずつ動かして、どの行で止まるかを追います
  3. 変数の値をマウスオーバーで確認する:変数名の上にカーソルを置くと現在の値がポップアップ表示されます
  4. ブレークポイントを設定する:怪しい行の左端をクリックして赤い丸(ブレークポイント)を置き、そこで実行を一時停止させます

ステップ実行(F8)は、エラーの直前の行で変数の値がどうなっているかを目で確認できるため、「コードは正しいはずなのになぜエラーが出るのか」という状況の解明に有効です。

イミディエイトウィンドウとウォッチ式の使い方

VBAエディターの「表示」メニュー(Ctrl + G)から開ける「イミディエイトウィンドウ」は、デバッグ時の強力な補助ツールです。Microsoft Learn「[表示] メニュー」によると、このウィンドウでは、実行中のデバッグ出力を表示したり、変数の値を確かめたりできます。

使い方は2とおりあります。

  • Debug.Printをコードに挿入する:Debug.Print ws.Nameのように書くと、実行時にイミディエイトウィンドウへ値が出力されます。ファイルパスやシート名など「想定と違う値が入っているかもしれない変数」を確認するのに便利です
  • イミディエイトウィンドウに直接入力する:ブレークポイントで止まった状態で?変数名と入力してEnterを押すと、その時点の値が表示されます

「ウォッチ式」は、特定の変数や式の値を見張る機能です。「デバッグ」メニューの「ウォッチ式の追加」から設定できます。Microsoft Learn「[デバッグ] メニュー」によると、ウォッチ式の値は、ブレーク モード(実行が一時停止した状態)に入るたびに更新されます。

ループの中にブレークポイントを置いたり、F8 キーで1行ずつ進めたりしながら見ると、変数が意図しない値に変わっていないかを追えます。

On Error構文でエラーを制御する書き方

Microsoft Learn「On Error ステートメント」によると、On Errorステートメントを使用しない場合、発生するすべての実行時エラーが致命的となります。つまり、エラーメッセージが表示されて実行が停止します。On Error構文は「エラーが起きたときにどう動くか」をあらかじめ決めておくための仕組みです。

緑に囲まれた池を一周する丸い散歩道
イメージ

On Error GoTo ラベル:エラー発生時に処理を分岐させる

Microsoft Learn(VBA公式リファレンス)によると、On Error GoToは、エラーが発生した瞬間に指定したラベル(行ラベル)へジャンプし、そこに書いたエラー処理ルーチンを実行する構文です。最も基本的な構造は次のとおりです。

Sub SampleMacro()
    On Error GoTo ErrorHandler
    
    ' 通常の処理
    Worksheets("データ").Activate
    
    Exit Sub  ' ← ここが重要
    
ErrorHandler:
    MsgBox "エラーが発生しました。" & vbCrLf & _
           "番号: " & Err.Number & vbCrLf & _
           "内容: " & Err.Description
End Sub

On Error GoTo を使うときに書き忘れに注意したいのが「Exit Sub」の記述です。通常の処理の末尾に Exit Sub を書かないと、エラーがない場合でもプログラムがそのまま ErrorHandler ラベルへ流れ込んでしまいます。

Microsoft Learn「On Error ステートメント」も、エラー処理ルーチンの直前に Exit Sub を置く書き方を示しています。この順番を守れば、流れ込みは防げます。

On Error Resume Next の使いどころと注意点

Microsoft Learnによると、On Error Resume Nextは、実行時エラーが起きても、エラーの起きた文の次から処理を続ける指定です。エラーを無視する範囲が広いと問題に気づけなくなるため、「エラーが出ても構わない1〜2行の処理」に絞って使うのが安全です。

典型的な使いどころは、オブジェクトの存在チェックです。

On Error Resume Next
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("集計")
Err.Clear          ' ← 残存エラー番号をリセット
On Error GoTo 0    ' ← 必ずリセット

If ws Is Nothing Then
    MsgBox "シート『集計』が見つかりません。"
    Exit Sub
End If

On Error Resume Next をプロシージャ全体に効かせると、意図しないエラーまで無視されたまま処理が進みます。データが壊れても気づけないおそれがあります。使い終わったら必ず On Error GoTo 0 でエラーを無視する設定を解除し、エラーを無視する範囲を最小限に絞ってください。

また、On Error Resume Next のあとで Err.Number を何度か確かめるときは、確かめるたびに Err.Clear で消しておきます。Microsoft Learn「Clear メソッド」の例のとおり、消さないと前のエラーが残り、次の確認でもエラーがあったと判断してしまいます。

プリンターのローラーに詰まった白い紙
イメージ

VBAマクロにエラーハンドリングが必須な理由とデータ破損リスク

「動けばいい」という気持ちでエラー処理を後回しにしがちですが、業務で使うマクロにエラー処理がないと、ある日突然、取り返しのつかない問題が起きることがあります。エラーハンドリングは「おまけ」ではなく、マクロの設計に最初から組み込む要素です。

エラー放置がデータ破損につながるリスク

エラー処理のないマクロで危ないのは「中途半端な状態で止まる」ことです。たとえば、次のような状態が残ることがあります。

  • ファイルを開いた後にエラーが起きてファイルが閉じられない → ファイルがロックされたまま残る
  • シートの保護を解除した後に止まって保護が戻らない → 意図しない編集が可能な状態になる
  • 途中まで書き込んだデータが中途半端な状態でシートに残る → データの整合性が崩れる

エラー処理を最初から書いておくと、クリーンアップ処理を確実に実行させられます。具体的には「開いたファイルを閉じる」「保護を元に戻す」「途中データを削除する」といった後始末です。マクロを他の人に使ってもらう場面では、エラーハンドリングの有無がそのままマクロの信頼性に直結します。

⚠️ On Error Resume Next の乱用に注意

「エラーが出なければいい」という理由でOn Error Resume Nextをプロシージャ全体に置くのは避けてください。エラーが握りつぶされたまま処理が続き、どこで何が起きたかまったく追えなくなります。使う場合は数行単位で、使用後はOn Error GoTo 0でリセットするのが原則です。

よくある質問

Q. コンパイルエラーと実行時エラーはどう違いますか?

A. コンパイルエラーは、マクロを実行する前のコンパイルの段階で見つかるエラーです。[自動構文チェック]がオンなら、構文の誤りは行を入力した時点で知らせてくれます。End Sub の欠落や、Option Explicit のあるモジュールでの未宣言の変数は、実行(コンパイル)しようとした時点でエラーになります。

Option Explicit が無いと、変数名のスペルミスはエラーにならず、新しい変数として扱われます。実行時エラーは構文に問題はないものの、マクロが動き出してから「存在しないシートを参照した」「型が合わない値を代入しようとした」などの状況で発生します。

Microsoft Learn「On Error ステートメント」によると、On Error ステートメントが働くのは実行時エラーが起きたときです。コンパイルエラーは On Error では対処できないので、コードを直します。

Q. エラー番号だけわかっても原因が特定できないのですが?

A. エラー番号はエラーの「カテゴリ」を示すもので、番号だけでは原因を一意に絞れないケースがあります。とくにエラー1004は、セルやシートの操作が失敗したときに幅広く出る番号のため、原因が多岐にわたります。

デバッグボタンでハイライトされた行を確認し、その行で使っているファイルパス・シート名・セル範囲の変数をDebug.Printでイミディエイトウィンドウに出力して、実際の値を目で確認するのが最も確実な方法です。

Q. On Error GoTo と On Error Resume Next はどちらを使えばよいですか?

A. 基本はOn Error GoToを使います。エラーが発生したことを検知して、ログ出力やメッセージ表示・クリーンアップ処理を確実に行えるためです。On Error Resume Nextは「シートが存在するかどうかを確認するためにあえてエラーを発生させる」など、エラーが起きても問題ない1〜2行の処理に限定して使います。

使用後は必ずOn Error GoTo 0でリセットしてください。

Q. Err.Number が 0 のときはどういう意味ですか?

A. Err.Number が 0 のときは、エラーが記録されていない状態です。Microsoft Learn「Err オブジェクト」によると、実行時エラーが起きると、Err オブジェクトにエラーの情報が入ります。エラー処理ルーチンの中で Exit Sub や Resume Next を実行すると、0 にリセットされます。

On Error Resume Nextを使った後にIf Err.Number <> 0 Thenでチェックするパターンが典型的で、0でなければエラーが起きたと判断して対処処理へ進みます。また、Microsoft Learn「Clear メソッド」のとおり、Err.Clear を呼び出すと Err.Number は 0 にリセットされます。

On Error Resume Nextを連続使用する場合は、各エラーチェック後にErr.Clearを呼ぶ習慣をつけてください。

Q. エラーハンドリングを書かずにマクロを配布してしまいました。どうすればよいですか?

A. まず既存のプロシージャにOn Error GoToブロックを追加します。最低限、エラー番号とエラーメッセージをMsgBoxで表示するだけでも、「なぜ止まったか」を利用者が報告しやすくなります。

クリーンアップが必要な処理(ファイルのOpen・シートの保護解除など)がある場合は、ErrorHandlerラベルの中でClose文や保護の再設定を確実に実行するよう修正してください。

まとめ

VBAの実行時エラーは、エラーダイアログの「番号」と「メッセージ」を組み合わせて読むことで、原因のカテゴリをすぐに絞り込めます。

エラー91はオブジェクトのSet忘れ、エラー9はシート名・配列インデックスのずれ、エラー1004はExcelオブジェクト操作の失敗全般、エラー13は型の不一致です。この4パターンを押さえておくと、エラー画面を見たときに原因を絞り込みやすくなります。

デバッグはエラー行の特定→変数値の確認→原因の絞り込みという3ステップで進めると、調査時間を大幅に短縮できます。

On Error GoToによるエラーハンドリングは、マクロを書き終えた後に追加するものではなく、プロシージャを書き始める段階で骨格として組み込むものです。エラーが起きたときに「適切なメッセージを出してクリーンアップしてから終了する」という流れを最初から設計しておくと、マクロの信頼性は大きく変わります。

まず次に書くプロシージャで、On Error GoToブロックとExit Subの組み合わせを試してみてください。On Errorの応用パターンやErrオブジェクトの詳細な活用法については、下記の参考サイトでさらに深く学べます。

※本記事の情報は2026年10月時点のものです。VBAの仕様は変更される場合があるため、最新情報はMicrosoft Learn等の公式ドキュメントでご確認ください。
最終更新: 2026年10月24日

参考サイト

集中できる学習環境を探している方は、新宿の自習室もご覧ください。24時間利用可・半個室ブース中心の自習室です。
→ アイデスク新宿自習室の詳細

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