tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルgotoなしに書き直すには?
記事No11102
投稿日: 2013/06/28(Fri) 17:57
投稿者ルトケ
vb6は長いけど.netは初心者で、VB2010を7上で使ってます。

blnStopというフラグが立つとサブプロシージャの後ろの方まで
飛ばすというコードを書きたいです。for nextループが複数あり、
exit forだけでは次のループに飛んでしまいます。これは意図したところ
ではありません。Exit Subももちろん目的を果たしません。
gotoなしにこの種のコードを書き直したいのですが、
みなさんの温かいご助言賜りますれば幸いです。

For i = 0 To 100
If blnStop = True Then GoTo EndMea
ここにいろいろステートメント
'ここにgoto 代わりにexit for書くと次のループが実行されてしまう
Next

For i = 0 To intNumMeasure2
If blnStop = True Then GoTo EndMea
ここにいろいろ
'ここにgoto 代わりにexit for書くとループ後の処理が抜ける
Next i
ここにもいろいろ
EndMea:
MsgBox ("now aborted")
blnStop = False
End Sub

[ツリー表示へ]
タイトルRe: gotoなしに書き直すには?
記事No11103
投稿日: 2013/06/28(Fri) 21:38
投稿者魔界の仮面弁士
> gotoなしに書き直すには?
意図があって使う分には構わないと思っている派ですが、
自分で使うことはまず無いですね…。(^^;


> EndMea
エンドメア ?


> for nextループが複数あり、exit forだけでは次のループに飛んでしまいます。

こういうことで良いのかな?

Try
    For i = 0 To 100
        If blnStop Then Exit Try
        DoSomething1()
    Next
    For i = 0 To intNumMeasure2
        If blnStop Then Exit Try
        DoSomething2()
    Next
    DoSomething3()
Finally
    If blnStop Then
        MsgBox("now aborted")
    End If
End Try



VB6 だと、Exit Do や Exit While で代用しているものを見たことがあります。

あるいは、それぞれの処理を別の Function やラムダ式に切り出すとか。

Sub Main()
    Dim done As Boolean = FirstLoop()
    If done Then done = SecondLoop()
    If done Then DoSomething3() Else MsgBox("now aborted")
End Sub

Function FirstLoop() As Boolean
    For i = 0 To 100
        If blnStop Then Return False
        DoSomething1()
    Next
    Return True
End Function

Function SecondLoop() As Boolean
    For i = 0 To intNumMeasure2
        If blnStop Then Return False
        DoSomething2()
    Next
    Return True
End Function

[ツリー表示へ]
タイトルRe^2: gotoなしに書き直すには?
記事No11105
投稿日: 2013/07/02(Tue) 06:52
投稿者ルトケ
魔界の仮面弁士さま

どうもありがとうございます。do whileループで囲っておいて
exit while とかで抜け出すようにするのですね。
カウンターを繰り上げるステートメントは入れないように
するという。なかなか凝った手ですね。

[ツリー表示へ]
タイトルRe^3: gotoなしに書き直すには?
記事No11106
投稿日: 2013/07/02(Tue) 17:20
投稿者shu
> 魔界の仮面弁士さま
>
> どうもありがとうございます。do whileループで囲っておいて
> exit while とかで抜け出すようにするのですね。
> カウンターを繰り上げるステートメントは入れないように
> するという。なかなか凝った手ですね。
Try

Finally

End Try
の方が分かりやすい方法であり一般的です。

do whileはTry文のなかったvb6で実現する為に
そんな方法もあったよという事でしょう。実際にループもしないのに
do while使うのは見た目このループはなんだとなってしまい
避けた方がよいと思います。そしてexit whileはwhileループでないと
使用できません。doループの場合はexit doとなります。

また
Try

Catch

Finally

End Try
の形にすれば例外後でも後処理を実行出来るようになります。

[ツリー表示へ]
タイトル違います。
記事No11107
投稿日: 2013/07/06(Sat) 15:49
投稿者魔界の仮面弁士
> どうもありがとうございます。do whileループで囲っておいて
> exit while とかで抜け出すようにするのですね。

そうではありません。Exit While を使うのであれば、Do ループは無関係です。
Do ループで囲ったのであれば、Exit Do で脱出してください。


Exit Do の対象となるループブロック
「Do/Loop」
「Do/Loop Until 完了条件」
「Do/Loop While 継続条件」
「Do Until 完了条件/Loop」
「Do While 継続条件/Loop」


Exit While の対象となるループブロック … VB6 の「While/Wend」には非対応
「While 継続条件/Exit While」


Exit For の対象となるループブロック
「For/Next」
「For Each/Next」


Exit Select の対象となるブロック … VB6 では使用不可
「Select/Case/End Select」


ただし、無駄なループブロックで囲む仕様は、(時にGoTo以上に)分かりにくくなるため
多用はお奨めしません。通常は、Try 構文を利用するか、もしくは
機能単位で Function に切り出すことを検討してください。

[ツリー表示へ]
タイトルerr.raiseを使うのは?
記事No11108
投稿日: 2013/07/11(Thu) 07:19
投稿者ルトケ
魔界の仮面様 SHU様
どうもありがとうございました。

売り物のソフトとしてコンパイルする場合は
NGだろうけど自分用のプログラムなら
エラーコード登録されてない空き番号
のエラーをわざと発生させてトライ文から
キャッチのところへ行かせる
ってのはどうでしょうか?

~~~
Try
If blnStop = True Then Err.Raise(999)
Catch When Err.Number = 999
Messagebox.Show("Aborted")
Finally

End Try
~~~

[ツリー表示へ]
タイトルRe: err.raiseを使うのは?
記事No11109
投稿日: 2013/07/11(Thu) 07:50
投稿者shu
> 魔界の仮面様 SHU様
> どうもありがとうございました。
>
> 売り物のソフトとしてコンパイルする場合は
> NGだろうけど自分用のプログラムなら
> エラーコード登録されてない空き番号
> のエラーをわざと発生させてトライ文から
> キャッチのところへ行かせる
> ってのはどうでしょうか?
>
売り物用でもこのやり方自体は使用してもよいと思います。
ただCatch,Finallyでの処理はしっかり行っておく必要があります。


Err.Raiseで独自のエラー番号を使うのではなく自分で作成したExceptionの
派生クラスのインスタンスをThrowした方がよいかと思います。


> Try
>  If blnStop = True Then Err.Raise(999)
> Catch When Err.Number = 999
>  Messagebox.Show("Aborted")
> Finally
>
> End Try
> ~~~

Try
  If blnStop = True Then Throw new MyException(〜)
Catch ex as MyException
  Messagebox.Show("Aborted")
Finally

End Try


Public Class MyException
    Inherits ApplicationException

    〜
End Class

[ツリー表示へ]