Link to home
Start Free TrialLog in
Avatar of ltdanp22
ltdanp22Flag for United States of America

asked on

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

ASKER CERTIFIED SOLUTION
Avatar of GrahamSkan
GrahamSkan
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Gene_Cyp
Gene_Cyp

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