VBA-forループの反復を条件付きでスキップする方法


101

配列にforループがあります。私がやりたいのは、ループ内の特定の条件をテストし、trueの場合は次の反復にスキップすることです。

For i = LBound(Schedule, 1) To UBound(Schedule, 1)
    If (Schedule(i, 1) < ReferenceDate) Then
        PrevCouponIndex = i
        Continue   '*** THIS LINE DOESN'T COMPILE, nor does "Next"
    End If
    DF = Application.Run("SomeFunction"....)
    PV = PV + (DF * Coupon / CouponFrequency)
Next

私ができることはわかっています:

 If (Schedule(i, 1) < ReferenceDate) Then Continue For

しかし、iの最後の値をPrevCouponIndex変数に記録できるようにしたいと思います。

何か案は?

ありがとう


3
あなたは言った:「私は私ができることを知っています:If (Schedule(i, 1) < ReferenceDate) Then Continue For」それについて確信していますか? ContinueはVBAキーワードではありません。
mwolfe02 2011

@ mwolfe02-わかりませんが、どこかで例を見ました(cpearson?)
Richard H

VB.NETの例である可能性があります
匿名型

回答:


31

こんな簡単なことをしてみませんか?

For i = LBound(Schedule, 1) To UBound(Schedule, 1)
  If (Schedule(i, 1) < ReferenceDate) Then
     PrevCouponIndex = i
  Else
     DF = Application.Run("SomeFunction"....)
     PV = PV + (DF * Coupon / CouponFrequency)
  End If
Next

4
確かに、それは私がやったこととまったく同じです:)しかし、それでも私はバグを抱えています。ありがとう
Richard H

4
+1 IF@RichardHはテストにを使用する必要があるので、コード的にはそれほど高価ではありません。ただし、最も一般的な結果は、必要以上に頻繁に実行することを避けるSchedule(i, 1)よりも少ないことを確認する必要があります。それ以外の場合はを使用します。(テストが50/50の場合、最適化の必要はありません)ReferenceDateElse(ReferenceDate>=Schedule(i, 1))
brettdj '31 / 12/31

結果を使用する前に一致を見つけられないように、各反復内でかなりの数のApplication.Matchの結果を確認する必要がある場合など、多数のネストされたifsで少し厄介になるかもしれません。しかし、そうであっても、人生にはもっと悪いことがある!
JeopardyTempest

182

VBAにはContinue、次のループ反復に直ちにジャンプするための、または他の同等のキーワードがありません。Goto回避策として、を慎重に使用することをお勧めします。これが単なる例であり、実際のコードがより複雑な場合は特にそうです。

For i = LBound(Schedule, 1) To UBound(Schedule, 1)
    If (Schedule(i, 1) < ReferenceDate) Then
        PrevCouponIndex = i
        Goto NextIteration
    End If
    DF = Application.Run("SomeFunction"....)
    PV = PV + (DF * Coupon / CouponFrequency)
    '....'
    'a whole bunch of other code you are not showing us'
    '....'
    NextIteration:
Next

しかし、それが本当にすべてのコードである場合、@ Brianは完全に正しいです。文にElse句を1つ入れれば、それで終わりIfです。


18
おかげで、それはGoTo(VBA-1964年に戻ってあなたを照らす)にとって良いヒントです
リチャードH

3
@George:GoToは悪用される可能性があります(これが私が自分の発言を修飾した理由です。賢明に見てください)。しかし、本質的に悪ではありません。しかし真剣に、エラー処理(つまり)のために必要なだけで、Gotoステートメントなしで堅牢なVBAを作成することは不可能ですOn Error Goto
mwolfe02

3
@George:ここで私がお勧めするのは、言語の別の制限(Continueステートメントなし)の回避策です。Continue他の言語でのの使用は避けるべきであり、したがって、ここでも避けるべきであると主張することができます。いくつかの点で、あなたが投稿したリンクは私の主張になっています。リンクはGoToVB.Net のステートメントへのリンクです。VB.Netには、構造化エラー処理とContinue For/ Continue Doステートメントの両方があります。GoToVB.Netでは本当に必要はありません。既存のVBA / VB6コードの簡単な変換をサポートするために主に残されたと思います。
mwolfe02

4
@GeorgeにGoToは、ネストを減らすという利点があります。インデントのレベルを追加せずにループ反復をスキップすることは、IMOでありGoTo、VBA / VB6 での数少ない正当な使用法の1つです。特に、ループの本体を独自のプロシージャに抽出する場合
Mathieu Guindon

4
@George コードを壊さないネストを見てきましたが、脳を破壊します ;)
Mathieu Guindon

35

continueネストされたを使用して、一種を使用できますDo ... Loop While False

'This sample will output 1 and 3 only

Dim i As Integer

For i = 1 To 3: Do

    If i = 2 Then Exit Do 'Exit Do is the Continue

    Debug.Print i

Loop While False: Next i

1
gotoを使用するよりも面白いです。
ozmike、

これはすごい
Kubie

1
これが答えになるはずです
Stian Ulriksen

非常にエレガントで素敵
アレクシス・サンチェス・テジョ

5
賢い!私はコメントなしでそれに遭遇する人になるのは嫌いだろう。笑
カルトール

14

Continue For VBAまたはVB6では無効です。

このMSDNページから、VS 2005./Net 2のVB.Netに導入されたようです。

他の人が言ったように、Gotoまたはを使用する以外に本当にオプションはありませんElse


2

こんにちは私もこの問題に直面しています。以下のサンプルコードを使用してこれを解決します

For j = 1 To MyTemplte.Sheets.Count

       If MyTemplte.Sheets(j).Visible = 0 Then
           GoTo DoNothing        
       End If 


'process for this for loop
DoNothing:

Next j 

なぜこれが反対票を投じられたのかわからず、次の回答が100以上の賛成票を獲得しました。それらは同じ回答です!
rryanp

4
おそらく、この回答はその回答から5年後に書かれたものであり、まったく同じ概念です。なぜこれは賛成票を受け取る必要があるのですか?
タイラースタンディッシュマン2017

-2

ifを最後にすべて配置してみて、elseを使用してコードをスキップすると、GoToを使用できないようになります。

                        If 6 - ((Int_height(Int_Column - 1) - 1) + Int_direction(e, 1)) = 7 Or (Int_Column - 1) + Int_direction(e, 0) = -1 Or (Int_Column - 1) + Int_direction(e, 0) = 7 Then
                Else
                    If Grid((Int_Column - 1) + Int_direction(e, 0), 6 - ((Int_height(Int_Column - 1) - 1) + Int_direction(e, 1))) = "_" Then
                        Console.ReadLine()
                    End If
                End If
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.