イントロダクション
前回(第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 FunctionSub 割り算を実行する()
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 | インデックスが有効範囲にありません | 配列の添字が範囲外、存在しないシートを指定した |
| 11 | 0 で除算しました | 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 を取り上げる。存在しないシートを確認する処理など、実務でよく使う場面を通して解説していこう。


コメント