VBA 例外処理をしたい
IT企業に入って初の仕事は無限にExcelを使う仕事だったので、少しでも楽するためにVBAを覚えたくなった
そんなVBAを覚えたての自分はこんなプログラムを書いた
Dim TypeNum As Integer
TypeNum = InputBox("区分を整数で入力")
If TypeNum <> 999 Then
'処理
End If
このInputBoxのキャンセルボタンを押したり、文字を入れたりエンターの連打癖があると
すぐにエラーが起こってしまう。
CInt(InputBox(".....")) とかやってみたり、aをVariantにしてみたり色々試したけど、全然直る気配がなかったので
仕方がないから例外処理を勉強することにした。
On Error ステートメント
VBA 例外処理 で調べたら
On Error GoTo ラベル名
処理
ラベル名:
例外処理
っていうのがいっぱい出てきた。とりあえずの疑問事項は...
「ステートメントってなんだ???」だった。
ステートメント・・・関数ではない命令の事。SubとかDimとかIfとか色々該当する
ステートメントについて多少は理解した。あと
・On Errorの構文(?)
・例外処理ではErrオブジェクトが使える
・GoToはあんまり使っちゃダメ
という情報をゲットしたので、とりあえず実装をしてみることにした。
めっちゃエラー出る
とりあえず書いてみたプログラムがこれ
Function TypeInputCheck() As Boolean
TypeInputCheck = True
(省略)
Dim TypeNum As Integer
On Error GoTo InputError
TypeNum = InputBox("区分を整数で入力")
If TypeNum <> 999 Then
'処理
End If
(省略)
InputError:
MsgBox("エラー!整数で入力してください!")
TypeInputCheck = False
Exit Function
End Function
めっちゃエラー出た。しかも整数を入力してもエラーが出るようになった....
あ、そういえばエラーコードごとに処理を分岐させたらいけるか?
InputError:
If Err.Number = 13 Then
MsgBox("エラー!整数で入力してください!")
Else
MsgBox("エラー!処理を中断します。")
End If
TypeInputCheck = False
Exit Function
End Function
・・・・・・・・?
罠?
例外処理について何も分からなくなってきたので、Gotoについて調べてみたら気が付いた。
GoTo・・・ラベル名の位置に移動できる
GoTo ラベル名
ラベル名:
処理
処理
( ゚д゚)ハッ!もしや....
出勤して早速、以下に編集した
InputError:
If Err.Description <> "" Then
If Err.Number = 13 Then
MsgBox("エラー!整数で入力してください!")
Else
MsgBox("エラー!処理を中断します。")
End If
TypeInputCheck = False
Exit Function
End If
End Function
直った!!!!!!!!!
原因として、On Error ~~ GoTo -- は
「エラーが起こったら処理を飛ばして、GoToのラベル名の位置から再開するよ」っていう意味だったのを
「エラーが起こらなかったらラベル名の下に書いた処理はしない」っていう風に曲解したことだった。
しかも、ステートメントについて全然理解していなかったのが実は一番の敗因で
「関数ではない命令...?定義とかできるの?」とか考えてた矢先の
ラベル名:
例外処理
っていう見た事無い書き方に出会ったからこそ、起こった勘違いだと思う。
## 反省
実はリーダブルコードも読んだことがあるし、高校でユーザーフォームを使ったVBAは経験していたから、
その時に「GoToはあまり使わない方がいい」
っていう知識があったから、使わなそうなGoTo文は記憶の片隅の片隅にしか無かった
「使わなそうな文だから勉強はそこそこでいい」
「あまり好きじゃないから知らなくていい」
という考え方は、おおよそもれなく、沼に落ちるという事を今後の教訓にしたい...