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

これは、行が追加されるたびに、追加された行数だけ "lastRow" 値が増加するように For ループ内に配置されました。残念ながら、これもうまくいきませんでした。「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 ループの制限をプリコンパイルしているようです。代わりに、ループを while に変更できます

この投稿を見る

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 に答える