本ページには広告が含まれています。

【Excel VBA】エラー処理について(On Error)

Excel VBA エラー処理(On Error)
画像はCanvaの「Text to Image」で生成しました

VBAで新たにマクロを作成する場合、テストを何度も行ない正しく動作することを検証してから配布します。しかし、実際に運用が開始されたところ「エラーになった!」ということが結構あります。

テストでは想定していなかった環境で運用されたりすることもあるため、エラーが発生することをあらかじめ想定して対処しておく必要があります。このエラーへの対処方法について基本的な部分をいくつか紹介したいと思います。

【この記事でわかることは】
・On Error ステートメントの使い方

スポンサーリンク

はじめに

「実行時エラー」は主にVBA(マクロ)が外部とのデータ取得・参照や書き込みなどのやりとりを行なう時に発生します。

エラーに対する対策を何もしていない場合は、次のようなVBAのエラーダイアログが表示されます。

実行時エラー9メッセージダイアログ

ここで「終了」を選択すると、エラーが発生して箇所で処理が中断されてそのまま終了します。
「デバッグ」を選択すれば、VBEが開き中断されている部分が黄色く表示されて編集状態になりますが、VBAがわからない人にとっては余計に混乱させてしまうことでしょう。また、VBAコードを触られたくない場合はVBAのエラーダイアログは表示しない方が良いでしょう。

On Errorステートメントを使ってエラーをトラップすることでエラーダイアログを表示しないようにできます。操作者にエラー発生事象や内容など独自のメッセージを通知して処理を打ち切るようにもできます。

On Errorステートメント

On Error は、実行時エラーが発生したらどうするかを指定するステートメントです。
発生したエラーをトラップしてプロシージャ内のエラー処理ルーチンの場所へジャンプさせたり、エラー処理ルーチンを無効にしたりすることができます。

On Error ステートメントの構文は、次の形式を使用できます。

ステートメント説明
On Error GoTo line同じプロシージャ内の line の指定行からの処理を実行します。
line 引数は、任意の行ラベルまたは行番号です。
On Error Resume Nextエラーは捉えますが、そのまま次のステートメントを実行します。
On Error GoTo 0プロシージャ内の有効なすべてのエラーハンドラーを無効にします。

On Error GoTo line

On Error に GoToステートメントを使うことで、エラー発生時にエラー処理ルーチンの場所へジャンプさせることができます。
※ GoToステートメンについて、詳しくはこちらを参照ください。

line には「行ラベル」又は「行番号」を指定します。「行ラベル」は任意の文字列で指定できます。
ジャンプ先の「行ラベル」はインデントせずに1列目から入力し末尾にコロン (:)を付けます。大文字と小文字は区別しません。

前回記事で使ったサンプルに基本的なエラー処理を加えてみるとこんな感じです。

Sub Sample03()
  Dim arr As Variant
  Dim i As Long
  On Error GoTo ErrorHandler    'エラー処理用
  arr = Array(1, 2, 3, 4, 5)
  For i = 1 To 5
    Cells(i, 1) = arr(i)        'i = 5 でエラー発生
  Next i
  Exit Sub
ErrorHandler:   '「行ラベル」
  With Err      'Errオブジェクト
    MsgBox .Source & "内でエラーが発生しました!" & _
      vbCrLf & "エラー番号" & .Number & ":" & .Description _
      , vbCritical, "エラー通知"
  End With
End Sub

・4行目に On Error GoToステートメントを入れ行ラベル ErrorHandler を指定

・9行目に Exit Sub を追加して正常の場合はここで処理を終了させます。
 これを忘れると正常なのに次のエラー処理のコードが実行されてしまいます。

・10行目の行ラベル ErrorHandler: からがエラー発生後の処理です。

・11行目、Errオブジェクトを複数使うので With プロパティを使っています。

・12~14行目でメッセージボックスの表示内容を設定しています。

・エラーが発生すると、エラーの情報が Errオブジェクトに格納されます。
 ここでは、その情報の中から「.Source」「.Number」「.Description」を使っています。

・14行目「, vbCritical, “エラー通知”」はアイコンとタイトルの設定です。

独自設定のエラーメッセージボックス
実行の結果表示された「エラー通知」メッセージボックス

MsgBox のアイコン変更はvb定数で指定します。ここでは「停止(×)」を示す赤いアイコン「vbCritical」を使っています。
その他、黄色の「注意(!)」アイコン「vbExclamation」、青色の「案内(i)」アイコン「vbInformation」などもあります。必要に応じて使い分けましょう。

On Error Resume Next

Resumeステートメントの構文は次のような形式を使用できます。

