【Excel】VBAのエラーハンドリング(On Error)の書き方と使い分け

【Excel】VBAのエラーハンドリング(On Error)の書き方と使い分け
🛡️ 超解決

Excel VBAでプログラムを作成する際、予期せぬエラーが発生して処理が中断してしまう経験はありませんか?

エラーが発生しても処理を継続させたり、エラー発生時に特定の処理を実行させたりできる「エラーハンドリング」は、VBA開発において非常に重要です。

この記事では、VBAのエラーハンドリング機能である「On Error」ステートメントの使い方と、状況に応じた使い分けについて詳しく解説します。

この記事を読めば、エラーに強く安定したVBAコードを作成できるようになります。

【要点】VBAエラーハンドリングの基本と使い分け

  • On Error GoTo ラベル名: エラー発生時に指定したラベルに処理を移します。エラー発生時の後処理などに使います。
  • On Error Resume Next: エラーが発生しても無視して次の行から処理を続行します。一時的なエラー回避などに使います。
  • On Error GoTo 0: エラーハンドリングを無効にし、エラー発生時に通常の処理(エラーメッセージ表示と処理中断)に戻します。

ADVERTISEMENT

VBAでエラーハンドリングが必要な理由

VBAコードは、ユーザーの操作ミス、データの欠損、外部要因など、様々な理由でエラーが発生する可能性があります。

例えば、存在しないファイルを開こうとしたり、数値ではないセルに数値を入力しようとしたりする場合です。

エラーハンドリングを適切に設定していないと、プログラムは予期せず停止し、ユーザーに混乱を与える可能性があります。

エラーハンドリングは、プログラムの安定性を高め、ユーザーエクスペリエンスを向上させるために不可欠な技術です。

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

On Errorステートメントの種類と仕組み

VBAには、エラー発生時の動作を制御するための「On Error」ステートメントが用意されています。

主なものとして、「On Error GoTo」「On Error Resume Next」「On Error GoTo 0」の3種類があります。

これらのステートメントをコードの適切な位置に記述することで、エラー発生時の挙動を制御できます。

On Error GoTo ラベル名

「On Error GoTo ラベル名」は、エラーが発生した際に、指定したラベル(コード内の特定の場所を示す印)へ処理をジャンプさせるためのステートメントです。

このステートメントを記述すると、エラーが発生した時点で、その後のコードの実行は中断され、指定したラベルの位置から実行が再開されます。

エラー処理ルーチン(エラー発生時の対応を行うコードブロック)を記述する際に使用します。

On Error Resume Next

「On Error Resume Next」は、エラーが発生してもそれを無視し、エラーが発生した行の次の行から処理を続行させるためのステートメントです。

このステートメントが有効な間は、エラーメッセージは表示されず、プログラムは停止しません。

一時的なエラーや、無視しても問題ないエラーに対して使用することがあります。

ただし、このステートメントを無効にしないまま処理を続けると、意図しない結果を招く可能性があるため、使用には注意が必要です。

On Error GoTo 0

「On Error GoTo 0」は、それまでに設定されていたエラーハンドリングを無効にし、エラー発生時にVBAの標準的なエラー処理(エラーメッセージの表示と処理の中断)に戻すためのステートメントです。

エラー処理ルーチンを終了する際や、特定のコードブロックでのみエラーハンドリングを有効にしたい場合に使用します。

On Error GoTo を使ったエラー処理の実装手順

「On Error GoTo」は、エラー発生時に特定の処理を実行させたい場合に最も一般的に使用される方法です。

この方法では、エラー発生時の処理を記述した「エラー処理ルーチン」をコード内に設けます。

  1. エラーハンドリングを有効にする
    コードの先頭付近に「On Error GoTo ラベル名」を記述します。ここで指定するラベル名は、エラー処理ルーチンを記述する場所を示します。
  2. 通常処理を記述する
    エラーが発生しても問題なく実行されるべきコードを記述します。
  3. エラー処理ルーチンを記述する
    「On Error GoTo」で指定したラベル名を記述し、その下にエラー発生時の処理を記述します。
  4. エラー処理ルーチンを終了する
    エラー処理ルーチンが終わったら、「Exit Sub」または「Exit Function」でプロシージャを終了させます。これにより、エラー処理ルーチンのコードが通常処理の続きとして実行されるのを防ぎます。
  5. エラーハンドリングを無効にする
    エラー処理ルーチンの最後に「On Error GoTo 0」を記述し、エラーハンドリングを無効に戻します。

エラー情報の取得方法

エラー処理ルーチン内では、「Err」オブジェクトを使用して、発生したエラーに関する情報を取得できます。

特に、「Err.Number」でエラーコード、「Err.Description」でエラーメッセージを取得できます。

これらの情報を利用して、ユーザーに分かりやすいメッセージを表示したり、特定のエラーに応じて異なる処理を実行したりすることが可能です。

例えば、以下のようなコードでエラー情報を表示できます。

“`vba

MsgBox “エラーが発生しました。” & vbCrLf & _

“エラー番号: ” & Err.Number & vbCrLf & _

“エラー内容: ” & Err.Description

“`

エラー発生時の後処理

エラー処理ルーチンでは、エラーが発生したことによる影響を最小限に抑えるための後処理を行うことができます。

例えば、開いたファイルを閉じる、一時ファイルを作成していた場合は削除する、といった処理です。

これにより、プログラムが予期せず終了した場合でも、システムに不要なファイルが残ったり、リソースが解放されなかったりする事態を防ぐことができます。

ADVERTISEMENT

On Error Resume Next を使ったエラー処理の実装手順

「On Error Resume Next」は、エラーを無視して処理を続行させたい場合に有効です。

ただし、このステートメントは広範囲に影響を及ぼすため、使用する箇所を限定し、その効果が切れたら元に戻すことが重要です。

  1. エラーハンドリングを有効にする
    エラーを無視したいコードブロックの直前に「On Error Resume Next」を記述します。
  2. エラーが発生する可能性のある処理を実行する
    このステートメントが有効な状態で、エラーが発生する可能性のあるコードを実行します。エラーが発生しても、プログラムは停止せず、次の行へ進みます。
  3. エラーハンドリングを無効に戻す
    エラーを無視する処理が終わったら、必ず「On Error GoTo 0」を記述して、エラーハンドリングを無効に戻します。これにより、それ以降のコードで発生したエラーは、標準のエラー処理で捕捉されるようになります。

On Error Resume Next の注意点

「On Error Resume Next」を多用すると、本来発見されるべきエラーが見過ごされ、後々深刻な問題を引き起こす可能性があります。

そのため、このステートメントは、エラーが発生してもプログラムの続行に支障がなく、かつエラー発生時の状態を把握できる場合に限定して使用することが推奨されます。

また、エラーが発生したかどうかを確認するために、「Err.Number」をチェックするコードを挟むことも有効です。

例えば、ファイルが存在しない場合にエラーとなる処理で、ファイルが存在しない場合は何もしない、という動作をさせたい場合などに限定的に使用します。

On Error GoTo 0 によるエラーハンドリングの解除

「On Error GoTo 0」は、それまで有効になっていたエラーハンドリングを解除し、VBAのデフォルトのエラー処理に戻すためのステートメントです。

「On Error GoTo ラベル名」や「On Error Resume Next」でエラーハンドリングを有効にした後、その効果を終了させたい場合に記述します。

特に、「On Error Resume Next」を使用した後に、意図しないエラーの発生を防ぐために、必ず「On Error GoTo 0」で元に戻すようにしましょう。

使い分けのポイント

どのエラーハンドリング方法を選択するかは、プログラムの目的と、エラー発生時の許容範囲によって決まります。

以下に、使い分けのポイントをまとめます。

On Error GoTo ラベル名 を使うべき場面

・エラー発生時に、ユーザーにエラー内容を通知し、適切な対応を促したい場合。

・エラー発生時に、特定のクリーンアップ処理(ファイル保存、一時ファイル削除など)を実行したい場合。

・エラー発生時の処理を、コードの他の部分から分離して管理したい場合。

・エラーの種類に応じて、異なる対応をしたい場合。

On Error Resume Next を使うべき場面

・一時的なエラー(例:ネットワーク一時切断)が発生しても、処理を続行させたい場合。

・エラーが発生しても、プログラムの動作に大きな影響がなく、無視しても問題ない場合。

・特定の処理が失敗しても、後続の処理を優先させたい場合。

※ただし、この場合でもErr.Numberを確認し、意図しないエラーでないかチェックすることを強く推奨します。

On Error GoTo 0 を使うべき場面

・「On Error GoTo ラベル名」や「On Error Resume Next」によるエラーハンドリングを終了させたい場合。

・特定のコードブロックでのみエラーハンドリングを有効にし、それ以降は標準のエラー処理に戻したい場合。

よくあるエラーとハンドリングの例

ここでは、VBAでよく発生するエラーと、それに対する「On Error GoTo」を使ったハンドリングの例を紹介します。

例1:存在しないファイルを開こうとするエラー(エラー番号 76)

ファイルパスが間違っていたり、ファイルが存在しなかったりする場合に発生します。

“`vba

Sub OpenFileWithErrorHandling()

On Error GoTo ErrorHandler ‘ エラーハンドリングを有効にする

Dim filePath As String

filePath = “C:\存在しないフォルダ\存在しないファイル.xlsx” ‘ 存在しないファイルパス

Workbooks.Open filePath

MsgBox “ファイルを開きました。” ‘ この行は実行されない

Exit Sub ‘ 通常処理が正常に終わった場合はここで終了

ErrorHandler:

‘ エラー発生時の処理

If Err.Number = 76 Then ‘ エラー番号 76: パスが見つかりません

MsgBox “指定されたファイルが見つかりません。パスを確認してください。”

Else

‘ その他のエラーの場合は、標準のエラーメッセージを表示

MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _

“エラー番号: ” & Err.Number & vbCrLf & _

“エラー内容: ” & Err.Description

End If

On Error GoTo 0 ‘ エラーハンドリングを無効に戻す

End Sub

“`

例2:オブジェクト変数がNothingの場合にプロパティを参照しようとするエラー(エラー番号 91)

オブジェクトが正しく設定されていない(Nothingである)状態で、そのオブジェクトのプロパティやメソッドにアクセスしようとした場合に発生します。

“`vba

Sub CheckObjectProperty()

On Error GoTo ErrorHandler

Dim ws As Worksheet

‘ Dim ws As Worksheet

‘ Set ws = ThisWorkbook.Sheets(“Sheet1”) ‘ 通常はここでオブジェクトを設定

‘ 上記のSet文をコメントアウトすると、wsはNothingのままになる

MsgBox “シート名: ” & ws.Name ‘ ここでエラー発生(wsがNothingの場合)

Exit Sub

ErrorHandler:

If Err.Number = 91 Then ‘ エラー番号 91: オブジェクト変数またはWithブロック変数が設定されていません

MsgBox “指定されたシートが見つからないか、オブジェクトが正しく設定されていません。”

Else

MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _

“エラー番号: ” & Err.Number & vbCrLf & _

“エラー内容: ” & Err.Description

End If

On Error GoTo 0

End Sub

“`

例3:配列の範囲外アクセス(エラー番号 9)

配列の定義された範囲外のインデックスを指定して要素にアクセスしようとした場合に発生します。

“`vba

Sub AccessArrayOutOfRange()

On Error GoTo ErrorHandler

Dim myArray(1 To 5) As Integer ‘ 要素数5の配列

myArray(6) = 10 ‘ 配列の範囲外(6番目の要素は存在しない)

MsgBox myArray(6) ‘ ここでエラー発生

Exit Sub

ErrorHandler:

If Err.Number = 9 Then ‘ エラー番号 9: サブスクリプト out of range

MsgBox “配列の範囲外にアクセスしようとしました。”

Else

MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _

“エラー番号: ” & Err.Number & vbCrLf & _

“エラー内容: ” & Err.Description

End If

On Error GoTo 0

End Sub

“`

セキュリティ警告とOn Error Resume Next

Excel VBAは、マクロのセキュリティ機能によって、意図しないコードの実行を防ぐ仕組みがあります。

特に、外部ファイルやWebからコードを読み込んだ場合、「セキュリティの警告」が表示され、マクロの実行がブロックされることがあります。

「On Error Resume Next」は、このセキュリティ警告が表示される状況を回避するために、意図的に使用されることがあります。

しかし、これはあくまで一時的な回避策であり、根本的な解決策ではありません。

セキュリティ警告が表示された場合は、信頼できるソースからのファイルであることを確認し、Excelの「セキュリティセンター」設定で、信頼できる場所からのマクロ実行を許可するなどの適切な対処を行うべきです。

「On Error Resume Next」をセキュリティ警告の回避に安易に使うと、悪意のあるコードが実行されてしまうリスクが高まるため、十分な注意が必要です。

まとめ

この記事では、Excel VBAにおけるエラーハンドリングの重要性と、「On Error GoTo」「On Error Resume Next」の使い方、そしてそれらの使い分けについて解説しました。

エラーハンドリングを適切に実装することで、予期せぬエラーによるプログラムの停止を防ぎ、より安定した、ユーザーフレンドリーなVBAアプリケーションを作成できます。

まずは、簡単なマクロに「On Error GoTo」を適用し、エラー発生時のメッセージ表示から試してみることをお勧めします。

さらに、エラーの種類に応じて詳細な処理を分岐させることで、より高度なエラー対応が可能になります。

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

ADVERTISEMENT

この記事の監修者
📈

超解決 Excel・Word研究班

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

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