user110084
user110084

Reputation: 279

Ways to advance loop prematurely

Other than using GOTO, are there ways to abandon a chunk of code within a loop to advance it to the next? Is GOTO an efficient way to do it in the code below?

Do While x < 10

    a = Int(Rnd * 100)
    b = Int(Rnd * 100)
    c = Int(Rnd * 100)

    For n = 1 To 4
        aa(i) = i * 2 + 4
        bb(i) = i * 2 + 5
        cc(i) = i * 2 + 6
    Next

    If a = b Then GoTo lastline
    If a = c Then GoTo lastline
    If b = c Then GoTo lastline

    For i = 1 To 4

        testa = (a = aa(i) Or a = bb(i) Or a = cc(i))
        If testa Then GoTo lastline

        testb = (b = aa(i) Or b = bb(i) Or b = cc(i))
        If testb Then GoTo lastline

        testc = (c = aa(i) Or c = bb(i) Or c = cc(i))
        If testc Then GoTo lastline
    Next

    Debug.Print a & ","; b & ","; c

lastline:
    x = x + 1

Loop

Upvotes: 0

Views: 231

Answers (4)

Comintern
Comintern

Reputation: 22195

For sake of completeness, this is what it would look like if you extracted a Sub to do the work. Note that you have what I assume is a typo in your original code:

For n = 1 To 4
    aa(i) = i * 2 + 4    '<--- 'i'?  shouldn't these be 'n'?
    bb(i) = i * 2 + 5
    cc(i) = i * 2 + 6
Next

Since you are using i as the loop counter later, it will always be whatever it was coming into the loop the first time through, and 4 every time after that. My guess is that this isn't what you intended.

That out of the way... extracted Sub:

Private Sub WhateverYoureDoing(aa As Variant, bb As Variant, cc As Variant)
    Dim a As Long, b As Long, c As Long

    a = Int(Rnd * 100)
    b = Int(Rnd * 100)
    c = Int(Rnd * 100)

    'Assuming this should be 'i' instead of 'n' as the loop count.
    For i = 1 To 4
        aa(i) = i * 2 + 4
        bb(i) = i * 2 + 5
        cc(i) = i * 2 + 6
    Next

    If a = b Then Exit Sub
    If a = c Then Exit Sub
    If b = c Then Exit Sub

    For i = 1 To 4
        If a = aa(i) Or a = bb(i) Or a = cc(i) Then Exit Sub
        If b = aa(i) Or b = bb(i) Or b = cc(i) Then Exit Sub
        If c = aa(i) Or c = bb(i) Or c = cc(i) Then Exit Sub
    Next

    Debug.Print a & ","; b & ","; c
End Sub

Calling code:

Do While x < 10
    WhateverYoureDoing aa, bb, cc
    x = x + 1
Loop

Note that you can simplify this code tremendously. For example, this...

a = Int(Rnd * 100)
b = Int(Rnd * 100)
c = Int(Rnd * 100)
'...
If a = b Then GoTo lastline
If a = c Then GoTo lastline
If b = c Then GoTo lastline

...can be simply:

Do
    a = Int(Rnd * 100)
    b = Int(Rnd * 100)
    c = Int(Rnd * 100)
Loop While a <> b And a <> c And b <> c

Upvotes: 1

DGulledge
DGulledge

Reputation: 180

I would just wrap the part which might be skipped with an if statement. The second For loop can also be exited early with Exit For. Doing this avoids using GoTo. I haven't tested the code below, but it should illustrate the concept.

Do While x < 10
    a = Int(Rnd * 100)
    b = Int(Rnd * 100)
    c = Int(Rnd * 100)
    For n = 1 To 4
        aa(i) = i * 2 + 4
        bb(i) = i * 2 + 5
        cc(i) = i * 2 + 6
    Next
    If Not a = b Or Not a = c Or Not b = c Then
        For i = 1 To 4
            testa = (a = aa(i) Or a = bb(i) Or a = cc(i))
            testb = (b = aa(i) Or b = bb(i) Or b = cc(i))
            testc = (c = aa(i) Or c = bb(i) Or c = cc(i))
            If testa Or testb Or testC Then
                Exit For
            Else
                If i = 4 Then
                    Debug.Print a & ","; b & ","; c
                End If
            End If
        Next
    End If
    x = x + 1
Loop

Upvotes: 2

Chrismas007
Chrismas007

Reputation: 6105

You can use Exit in a lot of different ways including Exit For to get out of your For...Next Loop.

Here is the Exit MSDN

Exit For

Immediately exits the For loop in which it appears. Execution continues with the statement following the Next statement. Exit For can be used only inside a For...Next or For Each...Next loop. When used within nested For loops, Exit For exits the innermost loop and transfers control to the next higher level of nesting.

Upvotes: 0

Scott Craner
Scott Craner

Reputation: 152525

As has been stated you would use IFs to skip when false:

Do While x < 10

    a = Int(Rnd * 100)
    b = Int(Rnd * 100)
    c = Int(Rnd * 100)

    For n = 1 To 4
        aa(i) = i * 2 + 4
        bb(i) = i * 2 + 5
        cc(i) = i * 2 + 6
    Next

    If Not a = b Or Not a = c Or Not b = c Then

        For i = 1 To 4

            testa = (a = aa(i) Or a = bb(i) Or a = cc(i))
            If Not testa Then
                testb = (b = aa(i) Or b = bb(i) Or b = cc(i))
                If Not testb Then
                    testc = (c = aa(i) Or c = bb(i) Or c = cc(i))
                    If Not testc Then
                        Debug.Print a & ","; b & ","; c
                    End If
                End If
            End If
        Next

    End If

    x = x + 1

Loop

Upvotes: 0

Related Questions