ステートメント説明
Resume [0]エラー発生ステートメントから実行を再開します。
Resume Nextエラー発生ステートメントを無視して次のステートメント
から実行が再開されます。
Resum lineエラーハンドラーと同じプロシージャ内の
line で指定された行から実行が再開されます。
line は行ラベル又は行番号を指定できます。

On Error に Resumeステートメントを使うことで、エラー発生時に指定した行からの処理を実行したり、エラー発生個所をスルーして次の処理を実行させることが可能です。

エラーをスルーさせたい場合は On Error Resume Next を使います。

Sub Sample03_2()
  Dim arr As Variant
  Dim i As Long
  On Error Resume Next       '実行時エラーを無視する
  arr = Array(1, 2, 3, 4, 5)
  For i = 1 To 5
    Cells(i, 1) = arr(i)        'i = 5 でエラー発生
  Next i
End Sub

先ほどのサンプルに On Error Resume Next を使うと、i = 5 で実行時エラーが発生しますがエラーメッセージは表示されずにそのまま終了します。

でもこの使い方では、セルに誤った結果が書き出されてしまいます。不用意に On Error Resume Next を使ってはダメだということがわかる事例です。エラーを無視しても正常な処理(結果)になる場合にだけ利用しましょう。

次の例は、セルのデータを一旦配列に入れて違うセルに2倍して書き出す処理です。

Sub ResumeNextSample()
  Dim arr(5) As Long 'Variant
  Dim i As Long
  On Error Resume Next  '実行時エラーを無視する
  'セルのデータを配列に格納
  For i = 1 To 5
    arr(i) = Cells(i, 1)  'データ型がLongならエラー
  Next
  '配列のデータを2倍してセルに書き込む
  For i = 1 To 5
    Cells(i, 2) = arr(i) * 2  'Variantならここでエラー
  Next
End Sub

・4行目に On Error Resume Next を入れています。

Resume Next 無しでは取得するセルに #N/A や #VALUE! のエラー表示や文字列があった場合、実行時エラー’13’が発生します。

実行時エラー13のエラーダイアログ

・配列のデータ型が Long の場合は、7行目のループでエラーが発生します。
 データ型が Variant の場合は、11行目のループでエラーとなります。

このように On Error Resume Next でエラーを無視することで、データが「0」になるので問題は発生しなくなります。むしろ、エラーのデータを事前に処理する手間が省けるというわけです。

On Error GoTo 0

現在のプロシージャで有効なすべてのエラーハンドラーを無効にするステートメントです。

先ほどの例でいえば、データ型が Long の場合は、配列にセルのデータを書き込む際のループでエラーが発生しますが、セルに書き込む際にはエラーは発生しませんので次のようにしても問題ありません。

Sub GoTo_0_Sample()
  Dim arr(5) As Long 'Variant
  Dim i As Long
  On Error Resume Next  '実行時エラーを無視する
  'セルのデータを配列に格納
  For i = 1 To 5
    arr(i) = Cells(i, 1)  'データ型がLongならエラー
  Next
  On Error GoTo 0       'エラー処理を無効にする
  '配列のデータを2倍してセルに書き込む
  For i = 1 To 5
    Cells(i, 2) = arr(i) * 2  'Variantならここでエラー
  Next
End Sub

・配列のデータ型を Variant に変更して実行してみてください。
 11行目のループでエラーが発生します。

・エラーハンドラーが無効になっていることが確認できます。

まとめ(おわりに)

今回の内容はいかがでしたか? お役に立てたなら幸いです(^^;

想定できるエラーに対して、エラー処理を設置する方法についての基本的なことは解説できたのではないでしょうか。

今回紹介したものはプロシージャだけでしたが、プロシージャを跨ぐ場合のエラー処理についても理解しておく必要があります。次回以降でエラー処理についてさらに詳しく見ていくようにしたいと思います。

最後に今回の内容を箇条書きでまとめるとこんな感じです。

・On Error は、実行時エラーが発生したらどうするかを指定するステートメント

・On Error GoToステートメントは、エラー処理ルーチンの場所へジャンプする

・On Error Resume Next で、エラー発生個所をスルーさせることが可能
 ただし、エラーを無視しても正常な処理(結果)になる場合にだけ利用する

・On Error GoTo 0 は、プロシージャで有効なエラーハンドラーを無効にする

★★★ ブログランキング参加中! クリックしてね(^^)/ ★★★

スポンサーリンク

過去記事のサンプルファイルをダウンロードできます

この記事で使用したサンプルの登録はありません。
過去の記事で使用したサンプルファイルをダウンロードできるようにページを設置していますので、こちら(このリンク先)からご利用ください