質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

2回答

3971閲覧

Excel VBAのエラー処理(On Error Resume Nextの処理)がうまくいきません

exnjinia

総合スコア16

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2020/04/17 14:25

Excel VBAのエラー処理(On Error Resume Nextでの処理)について

Excel VBAの勉強をしています。
エラー処理の練習として、次のコードを書いたところ、自分の予想と違う処理となりました。

●自分の予想
e002ラベルの処理の後、exit_handleラベルの処理に飛び、Exit Subによってプロシージャが終わる。

●実際の挙動
e002ラベルの処理の後、exit_handleラベルの処理には飛ばず、End Subによってプロシージャが終わる。

なぜ「実際の挙動」の動きをするのか、理由をご存知の方教えていただけないでしょうか。

ちなみに、On Error Resume Next を On Error GoTo e002 にした場合、なぜか「自分の予想」通りの動きができました。理由は分かりません・・・

また、あくまで On Error Resume Next を使用した上で、自分がやりたいこと(「自分の予想」の動き)をすることは可能でしょうか。
可能であれば、コードをどのように書き換えればよいでしょうか。

VBA

1Sub test() 2 3On Error GoTo e001 4 5Worksheets("存在しないシート").Select 6 7On Error GoTo 0 8 9from_e001: 10 11'★ここを On Error Resume Nextではなく、 On Error GoTo e002 にするとなぜか「自分の予想」どおりの動きができる。 12On Error Resume Next 13 14 Worksheets("存在しないシート").Select 15 16 If Err.Number <> 0 Then 17 18 MsgBox "ここはResume内部でエラーした場合の処理です" 19 MsgBox "ここからエラーe002ラベルに飛びます" 20 GoTo e002 21 22 End If 23 24 MsgBox "エラーなくここまで来たので、最後に終了処理に入ります。" 25 26On Error GoTo 0 27 28GoTo exit_handle 29 30exit_handle: 31 32 On Error Resume Next 33 MsgBox "終了処理をします!" 34 On Error GoTo 0 35 Exit Sub 36 37e001: 38 39 MsgBox "エラー処理(e001ラベル)に飛びました" 40 MsgBox "ここからResumeによって元の処理の続きに行きます" 41 Resume Next 42 43e002: 44 45 MsgBox "エラー処理(e002ラベル)に飛びました" 46 MsgBox "ここから終了処理(exit_handle)に飛びます" 47 Resume exit_handle 48 49End Sub 50 51 52

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Resume exit_handleは、エラーになっています。エラー処理中じゃ無いところでResumeを実行したというエラーです。
この時点では、On Error Resume Nextが有効なので、そのエラーで止まりませんが、次の行でErr.Numberを見ると該当する20になっているのが分かります。

On Error Goto xxxxで飛んだ先ではResumeするまでエラー処理中ですが、On Error Resume Nextすると、エラーが発生した時点で次の命令にResumeしています。
次の命令に移った時点ではエラー処理中では無いので、(その後でGotoしようがどうしようが)Resume命令は実行できません。

可能であれば、コードをどのように書き換えればよいでしょうか。

ResumeではなくGotoすればいいかと。

投稿2020/04/17 14:53

編集2020/04/17 14:55
otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

exnjinia

2020/04/18 10:48

理由がよく理解できました。 とても分かりやすい回答ありがとうございました。
guest

0

また、あくまで On Error Resume Next を使用した上で、自分がやりたいこと(「自分の予想」の動き)をすることは可能でしょうか。

今回の件の場合、On Error Resume Nextは適さないんじゃないんですかね?

出口(Exit sub)を一つに纏めたい意図はわかりますし、そうすることは正解でしょう。
ですが、Gotoでとんだ先でまたGotoで飛ぶというのは、
俗にいうスパゲティコードと呼ばれるものではないでしょうか?
それを避けるためにOn Error Resume Nextと言われているのかなぁとは
思いますが。。。
あと、出来るだけエラーを無効にしておく範囲も狭めておかないと、
想定外のエラーが見つからず、デバッグに苦労することになると思います。

エラーが発生したかどうかは、エラーナンバーを変数に記録してやれば、
後からでも判別可能です。

ExcelVBA

1Sub test() 2 Dim e As Long 3 4 On Error GoTo e001 5 Worksheets("存在しないシート").Select 6 On Error GoTo 0 7 8from_e001: 9 '★ここを On Error Resume Nextではなく、 On Error GoTo e002 にするとなぜか「自分の予想」どおりの動きができる。 10 On Error GoTo e002 11 Worksheets("存在しないシート").Select 12 On Error GoTo 0 13 14 If e = 0 Then 15 MsgBox "エラーなくここまで来たので、最後に終了処理に入ります。" 16 Else 17 MsgBox "e002へ飛びました。" 18 End If 19 20exit_handle: 21 MsgBox "終了処理をします!" 22 Exit Sub 23 24e001: 25 MsgBox "エラー処理(e001ラベル)に飛びました" 26 MsgBox "ここからResumeによって元の処理の続きに行きます" 27 Resume Next 28 29e002: 30 MsgBox "エラー処理(e002ラベル)に飛びました" 31 MsgBox "ここから終了処理に飛びます" 32 e = Err.Number 33 Resume Next 34End Sub

投稿2020/04/18 00:20

編集2020/04/18 00:26
mattuwan

総合スコア2163

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

exnjinia

2020/04/18 10:50

エラーハンドリングの方法を考えるうえで参考になります! 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問