【ExcelVBA・マクロ】VBA実行時エラー91・13を一発解決!デバッグ手法とエラーハンドリング実践ガイド【エラー対応】

VBA実行時エラー91・13 対応方法 ExcelVBA

「実行時エラー ’91’: オブジェクト変数または With ブロック変数が設定されていません。」
「実行時エラー ’13’: 型が一致しません。」

VBAを始めたばかりの頃、この2つのエラーに何度も悩まされました。

特にエラー91は「オブジェクト変数って何?」と理解するのに時間がかかり、エラー13は「数字なのになぜエラー?」と混乱しました。

しかし、エラーの原因を正しく理解し、適切なデバッグ手法を身につけてからは、エラーが出ても5分以内に解決できるようになりました。

この記事では、VBAで最も頻出する実行時エラー91・13の原因と解決方法を、実例コード付きで徹底解説します。

スポンサーリンク
スポンサーリンク
  1. VBA実行時エラーの基礎知識
    1. VBAのエラーは3種類ある
    2. 実行時エラーが発生する理由
  2. 実行時エラー91「オブジェクト変数が設定されていません」の完全攻略
    1. エラー91の正式メッセージ
    2. エラー91が発生する5つの原因
      1. 原因①:Setを付け忘れた
      2. 原因②:Nothingに設定されたオブジェクトを使用
      3. 原因③:Find/FindNextが見つからなかった
      4. 原因④:Withブロック内で変数未設定
      5. 原因⑤:関数がNothingを返した
    3. エラー91を防ぐ3つのベストプラクティス
  3. 実行時エラー13「型が一致しません」の完全攻略
    1. エラー13の正式メッセージ
    2. エラー13が発生する5つの原因
      1. 原因①:数値型の変数に文字列を代入
      2. 原因②:空白セルをLong型に代入
      3. 原因③:日付型に不正な文字列を代入
      4. 原因④:配列を単一値として扱う
      5. 原因⑤:Range型を文字列に代入
    3. エラー13を防ぐ3つのベストプラクティス
  4. デバッグ手法の基本(F8・ブレークポイント・Debug.Print)
    1. デバッグ手法①:F8キー(ステップ実行)
    2. デバッグ手法②:ブレークポイント(F9キー)
    3. デバッグ手法③:Debug.Print(イミディエイトウィンドウ)
    4. デバッグ手法の使い分け
  5. エラーハンドリングの実践(On Error GoTo vs Resume Next)
    1. エラーハンドリング①:On Error GoTo(推奨)
    2. エラーハンドリング②:On Error Resume Next(注意)
    3. On Error GoTo vs Resume Nextの使い分け
  6. 実務で使える!汎用エラー対策テンプレート
    1. テンプレート①:エラー91・13対策完全版
    2. テンプレート②:ログ出力機能付きエラーハンドリング
  7. よくある質問(FAQ)
    1. Q1. エラー91とエラー424の違いは?
    2. Q2. Option Explicitは必ず書くべき?
    3. Q3. Debug.Printの結果はどこに表示される?
    4. Q4. エラー番号13と91、どちらが先に対策すべき?
    5. Q5. On Error Resume Nextを使うと遅くなる?
  8. ✅ まとめ

VBA実行時エラーの基礎知識

VBAのエラーは3種類ある

エラー種類発生タイミング代表例
構文エラーコード入力時「Sub」の綴りミス、カッコの閉じ忘れ
コンパイルエラー実行前(コンパイル時)「変数が定義されていません」
実行時エラーマクロ実行中エラー91、エラー13、エラー9、エラー1004

この記事で扱うのは実行時エラーです。

実行時エラーが発生する理由

実行時エラーは、コードは正しいが、実行時の状況が想定外のときに発生します。

例えば:

  • 存在しないシートを開こうとした(エラー9)
  • 数値が入るべき変数に文字列を代入した(エラー13)
  • オブジェクト変数にSetせずに値を代入した(エラー91)
  • 範囲外のセルを参照した(エラー1004)

これらは構文的には正しいため、コンパイルは通過しますが、実行時に問題が起きます。

実行時エラー91「オブジェクト変数が設定されていません」の完全攻略

エラー91の正式メッセージ

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

エラー91が発生する5つの原因

原因①:Setを付け忘れた

最も頻出するパターンです。

❌ エラーが出るコード例

Sub Setを忘れた例()
    Dim ws As Worksheet
    ws = ThisWorkbook.Worksheets("Sheet1") ' ← Setが無い!
    ws.Range("A1").Value = "テスト"
End Sub

エラー理由:
オブジェクト変数(Worksheet型、Range型など)に値を代入するときは、必ずSetが必要です。

✅ 正しいコード例

Sub Setを正しく使う()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("Sheet1") ' ← Setを付ける
    ws.Range("A1").Value = "テスト"
End Sub

原因②:Nothingに設定されたオブジェクトを使用

❌ エラーが出るコード例

Sub Nothingを参照()
    Dim ws As Worksheet
    Set ws = Nothing
    ws.Range("A1").Value = "テスト" ' ← エラー91
End Sub

✅ 正しいコード例(Is Nothingでチェック)

Sub Nothing判定付き()
    Dim ws As Worksheet
    Set ws = Nothing

    If ws Is Nothing Then
        MsgBox "シートが設定されていません", vbExclamation
        Exit Sub
    End If

    ws.Range("A1").Value = "テスト"
End Sub

原因③:Find/FindNextが見つからなかった

❌ エラーが出るコード例

Sub Findが見つからない()
    Dim rng As Range
    Set rng = Range("A:A").Find("存在しない文字列")
    rng.Value = "更新" ' ← エラー91(rngがNothing)
End Sub

✅ 正しいコード例(Is Nothingでチェック)

Sub Find安全版()
    Dim rng As Range
    Set rng = Range("A:A").Find("存在しない文字列")

    If rng Is Nothing Then
        MsgBox "見つかりませんでした", vbInformation
        Exit Sub
    End If

    rng.Value = "更新"
End Sub

原因④:Withブロック内で変数未設定

❌ エラーが出るコード例

Sub Withブロックエラー()
    With Worksheets("存在しないシート") ' ← 存在しない
        .Range("A1").Value = "テスト" ' ← エラー91
    End With
End Sub

✅ 正しいコード例(事前にシート存在確認)

Sub With安全版()
    Dim ws As Worksheet
    On Error Resume Next
    Set ws = Worksheets("存在しないシート")
    On Error GoTo 0

    If ws Is Nothing Then
        MsgBox "シートが見つかりません", vbCritical
        Exit Sub
    End If

    With ws
        .Range("A1").Value = "テスト"
    End With
End Sub

原因⑤:関数がNothingを返した

❌ エラーが出るコード例

Function シートを取得(sheetName As String) As Worksheet
    On Error Resume Next
    Set シートを取得 = Worksheets(sheetName)
    On Error GoTo 0
End Function

Sub 関数からNothing()
    Dim ws As Worksheet
    Set ws = シートを取得("存在しないシート") ' ← Nothingが返る
    ws.Range("A1").Value = "テスト" ' ← エラー91
End Sub

✅ 正しいコード例(関数の戻り値をチェック)

Sub 関数戻り値チェック()
    Dim ws As Worksheet
    Set ws = シートを取得("存在しないシート")

    If ws Is Nothing Then
        MsgBox "シートが取得できませんでした", vbCritical
        Exit Sub
    End If

    ws.Range("A1").Value = "テスト"
End Sub

エラー91を防ぐ3つのベストプラクティス

  1. オブジェクト変数には必ずSetを付ける(最重要)
  2. Is Nothingで必ず存在チェック(Find、シート取得など)
  3. Option Explicitで変数宣言を強制(タイプミスを防ぐ)

実行時エラー13「型が一致しません」の完全攻略

エラー13の正式メッセージ

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

エラー13が発生する5つの原因

