# Nested For loops.

The code below is a series of nested For loops each with the same logic. The only difference is the equation to calculate dReleaseGateDOS which I think I can handle with some additional arrays. What is the standard way of writing nested for loops when each loop has the same logic as the others?

Also, the code below breaks at "For iStartGateDOS(16) = 1 To 42" with the compile error: "For control variable already in use." I would have thought iStartGate(15) and iStartGate(16) would be treated as two different variables. How do I get around this?

``````Function CalcStartGateDOS(dNewDesiredDOS As Double)
Dim vIncrements As Variant
Dim dBuffer As Double
Dim dReleaseGateDOS(15 To 20) As Double
Dim iStartGateDOS(15 To 20) As Integer

dBuffer = 0.2
vIncrements = Array(0.3, 0.3, 0.5, 0.5, 0.7, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6)

If dNewDesiredDOS < 4.3 Then
CalcStartGateDOS = 1
Exit Function
End If

If dNewDesiredDOS > 108 Then
CalcStartGateDOS = 42
Exit Function
End If

'*****Gate 15*****   Calc DesiredDOS for each StartGateDOS until Gate15DOS >= DesiredDOS
For iStartGateDOS(15) = 1 To 42
dReleaseGateDOS(15) = iStartGateDOS(15) + vIncrements(iStartGateDOS(15)) * 11
If dReleaseGateDOS(15) >= dNewDesiredDOS Then
'Calculate buffer
dReleaseGateDOS(20) = iStartGateDOS(15) + vIncrements(iStartGateDOS(15)) * 13 + 3 * (vIncrements(iStartGateDOS(15)) + 1)
If (dReleaseGateDOS(20) - dReleaseGateDOS(15)) / dReleaseGateDOS(15) < dBuffer Then
CalcStartGateDOS = iStartGateDOS(15)
Exit Function
Else
'*****Gate 16*****   Count backwards from Gate15's StartGateDOS since Gate16's StartGateDOS always smaller; saves resources
For iStartGateDOS(16) = 1 To 42
dReleaseGateDOS(16) = iStartGateDOS(16) + vIncrements(iStartGateDOS(16)) * 12
If dReleaseGateDOS(16) >= dNewDesiredDOS Then
'Calculate buffer
dReleaseGateDOS(20) = iStartGateDOS(16) + vIncrements(iStartGateDOS(16)) * 13 + 3 * (vIncrements(iStartGateDOS(16)) + 1)
If (dReleaseGateDOS(20) - dReleaseGateDOS(16)) / dReleaseGateDOS(16) < dBuffer Then
CalcStartGateDOS = iStartGateDOS(16)
Exit Function
Else
'*****Gate 17*****
For iStartGateDOS(17) = 1 To 42
dReleaseGateDOS(17) = iStartGateDOS(17) + vIncrements(iStartGateDOS(17)) * 13
If dReleaseGateDOS(17) >= dNewDesiredDOS Then
'Calculate buffer
dReleaseGateDOS(20) = iStartGateDOS(17) + vIncrements(iStartGateDOS(17)) * 13 + 3 * (vIncrements(iStartGateDOS(17)) + 1)
If (dReleaseGateDOS(20) - dReleaseGateDOS(17)) / dReleaseGateDOS(17) < dBuffer Then
CalcStartGateDOS = iStartGateDOS(17)
Exit Function
Else
'*****Gate 18*****
For iStartGateDOS(18) = 1 To 42
dReleaseGateDOS(18) = iStartGateDOS(18) + vIncrements(iStartGateDOS(18)) * 13 + 1 * (vIncrements(iStartGateDOS(18)) + 1)
If dReleaseGateDOS(18) >= dNewDesiredDOS Then
'Calculate buffer
dReleaseGateDOS(20) = iStartGateDOS(18) + vIncrements(iStartGateDOS(18)) * 13 + 3 * (vIncrements(iStartGateDOS(18)) + 1)
If (dReleaseGateDOS(20) - dReleaseGateDOS(18)) / dReleaseGateDOS(18) < dBuffer Then
CalcStartGateDOS = iStartGateDOS(18)
Exit Function
Else
'*****Gate 19*****
For iStartGateDOS(19) = 1 To 42
dReleaseGateDOS(19) = iStartGateDOS(19) + vIncrements(iStartGateDOS(19)) * 13 + 2 * (vIncrements(iStartGateDOS(19)) + 1)
If dReleaseGateDOS(19) >= dNewDesiredDOS Then
'Calculate buffer
dReleaseGateDOS(20) = iStartGateDOS(19) + vIncrements(iStartGateDOS(19)) * 13 + 3 * (vIncrements(iStartGateDOS(19)) + 1)
If (dReleaseGateDOS(20) - dReleaseGateDOS(19)) / dReleaseGateDOS(19) < dBuffer Then
CalcStartGateDOS = iStartGateDOS(19)
Exit Function
Else
'*****Gate 20*****
For iStartGateDOS(20) = 1 To 42
dReleaseGateDOS(20) = iStartGateDOS(20) + vIncrements(iStartGateDOS(20)) * 13 + 3 * (vIncrements(iStartGateDOS(20)) + 1)
If dReleaseGateDOS(20) >= dNewDesiredDOS Then
CalcStartGateDOS = iStartGateDOS(20)
Exit Function
End If
Next iStartGateDOS(20)
End If
End If
Next iStartGateDOS(19)
End If
End If
Next iStartGateDOS(18)
End If
End If
Next iStartGateDOS(17)
End If
End If
Next iStartGateDOS(16)
End If
End If
Next iStartGateDOS(15)

