【Excel】VBAで「実行時エラー91」が出る!Excelのオブジェクト変数未設定の原因と修正方法

【Excel】VBAで「実行時エラー91」が出る!Excelのオブジェクト変数未設定の原因と修正方法
🛡️ 超解決

Excel VBAで「実行時エラー91: オブジェクト変数またはWithブロック変数が設定されていません。」というエラーに遭遇した経験はありませんか。

このエラーは、VBAコードの実行中にオブジェクト変数に値が代入されていない状態で、その変数を使おうとした場合に発生します。原因を特定し、適切に修正することで、VBAコードを正常に動作させることが可能になります。

この記事では、実行時エラー91が発生する原因と、その具体的な修正方法について解説します。

【要点】VBAで実行時エラー91が発生する原因と修正方法

  • オブジェクト変数の初期化漏れ: 変数宣言後にSetステートメントでオブジェクトを代入していない場合に発生します。
  • 無効なオブジェクトへのアクセス: 存在しないシートやブック、セル範囲などを参照しようとした場合に発生します。
  • Withステートメント内の変数未設定: Withステートメントを使用する前に、対象のオブジェクト変数がSetされていない場合に発生します。

ADVERTISEMENT

実行時エラー91が発生する根本原因

実行時エラー91は、VBAにおいて「オブジェクト変数」が正しく設定されていない状態を指します。オブジェクト変数とは、Excelのシート、ブック、セル範囲、グラフなどのExcelの要素そのものを指し示すための変数です。これらのオブジェクトをコード内で操作するには、まず変数にそれらのオブジェクトを「代入」する必要があります。

このエラーが発生する主な原因は、変数が宣言されただけで、実際のオブジェクトへの参照が代入されていない(初期化されていない)状態で、その変数を使った処理を実行しようとすることです。

お探しの解決策が見つからない場合は、こちらの「Excelトラブル完全解決データベース」で他のエラー原因や解決策をチェックしてみてください。

オブジェクト変数未設定エラー(実行時エラー91)の主な原因と修正方法

実行時エラー91は、いくつかの具体的な状況で発生します。それぞれの原因と、それに対応する修正方法を解説します。

1. オブジェクト変数の初期化漏れ

最も一般的な原因は、オブジェクト変数を宣言したものの、`Set`ステートメントを使って実際のオブジェクトを代入するのを忘れているケースです。例えば、以下のようなコードです。

原因となるコード例:

Sub ErrorExample1()
    Dim ws As Worksheet
    ' Set ws = ThisWorkbook.Sheets("Sheet1")  ' この行がコメントアウトされているか、存在しない
    ws.Name = "新しいシート名" ' ここでエラー91が発生
End Sub

このコードでは、`Worksheet`型の変数`ws`を宣言していますが、`Set`ステートメントで`Sheet1`という実際のシートを代入していません。そのため、`ws.Name`という処理を実行しようとした際に、`ws`がどのシートを指しているのか不明な状態となり、エラーが発生します。

修正方法:

オブジェクト変数を宣言したら、必ず`Set`ステートメントを使用して、対象のオブジェクトを代入してください。Excel VBAでは、オブジェクト変数は`Set`キーワードを使わないと代入できません。

Sub CorrectedExample1()
    Dim ws As Worksheet
    ' Setステートメントでシートオブジェクトを代入する
    Set ws = ThisWorkbook.Sheets("Sheet1") 
    ws.Name = "新しいシート名" ' 正しく実行される
End Sub

もし、対象のシートが存在しない可能性がある場合は、エラー処理を加えるか、シートの存在を確認するコードを記述することが推奨されます。

Sub CorrectedExample1_WithCheck()
    Dim ws As Worksheet
    On Error Resume Next ' エラーが発生しても続行
    Set ws = ThisWorkbook.Sheets("Sheet1")
    On Error GoTo 0 ' エラー処理を元に戻す

    If Not ws Is Nothing Then
        ws.Name = "新しいシート名"
    Else
        MsgBox "Sheet1 が見つかりません。", vbExclamation
    End If
End Sub

2. 無効なオブジェクトへのアクセス

存在しないファイルを開こうとしたり、既に削除されたシートを参照しようとした場合にも、オブジェクト変数が`Nothing`(何も参照していない状態)のまま処理を進めようとしてエラー91が発生することがあります。

原因となるコード例:

Sub ErrorExample2()
    Dim wb As Workbook
    ' 存在しないファイルを開こうとする
    Set wb = Workbooks.Open("C:\存在しないフォルダ\存在しないファイル.xlsx") 
    wb.Save ' ここでエラー91が発生する可能性がある(Openでエラーになる場合もある)
End Sub

