VBAを操作していると、自身の記述ミスだけに限らず、様々なケースでエラーが発生する可能性があります。
そこで今回は、エラーが起きた際の処理の仕方について、詳しく解説をしていきたいと思います。
エラー処理とは?
例えば、複数のファイルを読み込む作業をしている途中に壊れたファイルが紛れていたり、特定の範囲から値を検索する処理で値が見つからなかったりと、プログラムの実行中に意図しない処理が挟まることはよくあります。
予期せぬエラーで処理が中断されてしまったり、思わぬ不具合に繋がることがないように、事前にエラーが起きた場合の処理を設計しておくことを、エラー処理と言います。
エラーが起きた場合の処理を実装する方法
エラー処理の仕方についてはいくつか方法がありますが、いずれもOn Errorステートメントを使って処理をします。
ステートメントを先に記述しておくことでエラー処理が有効になり、以降のコードでエラーが発生した際に、指定した内容でエラー処理を行うことができます。
On Errorステートメントの種類は主に以下の3つです。
- On Error GoTo ラベル:指定のラベル先に処理をスキップする
- On Error Resume Next:エラーを無視して次の行から処理を続ける
- On Error GoTo 0:有効化したエラー処理を無効にする
具体的な使い方について、サンプルコードを踏まえながら実際に見ていきましょう。
GoToでエラーをスキップする
まず初めに、GoToステートメントについて解説をしていきます。
GoToステートメントは、記述時に任意のラベルを指定することで、エラーが発生した際にそのラベル先へと処理をスキップさせる方法です。エラー内容をログに表示させるなど、処理したい内容をラベル先に記述してエラー処理を行います。
使用するには、以下のようにラベルと1セットで記述します。
【基本構文】
On Error GoTo ラベル名
(通常処理)
Exit Sub
ラベル名:
(エラー発生時の処理)
実際のサンプルコードで確認してみましょう。
【サンプルコード】
Sub sampleGoTo()
On Error GoTo ErrLabel
Dim result As Double
'0で割るのでエラーが発生
result = 1 / 0
MsgBox "答えは " & result & " です"
Exit Sub
ErrLabel:
MsgBox "エラーが発生しました"
End Sub
【実行結果】
0で割ったことによりエラーが発生し、そのすぐ下にあるメッセージではなく、ラベル部分に記載したメッセージが表示されているのが分かると思います。
このように、GoToステートメントを使うことで、任意の処理へとスキップさせることができます。
Resumeで処理を続行する
先ほどのサンプルコードでは、エラーが発生してラベル先へとスキップした後、エラー処理が終わった段階でプログラムの実行も終了していました。
そのままで問題ないパターンも勿論ありますが、場合によっては処理を継続したいケースも出てくると思います。その際には、Resumeステートメントを使うことで、エラーが発生した行やその次の行から処理を再開することができます。
「Resume」と記述すると発生した行に、「Resume Next」と記述するとその次の行から継続することができます。今回は、「Resume Next」を使用した場合のサンプルを確認してみましょう。
【サンプルコード】
Sub sampleResume()
On Error GoTo ErrLabel
Dim result As Double
'0で割るのでエラーが発生
result = 1 / 0
'Resume Nextで処理を継続
result = 10 / 2
MsgBox "答えは " & result & " です"
Exit Sub
ErrLabel:
MsgBox "エラーが発生しました"
Resume Next
End Sub
【実行結果】
【処理再開後】
基本は先ほどのサンプルコードと同じですが、ラベル先の処理にResume Nextステートメントを追加し、エラー処理後に別の計算結果を変数に代入するよう追記しています。
その結果として、エラーメッセージを表示する処理がされた後に、新たに計算結果がメッセージで表示されるようになりました。
ループ中のエラーはどうやって処理する?
ループ中にエラー処理を行う場合も、先ほど述べたResume Nextステートメントを使って処理をします。
サンプルコードを見てみましょう。
【サンプルコード】
Sub sampleLoop()
On Error GoTo ErrLabel
Dim Msg As String
For num = 0 To 2
Msg = Msg & "答えは " & 2 / num & " です" & vbCrLf
Next num
MsgBox Msg
Exit Sub
ErrLabel:
Msg = Msg & "エラーが発生しました" & vbCrLf
Resume Next
End Sub
【実行結果】
今回は、ループ内で割り算をした結果をメッセージに表示するサンプルコードを用意しました。固定の数字をカウント数で割り、その結果を文字列に追加していますが、ループのカウントを0から始めているためエラーが起こっています。
Resume Nextステートメントを使用することで、エラー発生時の処理を行った後にループ処理が再開され、その結果が文字列に追加することができました。
エラーメッセージを取得する方法
エラーが発生した際、Errオブジェクトのプロパティから情報を取得することで、コード番号やエラー内容を確認することができます。
【プロパティ一覧】
プロパティ | 内容 |
Description | エラーの説明 |
HelpContext | ヘルプファイルのコンテキストID |
HelpFile | ヘルプファイルへの絶対パス |
Number | エラーを示す数値 |
Source | エラーを発生させたオブジェクト、またはアプリ名 |
以下のサンプルコードで取得方法を確認してみましょう。
【サンプルコード】
Sub sampleErrMsg()
On Error GoTo ErrLabel
Dim result As Double
'0で割るのでエラーが発生
result = 1 / 0
MsgBox "答えは " & result & " です"
Exit Sub
ErrLabel:
MsgBox "エラー番号: " & Err.Number & vbCrLf & _
"エラー内容: " & Err.Description
End Sub
【実行結果】
このサンプルコードでは、ErrオブジェクトのNumberプロパティとDescriptionプロパティを使ってエラーメッセージを表示しています。
このように、エラーが発生した段階でメッセージを取得しておくと、原因をすぐに確認できるようになるのでとても便利です。
エラーの種類に応じて実装する処理を変えよう
先ほど紹介したNumberプロパティを使って、発生するエラー内容ごとに処理を変える方法も存在します。
エラー番号に応じて処理を変える際は、Select Caseステートメントを使います。
【記述例】
Select Case 変数
Case 条件式1
処理1
Case 条件式2
処理2
Case Else
デフォルト処理(どの条件にも一致しない場合)
End Select
変数の部分にNumberプロパティを指定し、条件式にそれぞれ対応したいエラー番号を記述して、ケースごとに処理を分けます。
以下がサンプルコードです。
【サンプルコード】
Sub sampleSelectCase()
On Error GoTo ErrLabel
Dim result As Double
Workbooks.Open ("Sample.xlsx")
result = 1 / 0
Exit Sub
ErrLabel:
Select Case Err.Number
Case 11
MsgBox "0で割ることはできません"
Case 1004
MsgBox "以下の理由により実行できませんでした:" & vbCrLf & Err.Description
Case Else
MsgBox "予期せぬエラーが発生しました" & vbCrLf & Err.Number & ":" & Err.Description
End Select
Resume Next
End Sub
【実行結果】
存在しないファイルを開こうとした場合には1004番のケースで、0での除算を行おうとした場合には11番のケースで、それぞれエラー処理が行われています。
このように、個別に処理したいケースごとに条件式を定義することで、処理内容を変更することができます。
On Errorを複数回使用する場合はどうする?
これまでのサンプルでは、いずれもOn Errorステートメントを1度だけ記述して処理を行ってきましたが、複数回に渡って使用することも可能です。
既に有効化されているエラー処理の他に、新たに処理を記述したい場合には、On Error GoTo 0ステートメントを使います。
このステートメントを使用することで、有効中のエラー処理を無効にすることができます。
実際のサンプルコードで確認してみましょう。
【サンプルコード】
Sub sampleGoTo0()
On Error GoTo ErrLabel1
Dim result As Double
Dim Msg As String
result = 1 / 0
On Error GoTo 0
On Error GoTo ErrLabel2
Workbooks.Open ("Sample.xlsx")
Exit Sub
ErrLabel1:
Msg = "ErrLabel1が実行されました"
ErrLabel2:
MsgBox Msg & vbCrLf & "ErrLabel2が実行されました"
End Sub
【実行結果】
1つのプロシージャ内で複数のエラー処理を記述する場合は、それぞれのラベルを同じ箇所にまとめて記述をすると、コードが読みやすくなるのでオススメです。
まとめ
今回は、エラー処理の具体的な方法について解説をしてきました。
VBAに限らず、プログラミングを行う上でエラー処理は必須の作業になります。
それぞれの方法について使いこなせるよう、何度も記事を読み返して理解を深めていきましょう!
関連記事
- VBAとは
- Excelで覚えておくべき17の基本関数と目的別逆引き一覧
- オートフィルターの設定・解除方法
- メッセージボックスの設定方法
- セルの値を取得・上書きするValueプロパティの使い方を解説
- 【Excel VBA】Functionの使い方を解説(宣言・引数、戻り値の指定、応用法)
VBAの勉強方法は?
書籍やインターネットで学習する方法があります。昨今では、YouTubeなどの動画サイトやエンジニアのコミュニティサイトなども充実していて多くの情報が手に入ります。
そして、より効率的に知識・スキルを習得するには、知識をつけながら実際に手を動かしてみるなど、インプットとアウトプットを繰り返していくことが重要です。特に独学の場合は、有識者に質問ができたりフィードバックをもらえるような環境があると、理解度が深まるでしょう。
ただ、VBAに限らず、ITスキルを身につける際、どうしても課題にぶつかってしまうことはありますよね。特に独学だと、わからない部分をプロに質問できる機会を確保しにくく、モチベーションが続きにくいという側面があります。独学でモチベーションを維持する自信がない人にはプログラミングスクールという手もあります。費用は掛かりますが、その分スキルを身につけやすいです。しっかりと知識・スキルを習得して実践に活かしたいという人はプログラミングスクールがおすすめです。
プログラミングスクールならテックマニアがおすすめ!
ITスキル需要の高まりとともにプログラミングスクールも増えました。しかし、どのスクールに通うべきか迷ってしまう人もいるでしょう。そんな方にはテックマニアをおすすめします!これまで多くのITエンジニアを育成・輩出してきたテックマニアでもプログラミングスクールを開講しています。
<テックマニアの特徴>
・たしかな育成実績と親身な教育 ~セカンドキャリアを全力支援~
・講師が現役エンジニア ~“本当”の開発ノウハウを直に学べる~
・専属講師が学習を徹底サポート ~「わからない」を徹底解決~
・実務ベースでスキルを習得 ~実践的な凝縮カリキュラム~
このような特徴を持つテックマニアはITエンジニアのスタートラインとして最適です。
話を聞きたい・詳しく知りたいという方はこちらからお気軽にお問い合わせください。