2013-10-16 46 views
5

我有一堆代碼通過一組數據,然後找到數據進入下一個值步(5單位增量)的行。找到該位置後,將插入5行,並在這些行中計算該數據塊範圍內的STDEVP,MIN,MAX和AVERAGE。輸入後,循環繼續遍歷數據,直到它到達最後一行(lastRow變量)。這樣做的代碼如下所示:在循環中更改For循環的長度

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循環仍然在沒有該行的同一個點處結束。

My TL; DR版本的問題是:有沒有辦法增加For循環的長度,而您已經在循環內部,或者是否有更好的方法來執行相同的操作?

如果解釋混亂,我可以提供一些數據。感謝您的時間。

回答

11

我做了一個簡單的測試,發現了同樣的問題:

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 
+0

非常感謝您的輸入。將它改爲While循環對我的代碼來說是更好的選擇。我還修改了最後24行代碼的行引用,以便在我找到您的答案之前使用「lastRow」而不是「x」來獲得該工作,儘管現在可以改回「x」引用現在是正確的。 – H0ckeyfr33k99

1

我認爲,如果你改變你的語句來給

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

這樣,它應該工作,你總是使用最後一排。目前,您將「舊」最後一行保存在變量lastRow中,這會使您的for-loop「非動態」。

您需要爲您的列循環做同樣的...

4

我會嘗試一個Do_While_Loop

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

歡迎來到SO,HexaGamnon。 – Brian

+0

感謝您的意見。 While循環是動態改變循環邊界時要走的路,但是我選擇了上面的答案,這是因爲我的特定代碼的答案很清晰。你的回答是正確的。謝謝。 – H0ckeyfr33k99

+0

@Brian&@ H0ckeyfr33k99;謝謝! – HexaGamnon