简体   繁体   English

计数器的值未在 For 循环中更新

[英]Value of counter is not updating in a For Loop

I have data in B Column of an excel file.我在 excel 文件的 B 列中有数据。 I have made a loop that If the value in B Cell is greater than a particular (len1) value, then the code puts the Cell (Value-Len1) value in a new cell at the end of the rows.我做了一个循环,如果 B 单元格中的值大于特定 (len1) 值,则代码将单元格 (Value-Len1) 值放在行末尾的新单元格中。

I increment the counter as lastrow = lastrow+1 everytime when the row is added.每次添加行时,我都会将计数器递增为 lastrow = lastrow+1。 Now here is the problem.现在问题来了。 Iniitially in the input file I had 122 set of data.最初在输入文件中我有 122 组数据。 But by the time the For loop finishes the value of lastrow becomes 160, but the loop exits at 122. WHY??但是当 For 循环完成时,lastrow 的值变为 160,但循环在 122 处退出。为什么? Any Help will be appreciated.任何帮助将不胜感激。

For i = 1 To lastrow Step 1
    If Range("B" & i).Value > len1 Then
        Range("A" & lastrow + 1).Value = Range("A" & i).Value
        Range("B" & lastrow + 1).Value = Range("B" & i).Value - len1
        Range("B" & i).Value = len1
        lastrow = lastrow + 1
    End If
Next

To get the behaviour you want you need a while loop (or do loop)要获得您想要的行为,您需要一个while循环(或do循环)

i = 1
While i <= lastrow
    If Range("B" & i).Value > len1 Then
        lastrow = lastrow + 1
        Range("A" & lastrow).Value = Range("A" & i).Value
        Range("B" & lastrow).Value = Range("B" & i).Value - len1
        Range("B" & i).Value = len1
    End If
    i = i + 1
Wend

I tested it with the sub below:我用下面的sub测试了它:

Sub LoopBeyondLastRow()
    Dim i  As Long, lastrow As Long, len1 As Long
    
    len1 = 10
    
    With ThisWorkbook.Sheets("Sheet1")
        lastrow = .Cells(Rows.Count, "B").End(xlUp).Row
        
        i = 1
        While i <= lastrow
            If .Range("B" & i).Value > len1 Then
                lastrow = lastrow + 1
                .Range("A" & lastrow).Value = .Range("A" & i).Value
                .Range("B" & lastrow).Value = .Range("B" & i).Value - len1
                .Range("B" & i).Value = len1
            End If
            i = i + 1
        Wend
    End With
End Sub

Please note the following:请注意以下事项:

  • Inside the loop I incremented lastrow first and then used it in the following 2 statements (to reduce the number of addition operations)在循环内部,我先增加lastrow ,然后在以下 2 个语句中使用它(以减少加法操作的数量)
  • In my test code I added With ThisWorkbook.Sheets("Sheet1") to fully qualify all ranges.在我的测试代码中,我添加了With ThisWorkbook.Sheets("Sheet1")以完全限定所有范围。 Not doing this is the source of many bugs that are sometimes very difficult to pinpoint.不这样做是许多有时很难查明的错误的根源。 One should get in the habbit of never to write Range or Cells without a little .一个人应该养成一个习惯,即永远不要在没有一点的情况下编写RangeCells . before them.在他们面前。

Test the next code, please:请测试下一个代码:

Sub TestLoopAddedRowsInclusive()
  '..... your code defining LastRow and len1
  Dim lastRInit As Long
  lastRInit = LastRow
  For i = 1 To Rows.count
    If Range("B" & i).Value = "" And i >= lastRInit Then Exit For
    If Range("B" & i).Value > len1 Then
        Range("A" & LastRow + 1).Value = Range("A" & i).Value
        Range("B" & LastRow + 1).Value = Range("B" & i).Value - len1
        Range("B" & i).Value = len1
        LastRow = LastRow + 1
    End If
  Next
End Sub

A faster method would be to export the range values to array and then do the comparision.一种更快的方法是将范围值导出到数组,然后进行比较。 Store the final output into a temp array and write it back to the worksheet.将最终的 output 存储到临时数组中并将其写回工作表。

If you want to follow your approach then is this what you are trying?如果您想遵循您的方法,那么这就是您正在尝试的吗? I have commented the code so you should not have a problem understanding it.我已经对代码进行了注释,因此您理解它应该没有问题。 Basically you need 2 loops if you want to recheck the data that you are adding at the end of the row.如果要重新检查在行尾添加的数据,基本上需要 2 个循环。

Option Explicit

Sub Sample()
    Dim ws As Worksheet
    Dim ComparisionValue As Long
    Dim countOfMatchedValues As Long
    Dim lRow As Long
    Dim i As Long
    Dim outputRow As Long
    Dim rng As Range
    
    '~~> Change this to the relevant sheet
    Set ws = Sheet1
    
    '~~> Change this to the relevant
    '~~> comparision value
    ComparisionValue = 122
    
    With ws
        '~~> Start an indefinite loop
        Do
            '~~> Find last row
            lRow = .Range("A" & .Rows.Count).End(xlUp).Row
            '~~> Fix the output row for the new data
            outputRow = lRow + 1
            
            '~~> Check if there are any matches for your condition
            countOfMatchedValues = Application.WorksheetFunction.CountIf( _
            .Range("B1:B" & lRow), ">" & ComparisionValue)
            
            '~~> If not then exit loop
            If countOfMatchedValues = 0 Then Exit Do
            
            '~~> Do your stuff
            For i = 1 To lRow
                If .Range("B" & i).Value > ComparisionValue Then
                    .Range("A" & outputRow).Value = .Range("A" & i).Value
                    .Range("B" & outputRow).Value = .Range("B" & i).Value - ComparisionValue
                    .Range("B" & i).Value = ComparisionValue
                    outputRow = outputRow + 1
                End If
            Next i
        Loop
    End With
End Sub

In Action在行动

在此处输入图像描述

for loops use a pre-defined number of iterations. for循环使用预定义的迭代次数。 For an unknown number of iterations you need to use a while loop.对于未知数量的迭代,您需要使用while循环。

Your code uses the value of lastRow at the time it was interpreted , and is never updated again.您的代码在解释时使用lastRow的值,并且永远不会再次更新。

This is similar to:这类似于:

lastRow = 1
Debug.Print lastRow
lastRow = lastRow + 1
Debug.Print lastRow

You will see:你会看见:

1
2

and not :不是

2
2

because once the first Debug statement has been executed, changing the value of lastRow doesn't affect this particular output anymore.因为一旦执行了第一个Debug语句,更改lastRow的值就不会再影响这个特定的 output 了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM