VBA のエラートラップ
Try 〜 Catch は使えない
エラートラップと言えば「Try 〜 Catch」と言うほど有名ですが、VB系では VB.net からの実装です。
.net ではない VB や、VBA では、使えません。
その代わりに使うのが、On Error Goto
やOn Error Resume Next
です。
しかし、これらは下記の様なエラートラップのネストが出来ません。
頑張ればそれっぽい事が出来ますが、非常にソースが汚くなります。
Try
’処理1
Try
’処理2
Catch ex
'処理2の例外処理
End Try
’処理3
Catch ex
'例外処理
End Try
えっ!? 今時 Goto?
Go To Eat じゃないですよ?
On Error Goto
をみて「Gotoかよ!」と思った方も多いでしょう。
Goto の是非は嫌と言うほどされてきましたし、理解して適度に使えば、問題ない、いや絶対に使ってはいけないなど色々言われてきましたし、私もどちらが正しいか分からないですが、VBA のエラートラップを使うと便利な時があるのは確かです。
VBA のエラートラップの有効な使い方
Excel のワークシートの有無を確認する
Excel のワークブック内に、指定の名前のワークシートが存在するのを確認する方法は、下記の様にワークシートの数分だけループを行い、見つけたら抜ける、最後までループしたら存在しない、という形になると思います。
またワークシート名は大文字と小文字を区別しない為、大文字(又は小文字)に変換して比較する必要があります。
'ワークシートの有無を確認
Private Function Check_WorksheetExsist(ByRef objWb As Workbook, ByRef strWsName As String) As Boolean
Dim objWs As Worksheet
Check_WorksheetExsist = True
For Each objWs In objWb.Worksheets
If UCase(objWs.Name) = UCase(strWsName) Then
Exit Function
End If
Next objWs
Check_WorksheetExsist = False
End Function
これでも良いのですが、もっと簡単に確認する方法もあります。
'ワークシートの有無を確認
Private Function Check_WorksheetExsist(ByRef objWb As Workbook, ByRef strWsName As String) As Boolean
On Error GoTo Err_Check_WorksheetExsist
Dim objWs As Worksheet
Check_WorksheetExsist = False
Set objWs = objWb.Worksheets(strWsName)
Set objWs = Nothing
Check_WorksheetExsist = True
Err_Check_WorksheetExsist:
End Function
短いですし、ループを回さないので、無駄が無いです。
If 文も無いので、エラートラップの例外で時間がかかる部分も相殺されるでしょうから、シートが多ければこちらの方が高速になります。
ミソは Set objWs = objWb.Worksheets(strWsName)
の部分。
そのシートが存在しなければ、エラーとなり Err_Check_WorksheetExsist:
に飛びます。
存在すれば、そのまま最後まで処理が行われます。
エラートラップを、一時的に無効化したい!
On Error Goto
や On Error Resume Next
はエラートラップ処理をしたい時には必須ですが、テスト時にはどこでエラーが発生しているかの確認がしにくくなるため、一時的に無効化したい事があると思います。
その際はVBE(VBA の IDE) の設定を変更する事で無効化出来ます。
- VBE のメニューバーから「ツール」-「オプション」を選択
- 開かれたオプションウィンドウから「全般」タグを選択
- 「エラートラップ」の項目の「エラー発生時に中断」を選択
これで、On Error Goto
や On Error Resume Next
が無効になります。
きっかけは On Error Resume Next
が効かないPCがあった事
このことを知ったきっかけは、On Error Resume Next
がうまく機能しないPCがあったからでした。
そのマシンでだけ、Excel のマクロがエラーになるとの事で、デバッグで調べてみた結果、直前で指定されている On Error Resume Next
が機能していないことが発覚、恐らくエラートラップ絡みの設定だろうという事で調べた所、当該の情報にたどり着きました。
便利な機能ですが、設定を変えたら戻しておかないと、大変な事になりますね。