VBA 中的条件循环使用 If, Then, Else, Else if 语句不循环到数组中的下一个 i

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15046778/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 19:45:44  来源:igfitidea点击:

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

excel-vbavbaexcel

提问by user1977802

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.

我正在尝试处理条件循环。一切似乎都在工作,但是它没有前进到下一个 i 和下一个 j 并继续循环。它似乎在循环的一个循环之后结束。我已经为此工作了很长一段时间,并且对 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

回答by chuff

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.

VBA 中可用于驯服顽固代码的最佳资源是内置调试器。有了它,就可以逐行查看每个变量在每一步的变化情况。

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.

如果您不熟悉调试器,可以在网上找到许多很好的解释,例如 Chip Pearson对基础知识解释

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.

可以使循环和索引更容易处理的一项更改是将“第 13 个月”值放入与数组分开的变量中,然后这将是 12 个月数据的简单集合。

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.

这将是一种减少否则需要的令人困惑的簿记的方法(“程序中此时的索引应该是 j,还是 j - 1,还是 j + 1?”)。我不知道这种方法是否真的适合您的数据和计算。

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