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

Open in new window

ltdanp22Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

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.

GrahamSkanRetiredCommented:
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

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

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

Start your 7-day free trial
Gene_CypCommented:
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
 
 
LeithauserCommented:
<<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.