この例では、`Workbooks.Open`メソッドで指定したファイルが存在しないため、`wb`変数に有効なWorkbookオブジェクトが代入されません。`Open`メソッド自体がエラーを返すこともありますが、場合によっては`wb`が`Nothing`のまま処理が続行され、後続の`wb.Save`などでエラー91が発生することがあります。

修正方法:

オブジェクトが正しく取得できたかを確認するために、`Set`した後に変数が`Nothing`でないかチェックします。また、ファイルを開く場合は、ファイルパスが正しいか、ファイルが存在するかを事前に確認することが重要です。

Sub CorrectedExample2()
    Dim wb As Workbook
    Dim filePath As String
    filePath = "C:\存在しないフォルダ\存在しないファイル.xlsx"

    ' ファイル存在チェック(FileSystemObjectを使用する場合)
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")

    If fso.FileExists(filePath) Then
        Set wb = Workbooks.Open(filePath)
        If Not wb Is Nothing Then
            wb.Save
            MsgBox "ファイルを開き、保存しました。"
        Else
            MsgBox "ファイルのオープンに失敗しました。", vbExclamation
        End If
    Else
        MsgBox "指定されたファイルが見つかりません。パスを確認してください。", vbExclamation
    End If
    Set fso = Nothing
End Sub

Excel VBAには、`Dir`関数を使ったファイルの存在チェックも可能です。

Sub CorrectedExample2_DirCheck()
    Dim wb As Workbook
    Dim filePath As String
    filePath = "C:\存在しないフォルダ\存在しないファイル.xlsx"

    If Dir(filePath) <> "" Then ' ファイルが存在する場合
        Set wb = Workbooks.Open(filePath)
        If Not wb Is Nothing Then
            wb.Save
            MsgBox "ファイルを開き、保存しました。"
        Else
            MsgBox "ファイルのオープンに失敗しました。", vbExclamation
        End If
    Else
        MsgBox "指定されたファイルが見つかりません。パスを確認してください。", vbExclamation
    End If
End Sub

3. Withステートメント内の変数未設定

`With…End With`ステートメントを使用して、複数のプロパティやメソッドを簡潔に記述する際に、`With`の対象となるオブジェクト変数が`Set`されていないと、エラー91が発生します。

原因となるコード例:

Sub ErrorExample3()
    Dim rng As Range
    ' Set rng = ThisWorkbook.Sheets("Sheet1").Range("A1") ' この行がない

    With rng
        .Value = "テスト"
        .Font.Bold = True ' ここでエラー91が発生
    End With
End Sub

このコードでは、`rng`というRangeオブジェクト変数に値を代入する前に`With rng`ブロックに入っています。そのため、`.Value`や`.Font.Bold`といった`rng`に対する操作を実行しようとすると、`rng`がどのセルを指しているか不明なため、エラー91が発生します。

修正方法:

`With`ステートメントを使用する前に、対象のオブジェクト変数が`Set`されていることを確認してください。

Sub CorrectedExample3()
    Dim rng As Range
    Set rng = ThisWorkbook.Sheets("Sheet1").Range("A1") ' オブジェクト変数をSetする

    With rng
        .Value = "テスト"
        .Font.Bold = True ' 正しく実行される
    End With
End Sub

4. オブジェクト変数が解放された後でのアクセス

一度`Set`してオブジェクトを代入した変数でも、`Set`ステートメントで`Nothing`を代入するなどして、明示的にオブジェクトへの参照を解放した後で、その変数を使おうとするとエラー91が発生します。

原因となるコード例:

Sub ErrorExample4()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Sheet1")
    
    Set ws = Nothing ' オブジェクト参照を解放
    
    ' 解放された変数にアクセスしようとする
    MsgBox ws.Name ' ここでエラー91が発生
End Sub

修正方法:

オブジェクト変数を解放(`Nothing`を代入)した後は、その変数に対して`Name`プロパティなどを参照する処理は行わないでください。もし、解放後に再度同じオブジェクトを操作したい場合は、再度`Set`ステートメントでオブジェクトを代入し直す必要があります。

Sub CorrectedExample4()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Sheet1")
    
    MsgBox ws.Name ' 解放前に名前を取得
    
    Set ws = Nothing ' オブジェクト参照を解放
    
    ' 再度Sheet1を操作したい場合
    Set ws = ThisWorkbook.Sheets("Sheet1")
    MsgBox ws.Name & " を再度取得しました。" ' 再代入後ならOK
End Sub

5. 参照設定の不足

