Reputation: 279
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
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
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
Reputation: 6105
You can use Exit
in a lot of different ways including Exit For
to get out of your For...Next
Loop.
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
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