VBAエキスパート対策
エラーへの対処

Excel VBAエキスパート対策です
公開日:2018-03-10 最終更新日:2019-08-26

エラーへの対処


・On Error Goto
・On Error Resume Next
・Errorオブジェクトほか


【ここでのポイント】

公式テキストでは、文法エラーと論理エラーについて書かれていますが、
そこはベーシックの出題範囲なので、ここでは省略します。
もし、不安な部分があるようなら、デバッグの基礎 を復習しておいてください。
・【ここでのポイント】 ・デバッグとは ・論理エラーと文法エラー ・イミディエイトウィンドウ ・ブレークポイント ・ステップ実行 ・その他のデバッグ用のウィンドウ ・【業務改善の実務】 ・【本サイト内の関連ページ】 ・VBAエキスパート公式テキスト

エラーへの対処は、極めて簡単です。
On Error Goto
On Error Resume Next
どちらかを使います。
そして、
エラー発生の理由は、Errオブジェクトのプロパティを調べるだけです。

たったこれだけです、そして、これ以外には有りません。
にもかかわらず、大項目として試験範囲に列挙されているのには理由があります。

何の対策もしてなければ、マクロ実行でエラーが発生すればマクロは停止してしまいます。

マクロが停止しては困ります。
そもそもマクロは作業を自動化するものなのに、停止してしまってはどうしようもありません。
そこで、エラーへの対処が必要になります。
そしてVBAとしての対処は、上記のとおり難しいものではありません。

本当に難しいのは、エラー発生の可能性を事前に予測することです。
これには経験が必要です。

試験対策としては、
VBAのステートメントはそれほど難しくないのでしっかり覚えることは当然として、
いろいろなエラー発生パターンを実際のVBAコードで体験しておくことです。

On Error Goto

実行時エラーが発生した時に、制御を指定の行ラベルに移動させるものです。


エラーが発生すると、行ラベルの位置に制御が移ります。

このステートメント以降、On Error GoTo 0 が無い限り、プロシージャーの終わりまで有効となります。

Sub Sample
  On Error GoTo Label01
  ・・・
  'ここでエラー発生した場合、Label01に制御が移ります
  ・・・
  Exit Sub
Label01:
  エラー時の処理
End Sub


Label01:
これが、行ラベルです。


行ラベル
ラベル名:

と書きます。

GoToの行先として指定する場所になります。

On Error Resume Next

エラーが発生しても、エラーが発生したステートメントの次のステートメントから実行を継続します。

このステートメント以降、On Error GoTo 0 が無い限り、プロシージャーの終わりまで有効となります。

実行時エラーを発生させたステートメントの直後にあるステートメント、または On Error Resume Next ステートメントを含むプロシージャから最後に呼び出しを行った直後のステートメントを使って、実行を継続します。

Dim i As Long
On Error Resume Next
i = "ABC"
If Err.Number <> 0 Then
  MsgBox Err.Description
  Err.Clear
End If


この場合、メッセージボックスには、
「型が一致しません」と表示されます。

Err.Clearでエラー情報をクリアしています。
クリアしないと、エラー情報はそのまま残っています。

次のエラーが発生したことを判断できるように、エラー処理の後でクリアするようにします。

Errorオブジェクト

Err オブジェクトは、実行時に発生したエラーに関する情報を保有しています。

Errオブジェクトのプロパティとメソッド

Err.Clear すべてのプロパティの設定値をクリアするメソッド
Err.Description エラーに関する簡単な説明
Err.HelpContext ヘルプ ファイルのトピックに対応するコンテキスト番号
Err.HelpFile ヘルプ ファイルへの絶対バス
Err.LastDllError 最後にダイナミック リンク ライブラリ (DLL) を呼び出したときのエラー コード
Err.Number エラーを指定する数値。エラーではない場合は0
Err.Source エラーの発生元のオブジェクトまたはアプリケーションの名前

Number プロパティの値でエラーの原因を判別します。

Err オブジェクトのプロパティの値には、最新のエラーだけが反映されます。

実行時にトラップ可能なエラー番号一覧と対処
・マクロVBAでのエラーとは ・VBA実行時のエラー番号一覧 ・実行時にトラップ可能なエラー番号一覧の最後に

On Error Goto 0

現在のプロシージャに含まれる使用可能なエラー処理ルーチンを無効にします。

その時点で有効となっている、
On Error GoTo
または
On Error Resume Next
これらのエラー処理を無効にします。

On Error の有効範囲

On Error GoTo 行ラベル

On Error Resume Next

これらは、このステートメントが実行されて以降、
On Error GoTo 0が出てくるか、
そのプロシージャが終了するまでが有効範囲となります。

On Errorが有効な状態別のプロシージャをCallし、
呼び出されたプロシージャ内でOn Error対応されていないエラーが発生した場合は、
呼び出されたプロシージャはその場で終了します。
呼び出し元のプロシージャに戻ってからは、On Errorの指定に従い動作します。

文章では理解しづらいので、以下のサンプルで確認してください。

Sub test1()
  On Error GoTo Err_Exit
  Call test2 'この中でエラー発生しても、On Error Go Toは有効
  MsgBox "正常終了"
  Exit Sub
Err_Exit:
  MsgBox "異常終了" & vbLf & Err.Description
End Sub

Sub test2()
  Dim i As Long
  On Error Resume Next
  i = "A" 'このエラーは無視
  On Error GoTo 0
  i = 0
  i = i / i 'ここでエラー発生→プロシージャを抜けます
  i = 1 'これは実行されません
End Sub

上記の「test1」の実行結果は、

MOS VBA エキスパート 参考画像

本来のエラー対応

エラー発生した時のエラー処理を記述する前に、
そもそもエラーが発生しないようにすることが本来のエラー対応です。

ブックの存在確認
Sub sample1()
  Dim sBook As String
  sBook = InputBox("ブック名を入力してください。")
  Workbooks.Open ThisWorkbook.Path & "\" & sBook
End Sub

存在しないブックを開いたときはエラーとなります。

MOS VBA エキスパート 参考画像

このエラーへの対応は、以下のようにします。

Sub sample2()
  Dim sBook As String
  On Error GoTo Err01
  sBook = InputBox("ブック名を入力してください。")
  Workbooks.Open ThisWorkbook.Path & "\" & sBook
  MsgBox sBook & "を開きました。"
  Exit Sub
Err01:
  MsgBox sBook & "は存在しません。"
End Sub
Sub sample3()
  Dim sBook As String
  On Error Resume Next
  sBook = InputBox("ブック名を入力してください。")
  Workbooks.Open ThisWorkbook.Path & "\" & sBook
  If Err.Number = 0 Then
    MsgBox sBook & "を開きました。"
  Else
    MsgBox sBook & "は存在しません。"
  End If
End Sub

上記の2つのVBAは、どちらも同じことをしています。
On Error GoToとOn Error Resume Nextの違いだけです。

これらは、ブックをOpenしてエラー発生したらメッセージを出しています。

しかし、そもそも存在しないブックを開こうとしていることが間違いです。
ブックOpenの前に、そのファイルが存在するかどうかのチェックをするべきです。

