简体   繁体   中英

Conditional Loop in VBA using If, Then, Else, Else if statement not looping to next i in array

I am trying to work on a conditional loop. Everything seems to be working, however it is not advancing to the next i and next j and continuing the loop. It seems to be ending after one loop of the loop. I have been working on this for quite sometime and am very very new to VBA.

Sub Read()
     NumMonth = 12
     Worksheets("Sheet1").Activate
     ReDim Month(1 To NumMonth)
     ReDim WCinit(1 To NumMonth)
     ReDim WC(1 To NumMonth + 1)
     ReDim Precip(1 To NumMonth)
     ReDim RefET(1 To NumMonth)
     ReDim Percolation(1 To NumMonth + 1)
     ReDim Runoff(1 To NumMonth + 1)
     For i = 1 To NumMonth

     Month(i) = Cells(4 + i, 1).Value
     WCinit(i) = Cells(4 + i, 10).Value

     Precip(i) = Cells(4 + i, 2).Value
     RefET(i) = Cells(4 + i, 3).Value

 Next i

For j = 1 To NumMonth + 1
       WC(j) = Cells(3 + i, 11).Value
Next j

     Application.ScreenUpdating = True
  End Sub


Sub Test()
    Dim fc As Double
    fc = 0.3
    NumMonth = 12
    i = 1
    j = 2

    Dim pwp As Double
    pwp=0.1
    Dim dz As Double
    dz = 0.5 'm

Do

If WC(j - 1) + WCinit(i) > pwp And fc - (WC(j - 1) + WCinit(i)) + RefET(i) < Precip(i)        Then
   Runoff(i) = (Precip(i) - (fc - (WC(j - 1) + WCinit(i)) + RefET(i))) * 0.5
   Percolation(i) = (Precip(i) - (fc - (WC(j - 1) + WCinit(i)) + RefET(i))) * 0.5
   WC(j) = fc

ElseIf WC(j - 1) + WCinit(i) > pwp And fc - (WC(j - 1) + WCinit(i)) + RefET(i) <    Precip(i) Then
   Runoff(i) = 0
   Percolation(i) = 0
   WC(j) = WC(j - 1) + WCinit(i) + Precip(i) - RefET(i)

Else
   WC(j) = pwp

End If
    j = j + 1
    i = i + 1

Loop While j<13

I have done some work on the code that you provided (as presented below with annotation), which mainly needed attentive debugging of the logic of the program. You will still get a compiler error because two of the arrays were not assigned in your code, and I don't have enough information to do that properly.

The best resource available in VBA for taming recalcitrant code is the built-in debugger. With it, it is possible to step through the code line-by-line looking at how each variable is changing at each step.

If you are not familiar with the debugger, a number of good explanations are available online, such as Chip Pearson's explanation of the basics .

One change that could make the loops and indexes easier to deal with is putting the "13th month" values into variables that are separate from the arrays, which would then be straightforward 12-month ensembles of the data.

That would be a way to reduce the confusing bookkeeping that is otherwise required ("Should the index at this point in the program be j, or j - 1, or j + 1?"). I don't know if that approach really fits with your data and calculations.

Option Explicit                         ' Require declaration of all variables 

Private Const NumMonth As Long = 12     ' Make these variable available to all subroutines   
Private month As Variant                ' and functions in the module. Needed because they 
Private WCinit As Variant               ' would otherwise be out of scope in the Test() 
Private WC As Variant                   ' subroutine.

Private Precip As Variant               ' The arrays need to be declared as type Variant,
Private RefET As Variant                ' so we can make the assignment
Private Percolation As Variant          
Private Runoff As Variant              

Sub Read()

    Dim firstMoDataRow As Long
    Dim lastMoDataRow As Long

    firstMoDataRow = 5
    lastMoDataRow = 16

    ' if you want to avoid using the transpose function in the following
    ' array assignments, you will need to reference the arrays as  
    ' two-dimensional, e.g., WC(i,1) or WC(3,1), etc., with the 
    ' second index always 1 (that's what many often do).

    month = WorksheetFunction.Transpose(Range(Cells(firstMoDataRow, 1), Cells(lastMoDataRow, 1)).Value)    ' Direct assignment of values

    WCinit = WorksheetFunction.Transpose(Range(Cells(firstMoDataRow, 10), Cells(lastMoDataRow, 10)).Value)  ' in the worksheet ranges

    WC = WorksheetFunction.Transpose(Range(Cells(firstMoDataRow - 1, 11), Cells(lastMoDataRow, 11)).Value)  ' to the arrays.

    Precip = WorksheetFunction.Transpose(Range(Cells(firstMoDataRow, 2), Cells(lastMoDataRow, 2)).Value)

    RefET = WorksheetFunction.Transpose(Range(Cells(firstMoDataRow, 3), Cells(lastMoDataRow, 3)).Value)

  ' ?! Percolation and runoff are not assigned in your code, so I don't know
  '    the correct row and column references in the worksheet.

End Sub


Sub Test()

    Dim fc As Double           
    Dim pwp As Double
    Dim dz As Double
    Dim i as Long, j as Long


    fc = 0.3
    pwp = 0.1
    dz = 0.5 'm

    i = 1
    j = 2

    Do While i <= NumMonth And j <= NumMonth + 1  ' I am assuming here that you will sort out
                                                  ' the correct initializing and incrementing 
                                                  ' of the loop indexes, which I have not
                                                  ' puzzled out


        If WC(j - 1) + WCinit(i) > pwp And fc - (WC(j - 1) + WCinit(i)) + RefET(i) < Precip(i) Then

            Runoff(i) = (Precip(i) - (fc - (WC(j - 1) + WCinit(i)) + RefET(i))) * 0.5
            Percolation(i) = (Precip(i) - (fc - (WC(j - 1) + WCinit(i)) + RefET(i))) * 0.5
            WC(j) = fc

        ElseIf WC(j - 1) + WCinit(i) > pwp And fc - (WC(j - 1) + WCinit(i)) + RefET(i) < Precip(i) Then

            ' You are getting a "Subscript out of range" error here because Runoff() and 
            ' Percolation<> did not get assigned in the Read sub

            Runoff(i) = 0                                         
            Percolation(i) = 0                                    
            WC(j) = WC(j - 1) + WCinit(i) + Precip(i) - RefET(i)  

        Else

            WC(j) = pwp

        End If

        j = j + 1
        i = i + 1

    Loop

End Sub 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM