【问题标题】:Change length of For loop while in the loop在循环中更改 For 循环的长度
【发布时间】:2013-10-16 17:15:56
【问题描述】:

我有一堆代码遍历一组数据,然后找到数据进入下一个值步骤(5 个单位增量)的行。找到此位置后,将插入 5 行,并在这些行中,在该数据块的范围内计算 STDEVP、MIN、MAX 和 AVERAGE。输入后,循环继续遍历数据,直到到达最后一行(lastRow 变量)。代码如下所示:

Sub sectionBlocking()
Dim lastRow As Integer
Dim lastColumn As Integer
Dim sectionLastRow As Integer
Dim initialValue As Double
Dim cellDifference As Double
Dim stepSize As Integer
Dim firstCell As Integer
Dim lastCell As Integer
firstCell = 2
lastCell = 2
initialValue = 84
stepSize = 5
lastRow = Range("A1").End(xlDown).Row
lastColumn = Range("A1").End(xlToRight).Column
For x = 2 To lastRow
    cellDifference = Range("B" & (x)).Value - initialValue
    If Abs(cellDifference) > 1 Then
        lastCell = x - 1
        Range("B" & (x)).EntireRow.Insert
        Range("A" & (x)) = "StdDev"
        For y = 2 To lastColumn
            Cells(x, y).FormulaR1C1 = "=STDEVP(" & "R" & firstCell & "C" & y & ": R" & lastCell & "C" & y & ")"
        Next y
        x = x + 1
        Range("B" & (x)).EntireRow.Insert
        Range("A" & (x)) = "MIN"
        For y = 2 To lastColumn
            Cells(x, y).FormulaR1C1 = "=MIN(" & "R" & firstCell & "C" & y & ": R" & lastCell & "C" & y & ")"
        Next y
        x = x + 1
        Range("B" & (x)).EntireRow.Insert
        Range("A" & (x)) = "MAX"
        For y = 2 To lastColumn
            Cells(x, y).FormulaR1C1 = "=MAX(" & "R" & firstCell & "C" & y & ": R" & lastCell & "C" & y & ")"
        Next y
        x = x + 1
        Range("B" & (x)).EntireRow.Insert
        Range("A" & (x)) = "AVG"
        For y = 2 To lastColumn
            Cells(x, y).FormulaR1C1 = "=AVERAGE(" & "R" & firstCell & "C" & y & ": R" & lastCell & "C" & y & ")"
        Next y
        x = x + 1
        Range("B" & (x)).EntireRow.Insert
        x = x + 1
        firstCell = x
        initialValue = initialValue + stepSize
        'lastRow = lastRow + 5
    End If
Next x
lastCell = x - 1
Range("B" & (x)).EntireRow.Insert
Range("A" & (x)) = "StdDev"
For y = 2 To lastColumn
    Cells(x, y).FormulaR1C1 = "=STDEVP(" & "R" & firstCell & "C" & y & ": R" & lastCell & "C" & y & ")"
Next y
x = x + 1
Range("B" & (x)).EntireRow.Insert
Range("A" & (x)) = "MIN"
For y = 2 To lastColumn
    Cells(x, y).FormulaR1C1 = "=MIN(" & "R" & firstCell & "C" & y & ": R" & lastCell & "C" & y & ")"
Next y
x = x + 1
Range("B" & (x)).EntireRow.Insert
Range("A" & (x)) = "MAX"
For y = 2 To lastColumn
    Cells(x, y).FormulaR1C1 = "=MAX(" & "R" & firstCell & "C" & y & ": R" & lastCell & "C" & y & ")"
Next y
x = x + 1
Range("B" & (x)).EntireRow.Insert
Range("A" & (x)) = "AVG"
For y = 2 To lastColumn
    Cells(x, y).FormulaR1C1 = "=AVERAGE(" & "R" & firstCell & "C" & y & ": R" & lastCell & "C" & y & ")"
Next y
'lastRow = lastRow + 4
End Sub

这非常有效,直到我尝试执行最后 24 行代码,却发现宏已按预期将新行插入到最后一个数据块的中间而不是末尾。我进行了调试,发现 For 循环中的行值变量“x”停止在原来的“lastRow”位置,而不是在新行输入图表后的新位置。这导致我尝试输入下面的代码行(上面注释以显示我自己调试的进度):

lastRow = lastRow + 5

这被放入 For 循环中,每次添加行时,“lastRow”值都会随着添加的行数增加。不幸的是,这也不起作用。 “lastRow”变量正在增加它的值(通过单步执行宏发现),但 For 循环仍然在与没有该行的位置相同的位置结束。

我的 TL;DR 版本的问题是:当您已经在循环内部时,有没有办法增加 For 循环的长度,或者是否有更优雅的方式来执行相同的操作?

如果解释令人困惑,我可以提供一些数据。感谢您的宝贵时间。

【问题讨论】:

    标签: vba loops excel


    【解决方案1】:

    我做了一个简单的测试,发现同样的问题:

    Sub Macro1()
        Dim x As Integer: x = 10
    
        For i = 1 To x
            If (i = 5) Then
                x = 15
            End If
        Next
    
        MsgBox (i)
    End Sub
    

    看起来 excel 确实预编译了 for 循环的限制。您可以改为将循环更改为 while

    看到这个post

    x = 2
    
    While x <= lastRow
        cellDifference = Range("B" & (x)).Value - initialValue
        If Abs(cellDifference) > 1 Then
            'your code
    
            lastRow = lastRow + 1
        End If
        x = x + 1
    Wend
    

    【讨论】:

    • 非常感谢您的意见。将其更改为 While 循环是我的代码的更好选择。我还修改了最后 24 行代码的行引用以使用“lastRow”而不是“x”来在我找到你的答案之前让它工作,尽管现在可以将它改回来,因为“x”引用现在是正确的.
    【解决方案2】:

    我会尝试 Do_While_Loop

    Do While x <= lastRow
        'Code that triggers insert
        lastRow = lastRow + 5
        '.....
        x = x + 1
    Loop
    

    【讨论】:

    • 欢迎来到 SO,HexaGamnon。
    • 感谢您的意见。 While 循环是动态更改循环边界时要走的路,但我选择了上面的答案,因为我的特定代码的答案很清楚。你的答案同样正确。谢谢。
    • @Brian & @H0ckeyfr33k99;谢谢!
    • 我确实看到了另一篇有有用建议的帖子;如果您从 Bottom->Top 开始工作,则 StartRow(例如 1000)和 EndRow(例如 100)不会改变,并且您不必有跳过插入代码的代码(就像您在工作 Top->Bottom 时所做的那样)。
    【解决方案3】:

    我认为如果您将 for 语句更改为

    ,它应该会起作用
    for x = 2 to Range("A1").End(xlDown).Row
    

    这样,您始终使用最后一行。目前,您将“旧”最后一行保存在变量 lastRow 中,这使您的 for 循环“非动态”。

    你需要为你的列循环做同样的事情......

    【讨论】:

      猜你喜欢
      • 2023-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-15
      • 2020-01-22
      • 2018-08-13
      • 2017-09-26
      • 1970-01-01
      相关资源
      最近更新 更多