Sub sample4()
  Dim sBook As String
  On Error Resume Next
  sBook = InputBox("ブック名を入力してください。")
  If Dir(ThisWorkbook.Path & "\" & sBook) = "" Then
    MsgBox sBook & "は存在しません。"
  Else
    Workbooks.Open ThisWorkbook.Path & "\" & sBook
    MsgBox sBook & "を開きました。"
  End If
End Sub

Dir関数で、ファイルが存在するか確認し、
存在する場合のみブックOpenしています。

シートの存在確認
Sub sample5()
  Dim sSheet As String
  sSheet = InputBox("シート名を入力してください。")
  Worksheets(sSheet).Select
End Sub

存在しないシートを選択したときはエラーとなります。

MOS VBA エキスパート 参考画像

このエラーへの対応は、以下のようにします。

Sub sample6()
  Dim sSheet As String
  On Error GoTo Err01
  sSheet = InputBox("シート名を入力してください。")
  Worksheets(sSheet).Select
  MsgBox sSheet & "を選択しました"
  Exit Sub
Err01:
  MsgBox sSheet & "は存在しません。"
End Sub

Sub sample7()
  Dim sSheet As String
  On Error Resume Next
  sSheet = InputBox("シート名を入力してください。")
  Worksheets(sSheet).Select
  If Err.Number = 0 Then
    MsgBox sSheet & "を選択しました"
  Else
    MsgBox sSheet & "は存在しません"
  End If
End Sub

上記の2つのVBAは、どちらも同じことをしています。
On Error GoToとOn Error Resume Nextの違いだけです。

これらは、シートを選択してエラー発生したらメッセージを出しています。

しかし、そもそも存在しないシートを選択していることが間違いです。
シート選択の前に、そのシートが存在するかどうかのチェックをするべきです。

Sub sample8()
  Dim sSheet As String
  Dim sht As Worksheet
  Dim flg As Boolean
  On Error Resume Next
  sSheet = InputBox("シート名を入力してください。")
  flg = False
  For Each sht In Worksheets
    If LCase(sht.Name) = LCase(sSheet) Then
      flg = True
      Exit For
    End If
  Next
  If flg = True Then
    Worksheets(sSheet).Select
    MsgBox sSheet & "を選択しました"
  Else
    MsgBox sSheet & "は存在しません"
  End If
End Sub

For Eachで、ワークシート コレクションを処理しています。
指定のシート名があれば、flgにTrueを入れています。
flgはBoolean変数で、TrueかFalseだけが入るデター型です。

シート名は大文字小文字を区別しないので、
判定時にLCaseで小文字に統一してから判定しています。

シートが存在した場合(flg=True)のみシートを選択するようにしています。

※試験対策としては、これくらいのVBAがすんなり読めるようになっておきましょう。

演算エラー対応の演習
Sub sample11()
  Dim i
  Dim j As Integer
  i = InputBox("データを入力してください")
  j = i + 100
  MsgBox j
  j = 10000 / i
  MsgBox j
End Sub

このマクロを実行した時、
入力した値によっては、以下のエラーが発生します。


計算できない文字列を計算したり、
数値のデータ型変数に文字列を入れた時はエラーとなります。

MOS VBA エキスパート 参考画像

0で割り算した時はエラーとなります。

MOS VBA エキスパート 参考画像

データ型の範囲外の数値(Integerに40000等)を入れた時はエラーとなります。

MOS VBA エキスパート 参考画像

演習として、以下に取り組んでみましょう。

このマクロを、
On Errorでエラー対応してみましょう。
そして、
On Errorを使わずに、エラー発生しないように対応してみしょう。
数値かどうかの判定は、IsNumeric関数を使います。

このエラー対応のVBAが書けることは、スタンダード合格としては最低限のレベルになります。
もし、これが書けないようであれば、もう一度最初から学び直してください。

【業務改善の実務】

VBAコードを見たとき、
エラー対応を考えて書かれているかどうかは直ぐに分かります。
そして、
どのように対応しているかを見れば、その人のVBAスキルがはかれます。
まさに、VBA上級者としては腕の見せ所でもあります。

しかし、
むやみやたらにエラー対応すれば良いというものではありません。
例えば、
シートを扱う時に、毎回シートの存在チェックをする必要があるかという事です。
シートを削除したらマクロが動かなくなることは、誰でもわかることです。
もし、それさえ分からない人が使うブックなら、ブックを保護しておくべきなのです。
従って、本来あるべきシートが存在しているかのチェックをすることの是非は考えるべきです。

Excelでシステムを作る場合は、使用者に最低限のExcel知識を教えるべきであり、
決まりを守って使う事を前提として、マクロ作成することがトータルコストの削減になります。

【本サイト内の関連ページ】

第60回.エラー処理(On Error)
・マクロVBAのエラー発生例 ・エラー処理のステートメント ・実行時エラー関連記事
第61回.「On Error Go To」と「Exit Sub」
・On Error GoTo 行ラベル ・Exit Sub ・On Error の有効範囲とその動作について ・最後に
第62回.「On Error Resume Next」とErrオブジェクト
・On Error Resume Next ・Errオブジェクト ・On Error Resume Next の使用例 ・「On Error Resume Next」の最後に

実行時にトラップ可能なエラー番号一覧と対処
・マクロVBAでのエラーとは ・VBA実行時のエラー番号一覧 ・実行時にトラップ可能なエラー番号一覧の最後に
よくあるVBA実行時エラーの解説と対応
・データ型のエラー ・計算時のエラー ・インデックスのエラー ・オブジェクトの設定エラー ・メソッド・プロパティのエラー ・引数のエラー ・実行時エラー関連記事

VBAエキスパート公式テキスト

2019/5/30発売リニューアル版


2019/7/26発売リニューアル版

こちらは必須として購入した方が良いでしょう。
ちょっと高いなーとは思いますが、
書籍を購入することで、学習用データが提供されています。
・サンプルブック
・VBAエキスパート模擬問題
これらが使えるようになります。
このシリーズでは、テキストを読みながら学習していることを前提とします。



同じテーマ「VBAエキスパート対策」の記事

プロシージャ
イベント
ステートメント(スタンダード)
関数
エラーへの対処
APIとOLEオートメーション
変数と配列
レジストリの操作
ファイルの操作
ユーザーフォームとメニューの操作
VBAスタンダード試験対策まとめ


新着記事NEW ・・・新着記事一覧を見る

ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
累計を求める数式あれこれ|エクセル関数応用(2024-01-22)
複数の文字列を検索して置換するSUBSTITUTE|エクセル入門(2024-01-03)
いくつかの数式の計算中にリソース不足になりました。|エクセル雑感(2023-12-28)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.RangeとCellsの使い方|VBA入門
4.ひらがな⇔カタカナの変換|エクセル基本操作
5.繰り返し処理(For Next)|VBA入門
6.変数宣言のDimとデータ型|VBA入門
7.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
8.並べ替え(Sort)|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.Findメソッド(Find,FindNext,FindPrevious)|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。


このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