【Excel VBA入門 第16回】エラー処理の基本!On Error GoToで「止まらない」マクロを作ろう

スポンサーリンク
Excel VBA

イントロダクション

前回(第15回)では、配列を Function や Sub に渡す方法を学んだ。これで、第12回から続いた「Function・引数編」は、これでひと区切りである。

ここまで作ってきたプロシージャは、「正しい値が渡される」ことを前提にしていた。
しかし実務では、入力ミスやファイルの不在など、想定外の事態が必ず起こる。
そこで今回から4回にわたり、マクロを安心して使えるようにする「エラー処理」を解説していこう。

  • 第16回(今回)
    エラー処理の基本。On Error GoTo、Errオブジェクト、エラー番号ごとのメッセージ出し分け
  • 第17回
    On Error Resume Next、Resume、Err.Clear。存在しないシートの確認など、エラーを無視する場面ややり直す場面
  • 第18回
    Err.Raiseでエラーを呼び出し元に伝える方法と、後始末の設計。ScreenUpdatingの復元など
  • 第19回
    エラーを起こさない工夫とシリーズのまとめ。IsNumeric、Dir、シート存在確認などの事前チェック

エラーが起きるとどうなるか

まず、わざとエラーを起こしてみよう。
第12回で作った Module1 に、割り算をする Function を追記する。

Function 割り算(被除数 As Double, 除数 As Double) As Double
    割り算 = 被除数 / 除数
End Function
Sub 割り算を実行する()
    Debug.Print 割り算(10, 0)
End Sub

実行すると「実行時エラー ’11’: 0 で除算しました。」というダイアログが表示され、マクロが途中で止まってしまう。[終了]を押せばマクロは終わり、[デバッグ]を押せばエラーの起きた行が黄色く表示される。

自分で作ったマクロであれば、これで原因を調べられる。しかし、他の人に使ってもらうマクロでこの画面が出ると、何が起きたのか分からず困らせてしまう。
エラーが起きても、わかりやすいメッセージを出して安全に終わらせる。
これがエラー処理の目的である。

エラーの種類

VBAのエラーは、大きく次の3つに分けられる。

  • 構文エラー:コードの書き方の誤り(入力中に赤字で表示される)
  • コンパイルエラー:変数の宣言漏れなど、実行前の検査で見つかる誤り
  • 実行時エラー:実行してはじめて発生するエラー(0で除算、ファイルが存在しない など)

エラー処理の対象となるのは、実行時エラーである。
構文エラーやコンパイルエラーは、コードを修正して解消するものだと覚えておこう。

On Error GoToの基本形

実行時エラーを捕まえるには、On Error GoTo ラベル名 を使う。エラーが起きると、指定したラベルの位置へ処理がジャンプする。

Sub エラー処理の基本形()
    Dim 結果 As Double

    On Error GoTo エラー処理

    結果 = 割り算(10, 0)
    MsgBox "結果:" & 結果
    Exit Sub

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

ポイントは次の3つである。

  • On Error GoTo エラー処理 を、エラーが起こりうる処理より前に書く
  • ラベルは「ラベル名+コロン(:)」の形で書き、行の先頭から始める
  • Exit Sub を必ず入れる。忘れると、エラーが起きなかった場合も、そのままエラー処理の部分に流れ込んでしまう

Function の場合は、Exit Function を使う。

Errオブジェクトでエラーの内容を知る

エラーが起きると、その情報が Err オブジェクトに格納される。主に使うのは次の2つである。

  • Err.Number:エラー番号
  • Err.Description:エラーの内容を表すメッセージ

よく出会うエラー番号を、いくつか挙げておこう。

エラー番号内容主な原因
6オーバーフローしました変数の型が扱える範囲を超えた
9インデックスが有効範囲にありません配列の添字が範囲外、存在しないシートを指定した
110 で除算しました0で割り算をした
13型が一致しません数値が必要な場所に文字列が渡された
53ファイルが見つかりません指定したファイルが存在しない
1004アプリケーション定義またはオブジェクト定義のエラーセルやシートの操作に失敗した

実践!エラー番号に応じてメッセージを出し分ける

エラー番号を Select Case で判定すれば、原因に合わせたメッセージを表示できる。
InputBox で数値を2つ入力してもらい、割り算をするマクロで試してみよう。

Sub 割り算の計算()
    Dim 数値A As Double
    Dim 数値B As Double

    On Error GoTo エラー処理

    数値A = CDbl(InputBox("割られる数を入力してください"))
    数値B = CDbl(InputBox("割る数を入力してください"))

    MsgBox 数値A & " ÷ " & 数値B & " = " & 割り算(数値A, 数値B)
    Exit Sub

エラー処理:
    Select Case Err.Number
        Case 11
            MsgBox "0で割ることはできません。", vbExclamation
        Case 13
            MsgBox "数値を入力してください。", vbExclamation
        Case Else
            MsgBox "予期しないエラーです。" & vbCrLf & _
                   Err.Number & ":" & Err.Description, vbCritical
    End Select
End Sub
   

実行して、次のように操作してみよう。

  • 2つ目に 0 を入力する → 「0で割ることはできません。」と表示される
  • 数値以外の文字(abc)を入力する → 「数値を入力してください。」と表示される
  • InputBox で[キャンセル]を押す → 空の文字列が返るため、同じく「数値を入力してください。」と表示される

Case Else は、想定していなかったエラーの受け皿である。ここで Err.Number と Err.Description を表示しておけば、後から原因を調べやすくなる。

まとめ

今回は、エラー処理の基本を学んだ。

  • エラー処理の対象は「実行時エラー」である
  • On Error GoTo ラベル名 で、エラー発生時のジャンプ先を指定する
  • 正常終了時にエラー処理へ流れ込まないよう、Exit Sub(Exit Function)を入れる
  • Err.Number と Err.Description で、エラーの内容を知ることができる
  • Select Case で、エラー番号ごとにメッセージを出し分けられる

次回(第17回)は、「エラーを無視して先へ進む」On Error Resume Next と、「エラーを直してやり直す」Resume を取り上げる。存在しないシートを確認する処理など、実務でよく使う場面を通して解説していこう。

コメント

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