特定のライブラリ(例:Microsoft ActiveX Data Objects Libraryなど)の機能を使用している場合、そのライブラリへの参照設定がVBAプロジェクトで有効になっていないと、関連するオブジェクト変数が正しく設定されず、エラー91が発生することがあります。これは、Excel標準のオブジェクト(Workbook, Worksheet, Rangeなど)以外で発生しやすい問題です。

原因となるコード例:

Sub ErrorExample5()
    Dim cn As ADODB.Connection ' ADODBライブラリのオブジェクト
    ' 参照設定がされていない場合、この行でコンパイルエラーになるか、
    ' 実行時にオブジェクトが設定されずにエラー91となる可能性がある。
    Set cn = New ADODB.Connection 
    cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\test.accdb;"
    ' ... 処理 ...
    cn.Close
    Set cn = Nothing
End Sub

修正方法:

VBAエディタの「ツール」メニューから「参照設定」を開き、使用しているライブラリにチェックを入れて有効にします。例えば、上記の例では「Microsoft ActiveX Data Objects x.x Library」を探してチェックを入れます。

参照設定の手順:

  1. VBAエディタを開く
    ExcelでAlt + F11キーを押してVBAエディタを開きます。
  2. 参照設定メニューを開く
    メニューバーの「ツール」をクリックし、「参照設定(R)…」を選択します。
  3. ライブラリを選択する
    表示されたダイアログボックスで、使用したいライブラリ(例: Microsoft ActiveX Data Objects 6.1 Library)を探し、チェックボックスをオンにします。
  4. OKをクリックする
    「OK」ボタンをクリックしてダイアログを閉じます。

参照設定が完了したら、コードを再度実行してみてください。

実行時エラー91を未然に防ぐためのヒント

実行時エラー91は、VBAプログラミングにおいて非常に頻繁に遭遇するエラーの一つです。これを防ぐためには、いくつかの習慣を身につけることが有効です。

オブジェクト変数は必ず初期化する

オブジェクト変数を宣言したら、その直後、または関連する処理の開始前に必ず`Set`ステートメントで初期化する癖をつけましょう。`Dim`だけでは変数は宣言されるだけで、実際のオブジェクトは代入されません。

エラーハンドリングを活用する

`On Error Resume Next`や`On Error GoTo`ステートメントを使用して、エラーが発生した場合の処理を記述します。これにより、エラーが発生してもコードの実行を停止させずに、エラーの原因を調査したり、代替処理を実行したりできます。

例:

Sub SafeOperation()
    Dim ws As Worksheet
    On Error Resume Next ' エラーが発生しても続行
    Set ws = ThisWorkbook.Sheets("存在しないシート")
    On Error GoTo 0 ' エラー処理を元に戻す

    If ws Is Nothing Then
        MsgBox "指定されたシートが見つかりませんでした。", vbExclamation
    Else
        ' シートが見つかった場合の処理
        ws.Activate
        MsgBox ws.Name & " をアクティブにしました。"
    End If
End Sub

デバッグ機能を活用する

VBAエディタのデバッグ機能(ステップ実行、ブレークポイントの設定、イミディエイトウィンドウでの変数確認など)を積極的に活用しましょう。これにより、コードの実行フローを追跡し、どの時点でオブジェクト変数が`Nothing`になっているのかを特定しやすくなります。

コードの可読性を高める

インデントを正しく使用し、変数名に意味を持たせることで、コードの可読性を向上させます。これにより、どこでオブジェクトが設定されるべきか、どこで使われているかが把握しやすくなり、誤りを減らすことができます。

ADVERTISEMENT

まとめ

Excel VBAにおける実行時エラー91「オブジェクト変数またはWithブロック変数が設定されていません。」は、オブジェクト変数が初期化されていない状態で使用された場合に発生します。

この記事では、初期化漏れ、無効なオブジェクトへのアクセス、Withステートメント内の変数未設定、オブジェクト解放後のアクセス、参照設定不足といった具体的な原因と、それぞれの修正方法を解説しました。

これらの原因を理解し、コードの記述時に`Set`ステートメントでの初期化を徹底し、エラーハンドリングやデバッグ機能を活用することで、実行時エラー91の発生を大幅に減らすことが可能です。

📊
Excelトラブル完全解決データベースこの記事以外にも、様々なエラー解決策をまとめています。困った時の逆引きに活用してください。

ADVERTISEMENT

この記事の監修者
📈

超解決 Excel・Word研究班

企業のDX支援や業務効率化を専門とする技術者チーム。20年以上のExcel・Word運用改善実績に基づき、不具合の根本原因と最短の解決策を監修しています。ExcelとWordを使った「やりたいこと」「困っていること」「より便利な使い方」をクライアントの視点で丁寧に提供します。

🏆
超解決 Excel検定 あなたのExcel実務能力を3分で測定!【1級・2級・3級】