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

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

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

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

Q&A

解決済

1回答

7349閲覧

VBAのクラスを使ったエラー処理について

退会済みユーザー

退会済みユーザー

総合スコア0

VBA

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

0グッド

0クリップ

投稿2018/11/30 04:48

質問

以下のようなコードを実行した時に、VBEのオプションで設定が「クラスモジュールで中断」になっていると、クラスモジュール中のErr.Raiseで中断してしまいます。

標準は「エラー処理対象外のエラーで中断」なのでユーザー環境では問題ないのですが、開発環境だと上記設定にしておかないとデバッグが大変です。

このようなRaiseを使った書き方は不適切なのでしょうか。

VBA

1'Module1 2 Sub main() 3 Dim cls As Class1 4 Set cls = New Class1 5 Dim i As Long 6 7 Debug.Print "---開始---" 8 For i = 1 To 5 9 On Error GoTo ErrHandle 10 Debug.Print cls.CheckNum(i) 11 GoTo NoErr 12ErrHandle: 13 Debug.Print "エラー:" & Err.Description 14 Resume Next 15NoErr: 16 '処理続行 17 Next 18 Debug.Print "---終了---" 19End Sub

VBA

1'Class1 2 Public Function CheckNum(i As Long) As Long 3 If i Mod 2 = 0 Then 4 Err.Raise 9999, "CheckNumのエラー", "偶数は認めません。" 5 Else 6 CheckNum = i 7 End If 8End Function

代替案

クラス中で発生したエラーをクラス変数に格納しておいて見かけ上は正常に完了させた上で、後からチェックするような案を考えてみたのですが、これは呼び出し元がチェックを怠る可能性があるため不適切だと思います。

どのような書き方が適切なのでしょうか。

VBA

1'Module1 2Sub main2() 3 Dim cls As Class1 4 Set cls = New Class1 5 Dim i As Long 6 7 Debug.Print "---開始---" 8 For i = 1 To 5 9 Dim V As Variant 10 V = cls.CheckNum2(i) 11 If cls.Result = "" Then 12 Debug.Print V 13 Else 14 Debug.Print "エラー:" & Err.Description 15 End If 16 '処理続行 17 Next 18 Debug.Print "---終了---" 19End Sub

VBA

1'Class1 2Public Result As String 3 4Public Function CheckNum2(i As Long) As Long 5 If i Mod 2 = 0 Then 6 Result = "偶数は認めません。" 7 Else 8 Result = "" 9 CheckNum2 = i 10 End If 11End Function

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

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

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

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

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

guest

回答1

0

ベストアンサー

そもそもCheckNum2の役割が中途半端な気がします。
関数名からしてチェックだけする役割にするべきかと。
引数の値を返却しているから面倒な作りになっていないでしょうか。
要はOK/NGだけ返却すればいいと思います。
エラーメッセージも受け取りたいなら、代替案のようにグローバル変数にメッセージを格納してもいいし、引数で受け取ってもいいし。
私ならプライベート変数にしてメソッド経由で受け取ります(折角クラスなので)。

VBA

1Sub main() 2 Dim cls As Class1 3 Set cls = New Class1 4 Dim i As Long 5 6 Debug.Print "---開始---" 7 For i = 1 To 5 8 If cls.CheckNum(i) Then 9 Debug.Print cls.CheckNum(i) 10 Else 11 Debug.Print "エラー:" & cls.GetResult() 12 End If 13 Next 14 Debug.Print "---終了---" 15End Sub 16 17'Class1 18Private Result As String 19Public Function CheckNum2(i As Long) As Boolean 20 CheckNum2 = (i Mod 2 <> 0) 21 Result = "" 22 If Not CheckNum2 Then 23 Result = "偶数は認めません。" 24 End If 25End Function 26 27Public Function GetResult() As String 28 GetResult = Result 29End Function

Resultは普通に書いちゃいましたが、Propertyを使ったほうがいいかもしれません。

投稿2018/11/30 06:10

ttyp03

総合スコア16998

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

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

退会済みユーザー

退会済みユーザー

2018/11/30 10:46

「そもそもCheckNum2の役割が中途半端な気がします。」 質問ように適当に書いたので意味不明なことをしていました。本当はもっと複雑な計算結果を返す関数と考えて頂ければと思います。 いっその事、自身のインスタンスを返してプロパティに計算結果とResultを残すのが無難でしょうか・・・? >Propertyを使ったほうがいいかもしれません。 おっしゃる通りだと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問