End Function
``````
###### Who is Participating?

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

RetiredCommented:
It looks like a case for recursion. Something like this.
``````Sub ExecuteReleasegates(i As Integer)
For iStartGateDOS(i) = 1 To 42
dReleaseGateDOS(i) = iStartGateDOS(i) + vIncrements(iStartGateDOS(i)) * 13 + 2 * (vIncrements(iStartGateDOS(i)) + 1)
If dReleaseGateDOS(i) >= dNewDesiredDOS Then
'Calculate buffer
dReleaseGateDOS(i + 1) = iStartGateDOS(i) + vIncrements(iStartGateDOS(i)) * 13 + 3 * (vIncrements(iStartGateDOS(i)) + 1)
If (dReleaseGateDOS(i + 1) - dReleaseGateDOS(i)) / dReleaseGateDOS(i) < dBuffer Then
CalcStartGateDOS = iStartGateDOS(i)
Exit Sub
Else
ExecuteReleasegatesi + 1
'*****Gate  i + 1*****
For iStartGateDOS(i + 1) = 1 To 42
dReleaseGateDOS(i + 1) = iStartGateDOS(i + 1) + vIncrements(iStartGateDOS(i + 1)) * 13 + 3 * (vIncrements(iStartGateDOS(i + 1)) + 1)
If dReleaseGateDOS(i + 1) >= dNewDesiredDOS Then
CalcStartGateDOS = iStartGateDOS(i + 1)
Exit Sub
End If
Next iStartGateDOS(i + 1)
End If
End If
Next iStartGateDOS(i)
End If
End Sub
``````

Experts Exchange Solution brought to you by

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Commented:
Given identical code, you call the method itself by itself. This is called recursion.
The pitfall: ensure your cycle ENDS (just like while loops without a proper closing clause, a recursive method can go on and on and on.. and your program will hang.

Example of recursion:
Function myRecursiveFunction(myInt as Integer)
If myInt > 10 Then
'code here to do whatever when we reach 10
Else
Print(myInt); ' Let's say we got a printing method

myInt++; ' without this to change the parameter i'llg et stuck
myRecursiveFunction(myInt);  ' Notice how I call my own method inside my actual method
End If

End Function

Commented:
<<What is the standard way of writing nested for loops when each loop has the same logic as the others?>>
The standard procedure is to use different variables, such as
For X = 1 to 10
For Y = 1 To 5
'Do stuff here
Next Y
Next X

<<Also, the code below breaks at "For iStartGateDOS(16) = 1 To 42" with the compile error: "For control variable already in use." I would have thought iStartGate(15) and iStartGate(16) would be treated as two different variables. How do I get around this?>>
It would seem to, but I have never heard of using a subscripted variable for a For-Next loop, and maybe your compiler just cannot handle it. I suggest you use separate variables, not subscripted variables, for your For-Next loops. If you need the subscripted variables to have these values within the loop, just assign the values right after the For statement. For example,
For X = 1 To 42
iStartGateDOS(17) = X

If it helps you to keep things straight, you can use nonsubsripted varialbe names that look much like the subscripted variable names, like iStartGateDOS17 for iStartGateDOS(17), like
For iStartGateDOS17 = 1 to 42
iStartGateDOS(17) = iStartGateDOS17
###### It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.