Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


3223 / 13644 ツリー ←次へ | 前へ→

【63464】エラー発生後、次のプロシージャを呼び出さない なみ 09/11/9(月) 9:46 質問[未読]
【63465】Re:エラー発生後、次のプロシージャを呼び... Jaka 09/11/9(月) 10:17 発言[未読]
【63468】Re:エラー発生後、次のプロシージャを呼び... なみ 09/11/9(月) 11:58 お礼[未読]
【63467】Re:エラー発生後、次のプロシージャを呼び... seg 09/11/9(月) 10:59 発言[未読]
【63469】Re:エラー発生後、次のプロシージャを呼び... なみ 09/11/9(月) 13:21 お礼[未読]
【63470】Re:エラー発生後、次のプロシージャを呼び... seg 09/11/9(月) 13:55 発言[未読]
【63472】Re:エラー発生後、次のプロシージャを呼び... でれすけ 09/11/9(月) 21:40 回答[未読]
【63479】Re:エラー発生後、次のプロシージャを呼び... seg 09/11/10(火) 9:28 発言[未読]

【63464】エラー発生後、次のプロシージャを呼び出...
質問  なみ  - 09/11/9(月) 9:46 -

引用なし
パスワード
   どうしても分からなくて投稿しました。

今、下記のようなVBAがあります

Sub Test ()

Call 処理1
Call 処理2
Call 処理3

End Sub

たとえば、処理2でエラーが発生した場合、
処理2のプロシージャ内でエラー処理をしています。
エラー発生したら、処理を中止にしたいのですが、
Callでプロシージャを呼び出している為、
処理2でエラー発生しても、そのまま処理3へ進んでしまいます
これを止める方法はないのでしょうか?

いろいろ考えてますが、いまいち分からず困っています

どうかよろしくお願いします

【63465】Re:エラー発生後、次のプロシージャを呼...
発言  Jaka  - 09/11/9(月) 10:17 -

引用なし
パスワード
   フラグ使っても良いだろうけど、
賛否両論のある、
End ステートメント

【63467】Re:エラー発生後、次のプロシージャを呼...
発言  seg  - 09/11/9(月) 10:59 -

引用なし
パスワード
   ▼なみ さん:
>Sub Test ()
>
>Call 処理1
>Call 処理2
>Call 処理3
>
>End Sub

>処理2のプロシージャ内でエラー処理をしています。
エラー処理は、上位のプロシージャで行って下さい。

>処理2でエラー発生しても、そのまま処理3へ進んでしまいます
>これを止める方法はないのでしょうか?
全体の処理は、処理1/2/3なので、それぞれの関数は、成功したかどうかを
返しましょう。
こんな感じです。

' 概要 :整数Aと整数Bは同じかチェックするプロシージャ
' 戻り値:同じ 0 違う -1
Private Function 処理1(a As Integer, b As Integer) As Integer
  ' 初期化
  処理1 = -1
  
  If (a = b) Then 処理1 = 0

End Function

その戻り値を元に、以下の様に判定しましょう。

Sub test()

  If (処理1 <> 0) Then GoTo ERR_HANDLER
  If (処理2 <> 0) Then GoTo ERR_HANDLER
  If (処理3 <> 0) Then GoTo ERR_HANDLER
  
  Exit Sub
  
ERR_HANDLER:

  ' エラー処理
  
End Sub

【63468】Re:エラー発生後、次のプロシージャを呼...
お礼  なみ  - 09/11/9(月) 11:58 -

引用なし
パスワード
   ▼Jaka さん:
>フラグ使っても良いだろうけど、
>賛否両論のある、
>End ステートメント
 
ありがとうございました
解決しました

【63469】Re:エラー発生後、次のプロシージャを呼...
お礼  なみ  - 09/11/9(月) 13:21 -

引用なし
パスワード
   ▼seg さん:

ありがとうございます

Function の使い方がいまいち把握できていない為、なかなか意味がつかめません・・・

もう少し勉強します

【63470】Re:エラー発生後、次のプロシージャを呼...
発言  seg  - 09/11/9(月) 13:55 -

引用なし
パスワード
   ▼なみ さん:
Functionは重要なので覚えておいた方が良いと思います。

簡単に説明すると、仕事の結果を返す物です。

1.なぜプロシージャを作成する?
 同じ処理を何度も書くのではなく、関数化しておけば必要な時に
 Call ○○ と書けるから。

2.作成したプロシージャは、ちゃんと仕事をしたの?
 例えば印刷プロシージャを作成したとして、メイン処理側で処理が
 完了したので印刷プロシージャをコールし印刷しようとした。
 でも、そいつは正常に印刷したのかがメイン側から解らない。
 なので、正常に仕事をしたのか、不慮の事故にあったのかをメイン側
 (呼び出し側)に返す必要がある。全てではないけど。

3.引数と戻り値って?
 2.の例でいくと、印刷プロシージャは何を印刷すれば解らないので
 印刷するデータが必要。そのデータの事を『引数』という。
 引数を元に印刷処理を完了し、それを呼び出し側に伝える値を『戻り値』
 という。
 VBAの場合、戻り値が欲しい時に『Function』を使用する。
 また、『Function』を必ず用いる必要はなく、グローバル変数を使うと
 値は、どこからでも参照できる。(厳密には違う)

さて、元々の質問に戻ると
処理2の中でエラー処理をしていても、処理2が失敗したことをtest側(メイン側)
では認識出来ないから処理3を実行してしまう。もし失敗した事が解れば

If(処理2は失敗したの?) Then
  ' 失敗した処理
Else
  ’処理2が成功したから処理3
End If

と出来る。
頑張ってください^^

【63472】Re:エラー発生後、次のプロシージャを呼...
回答  でれすけ  - 09/11/9(月) 21:40 -

引用なし
パスワード
   こんにちは。

ひとつの方法ですが

メインの側にもエラー処理ルーチンを設けます。
SUB側のエラー処理ルーチンでは、
・SUB側でエラー処理が完結する場合は処理する
・メイン側で処理を中断する場合は Err.Raise でエラーを再発生させる

というやり方があります。

以下のサンプルでは、オーバーフローの場合はSUB側で処理し、
0除算はメイン側で中断しています。

Sub main()

On Error GoTo Err_Exit

 Call sub1

On Error GoTo 0

Exit Sub

Err_Exit:
 MsgBox Err.Description

End Sub


Sub sub1()
Dim a As Integer, b As Integer, c As Integer

On Error GoTo Err_handler
 a = 2
 b = 2 ^ 14
 c = a * b    ' オーバーフローエラー
 Debug.Print c
 
 a = 2
 b = 0
 c = a / b    ' 0除算のエラー
 Debug.Print c

On Error GoTo 0

Exit Sub

Err_handler:
 Select Case Err.Number
  Case 6 ' オーバーフロー
    b = b / 2
    Resume
  Case Else
    Err.Raise Err.Number
 End Select

End Sub

【63479】Re:エラー発生後、次のプロシージャを呼...
発言  seg  - 09/11/10(火) 9:28 -

引用なし
パスワード
   ▼でれすけ さん:
>こんにちは。
>
>ひとつの方法ですが
>
>メインの側にもエラー処理ルーチンを設けます。
>SUB側のエラー処理ルーチンでは、
>・SUB側でエラー処理が完結する場合は処理する
>・メイン側で処理を中断する場合は Err.Raise でエラーを再発生させる

面白いなぁ…Errをそのまま持って帰るのか
勉強になります^^

3223 / 13644 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free