はじめに
ITに詳しくない人でも便利に触れるExcelはいろんなところで使われています。
そのために肥大化して邪悪でアンタッチャブルなExcelになる場合もありますが、健全な良識をもってすればそこそこ手軽に便利で使えることはご理解いただけるかと思います。
こうして使われているExcelを処理するのにVBAは手軽でExcel操作を自動化できてよいのですが、近代的な言語と比べると機能性に難があります。
そのひとつとして、繰り返し文中でのスキップをするために、よくある言語で利用されるcontinueがないことや、エラーハンドリングがしにくいことがあったりします。
なんか公式のドキュメントもわかりにくいし、調べて出てきたサンプルもいけていなかったのでちょっと試行錯誤してサンプルを書いてみたので、1時間前の自分が知りたかった情報を書きとどめておく次第です。
サンプルコード
- 前提:シートSheet1、Sheet2、Sheet4、Sheet5があるExcel
- 期待の動作:実行しているExcelのSheet名を取得し連結して、メッセージを出力する。
Sheet名は「Sheet連番」としているが、Sheetが存在しない場合、スキップして次のSheetに移る。
'' エラー処理サンプル
Sub sampleError()
Dim i As Long, buf As String
'' エラー発生時にラベル「SHEETOPENERROR」まで飛ばす。
'' On Errorステーツメントについて:https://msdn.microsoft.com/ja-jp/library/5hsw66as(v=vs.90).aspx
On Error GoTo SHEETOPENERROR
For i = 1 To 5
'' シートの名前を取得していく
buf = buf & Worksheets("Sheet" & i).Name & vbCrLf
'' 2行上の処理でエラー発生した場合、本行は処理されない
MsgBox "進捗" & i
'' エラーラベル。VBEで自動でインデントなしになる・・・
SHEETOPENERROR:
'' 注意:エラーラベル以降はエラーがない場合も通るので、エラー有無を確認する
'' Err オブジェクトは、グローバル スコープを持つ組み込みオブジェクトです https://msdn.microsoft.com/ja-jp/library/ka13cy19%28v=vs.90%29.aspx
If Err.Number <> 0 Then
'' Err.Numberでエラー番号、Err.Descriptionでエラーの内容を取得できる。
'' とはいえ、一般利用者がユーザが見ても理解できないことが多いので発生しうる例外については説明しておく。この例ではスキップ(continue的処理)しているが、停止の必要があればEndする
MsgBox "Sheet= " & i & "を開く際にエラーが発生したためスキップします。シートが存在しない可能性があります。" & vbCrLf & "エラー番号:" & Err.Number & vbCrLf & "エラー内容:" & Err.Description, vbExclamation
'' .Clearしないとエラーを保持し続けるため
Err.Clear
End If
Next i
'' エラー発生時にラベル移動する処理を停止する
On Error GoTo 0
MsgBox buf
End Sub
(追記)
コメントにてご指摘いただきましたが「On Error GoTo 」は1回した動作しないことがわかっています。
コメントソースの通り、プロシージャとして切り出す必要がありますのでご注意ください。