【EXCEL VBA】エラーを適切に処理する

スポンサーリンク

エラーの種類

記述エラー

VBAの構文に違反した書き方をした場合に発生するエラー(文法エラーとも呼ばれる)

論理エラー

記述エラーは無いけど、論理矛盾が起こっている場合に発生するエラー。論理エラーには”コンパイルエラー””実行時エラー”がある。

コンパイルエラーは、VBAコードをコンパイルする時に論理矛盾が発生するとコードを実行する前に発生します。

実行時エラーは、コードを実行して初めて分かるエラーです。指定しているシートが無いとか、配列の要素数がおかしいとかそんな感じです。

Errオブジェクト

エラーが発生すると、VBAはエラーに関する情報を”Errオブジェクト”に格納します。

Errオブジェクトのプロパティ

Noプロパティ名説明
Descriptionエラーに関連付けられている説明を取得または設定する。
HelpContextヘルプファイルのトピックに対応するコンテキストIDを含む文字列式を取得するか設定する。
HelpFileヘルプファイルへの完全修飾パスを含む文字列式を設定または取得します。
Numberエラー番号の取得または設定する。
Source最初にエラーを生成したオブジェクトまたはアプリケーションの名前を指定した文字列を取得または設定する。

次のコードを実行してエラーを発生させてみましょう。

実行しているEXCELブックには、「エラーシート」という名前のシートは無いとします。

Sub sample()

    'シートの指定
    Dim sheet As Worksheet
    Set sheet = ThisWorkbook.Sheets("エラーシート")
   
End Sub

指定したシート名が無いので、次のようなエラーが発生します。

この図で言う、「9」が④のNumberプロパティ、「インデックスが有効位な範囲にありません。」が①のDescriptionになります。

他のプロパティもイミディエイトウィンドウで調べてみましょう。

エラーのポップアップの「デバッグ」ボタンを押します。

エラーの場所の色が変わると思います。

イミディエイトウィンドウでプロパティを確認するには、その状態で

?Err.プロパティ名

あるいは、

Debug.Print Err.プロパティ名

を入力します。

「?」は「Debug.Print」の意味です。

1行入力するごとに、Enterで決定するとその行が実行出来ます。

次のコードを入力して、それぞれ実行してみます。

?Err.Description
インデックスが有効範囲にありません。

?Err.HelpContext
 1000009 

?Err.HelpFile
C:\Program Files\Common Files\Microsoft Shared\VBA\VBA7.1\1041\VbLR6.chm

?Err.Number
 9

?Err.Source
VBAProject

それぞれのプロパティの中身が出てきましたね(^o^)

”Description”と”Number”はよく使うので覚えておいてください。

エラーが発生したときの処理

記述エラーやコンパイルエラーは、通常開発時に修正することが出来ますが、実行時エラーは厄介です。

作ったEXCELツールがシートの値を参照している場合など、ユーザーが予期せぬ入力を行ったり、適切に運用がされなかった場合にも発生します。

エラーが発生した際は、VBEからのメッセージとともに、コードの実行が止まります。VBAを理解している人ならば適切に処理出来ますが、VBAを知らない人には処理するのは難しいでしょう。

VBAは、エラーが発生したことを検知するために、On Errorステートメントが用意されています。

代表的な使い方は、次の2つです。

  • On Error Goto ラベル
  • On Error Resume Next

On Error Goto ラベルは、エラーを検知したら、ラベルまで次の処理を飛ばします。

先程サンプルコードに、On Error Gotoを付け加えます。

Sub sample()

On Error GoTo Catch

    'シートの指定
    Dim sheet As Worksheet
    Set sheet = ThisWorkbook.Sheets("エラーシート")
    
    
    Debug.Print "正常終了"
    Exit Sub   ' 正常終了したときはここで終わり
    
    
Catch:
    Debug.Print "エラーが発生したよ"
    
End Sub

ここでは、ラベルを「Catch」としています。このラベルの名前は任意でOKです。分かりやすい名前にしておきましょう!

14行目に「Catch:」とありますが、これがエラーが発生した時に飛んでくるラベルの場所です。ラベル名に続けて「:」を付けてください。

その後に、エラーの場合の処理を記入します。

また、エラーが発生しなかった場合、ラベルの処理を行わないように、ラベルの前でプロシージャを終了させる必要がありますね。

”Exti Sub”を記述することで、ここでプロシージャの処理を終了させることが出来ます。

実行動画を見てみましょう!

最初にエラーが発生するバージョン、次に実際に存在するシート名に変更して、エラーが発生しないバージョンです。

On Error Resume Nextは、エラーを検知したら、無視して次の処理に進みます。

「エラーシート」というシートが無いEXCELブックで次のコードを実行します。

※エラーになります。

Sub sample()

On Error Resume Next

    'シートの指定
    Dim sheet As Worksheet
    Set sheet = ThisWorkbook.Sheets("エラーシート")
    
    Debug.Print "無視して突き進むよ"
    
End Sub

通常エラーで止まってしまうところを、無視して突き進みましたw

Errオブジェクトをクリアする

Errオブジェクトに格納されたエラー情報は、プロシージャが終了するまで保持されます。

複数のOn Errorステートメントを利用したい場合は、前のエラー情報をClearメソッドで削除しておく必要があります。

Err.Clear

これでOKです。

スポンサーリンク

まとめ

エラーが発生した場合、On Error Gotoで飛ばして、メッセージボックスにエラー情報に加えて「開発担当に連絡してください」と表示するようにしたり、エラー番号によってその後の処理を分けたりなど、場合によっていろいろな処理が出来ると思います(^o^)

コメント

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