6

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

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

4

3 回答 3

17

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

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

看到这个帖子

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
于 2013-10-16T17:23:59.527 回答
5

我会尝试一个 Do_While_Loop

Do While x <= lastRow
    'Code that triggers insert
    lastRow = lastRow + 5
    '.....
    x = x + 1
Loop
于 2013-10-16T17:26:29.743 回答
1

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

for x = 2 to Range("A1").End(xlDown).Row

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

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

于 2013-10-16T17:24:51.593 回答