実行時エラー91「オブジェクト変数または With ブロック変数が設定されていません」の原因と直し方

公開日:2026年10月7日 執筆:Takuya カテゴリ:エラー対処

実行時エラー91は、中身が空(Nothing)のオブジェクト変数を使おうとしたときに起きます。Set の書き忘れ、Find で見つからなかった場合など、よくある原因ごとに直し方を解説します。

どんなエラーか

実行時エラー91は、「オブジェクトを入れるための変数に、まだ何も入っていない(Nothing の)状態で、その変数のプロパティやメソッドを使おうとした」ときに表示されます。Worksheet 型や Range 型の変数は、宣言しただけでは中身が空で、Set で何かを入れて初めて使えるようになります。

エラーで止まった行には、たいてい「変数名.何か」という書き方があります。その変数に Set が実行されているか、Set した結果が Nothing になっていないかを確認するのが、原因を探す近道です。

原因1:Set を書き忘れている

最も多いのが、オブジェクト変数への代入に Set を付け忘れるケースです。数値や文字列の変数と同じ感覚で「ws = ...」と書くと、ws に中身が入らないままになり、エラー91になります。

' エラーになる書き方
Sub BadSample()
    Dim ws As Worksheet
    ws = ThisWorkbook.Worksheets("売上")      ' Set がないのでエラー91
    ws.Range("A1").Value = "集計日"
End Sub

' 正しい書き方
Sub GoodSample()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("売上")
    ws.Range("A1").Value = "集計日"
End Sub

原因2:Find で見つからなかった

Range.Find は、探している値が見つからないと Nothing を返します。見つかる前提で「.Row」などを続けて書くと、データがない日にだけエラー91で止まる、という分かりにくい不具合になります。Find の結果は必ず変数に受け、Is Nothing で確認してから使います。

Sub FindCustomer()
    Dim ws As Worksheet, hit As Range

    Set ws = ThisWorkbook.Worksheets("顧客一覧")
    Set hit = ws.Range("A:A").Find(What:="C1024", LookIn:=xlValues, LookAt:=xlWhole)

    If hit Is Nothing Then
        MsgBox "顧客コード C1024 は見つかりませんでした"
        Exit Sub
    End If
    MsgBox "顧客コード C1024 は " & hit.Row & " 行目です"
End Sub

そのほかのよくある原因

ほかにも、次のような場面でエラー91が起きます。いずれも「変数に Set されないまま使われている」という点は共通です。

  • If 文の中でだけ Set していて、条件に合わなかったときに Set されないまま使っている
  • モジュールの先頭で宣言した変数を、別のマクロで Set してから使う設計になっていて、その準備のマクロを実行していない
  • コードを編集したり「リセット」したりして、モジュール変数の中身が消えている
  • With ブロックの外から GoTo で With の中の行へ飛び込んでいる
  • On Error Resume Next を付けて Set した行が失敗し、変数が Nothing のまま次の行へ進んでいる

原因を見つける手順と予防策

エラーのダイアログで「デバッグ」を押すと、止まった行が黄色で表示されます。その行で使っているオブジェクト変数にマウスを重ねるか、イミディエイトウィンドウで「? 変数名 Is Nothing」と入力すると、中身が空かどうかを確認できます。True と表示されれば、その変数に Set されていないことが原因です。

予防策としては、オブジェクト変数を Set した直後に Is Nothing で確認する習慣を付けることです。特に Find、Dictionary から取り出したオブジェクト、On Error Resume Next を付けて取得したシートやブックは、取得に失敗しても次の行に進んでしまうため、確認を省略しないようにします。Find は前回の検索条件を引き継ぐ性質もあるので、LookIn や LookAt を毎回指定しておくと、見つかるはずの値が見つからないという事態も防げます。

ほかの記事