原因①:数値型の変数に文字列を代入

❌ エラーが出るコード例

Sub 型が一致しない()
    Dim num As Long
    num = "テスト" ' ← エラー13
End Sub

✅ 正しいコード例(IsNumericで事前チェック)

Sub 型チェック付き()
    Dim num As Long
    Dim inputValue As Variant
    inputValue = InputBox("数値を入力してください")

    If IsNumeric(inputValue) Then
        num = CLng(inputValue)
        MsgBox "入力値: " & num
    Else
        MsgBox "数値を入力してください", vbExclamation
    End If
End Sub

原因②:空白セルをLong型に代入

❌ エラーが出るコード例

Sub 空白セルをLongに()
    Dim num As Long
    num = Range("A1").Value ' ← A1が空白の場合エラー13
    MsgBox num
End Sub

✅ 正しいコード例(空白チェック付き)

Sub 空白チェック付き()
    Dim num As Long

    If Range("A1").Value = "" Then
        MsgBox "A1が空白です", vbExclamation
        Exit Sub
    End If

    If IsNumeric(Range("A1").Value) Then
        num = CLng(Range("A1").Value)
        MsgBox num
    Else
        MsgBox "A1に数値を入力してください", vbExclamation
    End If
End Sub

原因③:日付型に不正な文字列を代入

❌ エラーが出るコード例

Sub 日付型エラー()
    Dim dt As Date
    dt = "テスト" ' ← エラー13
End Sub

✅ 正しいコード例(IsDateで事前チェック)

Sub 日付型チェック付き()
    Dim dt As Date
    Dim inputValue As String
    inputValue = InputBox("日付を入力してください(例:2026/02/09)")

    If IsDate(inputValue) Then
        dt = CDate(inputValue)
        MsgBox "入力日付: " & Format(dt, "yyyy/mm/dd")
    Else
        MsgBox "正しい日付形式で入力してください", vbExclamation
    End If
End Sub

原因④:配列を単一値として扱う

❌ エラーが出るコード例

Sub 配列を単一値に()
    Dim arr As Variant
    arr = Array(1, 2, 3)

    Dim num As Long
    num = arr ' ← エラー13(配列を単一値に代入できない)
End Sub

✅ 正しいコード例(配列の要素を指定)

Sub 配列の要素を指定()
    Dim arr As Variant
    arr = Array(1, 2, 3)

    Dim num As Long
    num = arr(0) ' ← 配列の最初の要素
    MsgBox num
End Sub

原因⑤:Range型を文字列に代入

❌ エラーが出るコード例

Sub Rangeを文字列に()
    Dim str As String
    str = Range("A1") ' ← エラー13(Range型を文字列に直接代入)
End Sub

✅ 正しいコード例(.Valueで値を取得)

Sub Rangeの値を取得()
    Dim str As String
    str = Range("A1").Value ' ← .Valueで値を取得
    MsgBox str
End Sub

エラー13を防ぐ3つのベストプラクティス

  1. IsNumeric/IsDateで事前チェック(最重要)
  2. CInt/CLng/CDateで明示的に型変換(暗黙の型変換に頼らない)
  3. Option Strictを有効にする(VBA.NET環境の場合)

デバッグ手法の基本(F8・ブレークポイント・Debug.Print)

デバッグ手法①:F8キー(ステップ実行)

使い方:

  1. VBエディタを開く(Alt + F11)
  2. 実行したいマクロの最初の行にカーソルを置く
  3. F8キーを押す
  4. 1行ずつ実行され、黄色いハイライトが移動する
  5. 変数の中身を確認しながら進む

メリット:

  • どの行でエラーが出るか特定できる
  • 変数の値をリアルタイムで確認できる

デバッグ手法②:ブレークポイント(F9キー)

使い方:

  1. 一時停止したい行の左端をクリック(または行を選んでF9キー)
  2. 赤い●マークが表示される
  3. マクロを実行すると、その行で一時停止
  4. 変数の中身を確認できる

メリット:

  • 特定の箇所だけチェックできる(F8より早い)
  • 複数のブレークポイントを設定可能

デバッグ手法③:Debug.Print(イミディエイトウィンドウ)

使い方:

Sub Debug_Printを使う()
    Dim num As Long
    num = 100

    Debug.Print "変数numの値: " & num

    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("Sheet1")

    Debug.Print "シート名: " & ws.Name
End Sub

イミディエイトウィンドウの表示方法:

  • Ctrl + G
  • または「表示」→「イミディエイトウィンドウ」

メリット:

  • 変数の値をリアルタイムで確認できる
  • マクロを止めずに確認可能
  • ログとして残る

デバッグ手法の使い分け

手法使うタイミングメリット
F8(ステップ実行)エラーが出る行が不明なとき全体の流れを確認できる
F9(ブレークポイント)特定の箇所だけチェックしたいとき高速にデバッグできる
Debug.Print変数の値を記録したいときログとして残る

エラーハンドリングの実践(On Error GoTo vs Resume Next)

エラーハンドリング①:On Error GoTo(推奨)

使い方:

Sub OnErrorGoTo例()
    On Error GoTo ErrorHandler

    ' エラーが発生する可能性のある処理
    Dim ws As Worksheet
    Set ws = Worksheets("存在しないシート") ' ← エラー発生
    ws.Range("A1").Value = "テスト"

    ' 正常終了時の処理
    MsgBox "処理が完了しました", vbInformation
    Exit Sub

ErrorHandler:
    MsgBox "エラーが発生しました" & vbCrLf & _
           "エラー番号: " & Err.Number & vbCrLf & _
           "エラー内容: " & Err.Description, vbCritical
End Sub

メリット:

  • エラーが発生しても安全に終了できる
  • エラー番号とメッセージを取得できる
  • エラー時の処理を自由に記述できる

エラーハンドリング②:On Error Resume Next(注意)

使い方:

Sub OnErrorResumeNext例()
    On Error Resume Next

    ' エラーを無視して次の行に進む
    Dim ws As Worksheet
    Set ws = Worksheets("存在しないシート") ' ← エラー発生するが無視

    ' エラーチェック
    If Err.Number <> 0 Then
        MsgBox "シートが見つかりません", vbExclamation
        On Error GoTo 0 ' ← エラー処理を解除
        Exit Sub
    End If

    ws.Range("A1").Value = "テスト"

    On Error GoTo 0 ' ← 必ず解除する
End Sub

⚠️ 注意点:

  • エラーを無視するため、本当のエラー原因を見逃す危険性がある
  • 必ずOn Error GoTo 0で解除する
  • Err.Numberで毎回エラーチェックする

On Error GoTo vs Resume Nextの使い分け

エラーハンドリング使うタイミング推奨度
On Error GoTo基本的に常に使う⭐⭐⭐⭐⭐
On Error Resume Nextシート存在チェックなど、エラーが想定内のとき⭐⭐⭐

実務で使える!汎用エラー対策テンプレート

テンプレート①:エラー91・13対策完全版

Sub 汎用エラー対策テンプレート()
    ' エラーハンドリング設定
    On Error GoTo ErrorHandler

    ' ========== 処理1: オブジェクト変数の安全な取得 ==========
    Dim ws As Worksheet
    On Error Resume Next
    Set ws = ThisWorkbook.Worksheets("売上")
    On Error GoTo ErrorHandler

    If ws Is Nothing Then
        MsgBox "シート「売上」が見つかりません", vbCritical
        Exit Sub
    End If

    ' ========== 処理2: 数値型変数の安全な代入 ==========
    Dim num As Long
    Dim inputValue As Variant
    inputValue = ws.Range("A1").Value

    If inputValue = "" Then
        MsgBox "A1が空白です", vbExclamation
        Exit Sub
    End If

    If Not IsNumeric(inputValue) Then
        MsgBox "A1に数値を入力してください", vbExclamation
        Exit Sub
    End If

    num = CLng(inputValue)

    ' ========== 処理3: Findの安全な使用 ==========
    Dim rng As Range
    Set rng = ws.Range("A:A").Find("検索文字列")

    If rng Is Nothing Then
        MsgBox "検索文字列が見つかりませんでした", vbInformation
        Exit Sub
    End If

    rng.Value = "更新"

    ' ========== 正常終了 ==========
    MsgBox "処理が完了しました", vbInformation
    Exit Sub

