在循环中更改For循环的长度

时间:2013-10-16 17:15:56

标签: excel vba loops excel-vba

我有一堆代码通过一组数据,然后找到数据进入下一个值步骤的行(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循环的长度,或者是否有一种更优雅的方式来执行相同的操作?

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

3 个答案:

答案 0 :(得分:14)

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

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循环的限制。您可以将循环更改为

请参阅此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

答案 1 :(得分:4)

我会尝试Do_While_Loop

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

答案 2 :(得分:1)

如果您将 for -statement更改为

,我认为它应该有用
for x = 2 to Range("A1").End(xlDown).Row

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

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