ErrorHandler:
    MsgBox "エラーが発生しました" & vbCrLf & _
           "エラー番号: " & Err.Number & vbCrLf & _
           "エラー内容: " & Err.Description & vbCrLf & _
           "エラー発生行: " & Erl, vbCritical
End Sub

テンプレート②:ログ出力機能付きエラーハンドリング

Sub ログ出力付きエラーハンドリング()
    On Error GoTo ErrorHandler

    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("Sheet1")

    ' Debug.Printでログ出力
    Debug.Print "処理開始: " & Now
    Debug.Print "対象シート: " & ws.Name

    ' 処理内容
    ws.Range("A1").Value = "テスト"

    Debug.Print "処理終了: " & Now
    Exit Sub

ErrorHandler:
    Debug.Print "エラー発生: " & Now
    Debug.Print "エラー番号: " & Err.Number
    Debug.Print "エラー内容: " & Err.Description

    MsgBox "エラーが発生しました。イミディエイトウィンドウを確認してください。", vbCritical
End Sub

よくある質問(FAQ)

Q1. エラー91とエラー424の違いは?

A. エラー424は「オブジェクトが必要です」で、オブジェクト変数を使わずに直接メソッドを呼んだときに発生します。エラー91は「オブジェクト変数が設定されていません」で、Nothingまたは未初期化のオブジェクトを使ったときに発生します。

Q2. Option Explicitは必ず書くべき?

A. はい、必ず書くべきです。変数の宣言忘れによるエラーを防ぎ、タイプミスも検出できます。VBエディタの「ツール」→「オプション」→「変数の宣言を強制する」にチェックを入れると、自動的に挿入されます。

Q3. Debug.Printの結果はどこに表示される?

A. イミディエイトウィンドウに表示されます。Ctrl + G で表示できます。または「表示」→「イミディエイトウィンドウ」でも開けます。

Q4. エラー番号13と91、どちらが先に対策すべき?

A. エラー91を先に対策すべきです。エラー91が解決すると、エラー13も自然に減ります。理由は、オブジェクト変数が正しく設定されていれば、型不一致のエラーも減るからです。

Q5. On Error Resume Nextを使うと遅くなる?

A. わずかに遅くなりますが、体感できるレベルではありません。ただし、エラーを見逃すリスクの方が大きいため、基本的にはOn Error GoToを推奨します。

✅ まとめ

実行時エラー91と13は、VBAで最も頻繁に遭遇するエラーです。

エラー91対策:

  • ✅ オブジェクト変数には必ずSetを付ける
  • ✅ Is Nothingで存在チェック
  • ✅ Findの戻り値は必ずチェック

エラー13対策:

  • ✅ IsNumeric/IsDateで事前チェック
  • ✅ 空白セルのチェックを忘れない
  • ✅ .Valueで明示的に値を取得

デバッグ手法:

  • ✅ F8キー(ステップ実行)でエラー箇所を特定
  • ✅ F9キー(ブレークポイント)で高速デバッグ
  • ✅ Debug.Printでログ出力

エラーハンドリング:

  • ✅ 基本はOn Error GoToを使う
  • ✅ On Error Resume Nextは最小限に
  • ✅ 必ずOn Error GoTo 0で解除

この記事の汎用エラー対策テンプレートをコピーして、自分のコードに組み込んでください。

エラーが出たときは、まずF8キーでステップ実行してエラー箇所を特定し、Debug.Printで変数の値を確認しましょう。

スポンサーリンク
スポンサーリンク
ExcelVBA
いがぴをフォローする

コメント

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