Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 计数器的值未在For循环中更新_Excel_Vba_For Loop - Fatal编程技术网

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

Excel 计数器的值未在For循环中更新,excel,vba,for-loop,Excel,Vba,For Loop,我在excel文件的B列中有数据。我做了一个循环,如果B单元格中的值大于一个特定的(len1)值,那么代码将单元格(value-len1)值放在行末尾的一个新单元格中 每次添加行时,我都将计数器递增为lastrow=lastrow+1。现在问题来了。在最初的输入文件中,我有122组数据。但当For循环完成时,lastrow的值变为160,但循环在122处退出。为什么?任何帮助都将不胜感激 For i = 1 To lastrow Step 1 If Range("B"

我在excel文件的B列中有数据。我做了一个循环,如果B单元格中的值大于一个特定的(len1)值,那么代码将单元格(value-len1)值放在行末尾的一个新单元格中

每次添加行时,我都将计数器递增为lastrow=lastrow+1。现在问题来了。在最初的输入文件中,我有122组数据。但当For循环完成时,lastrow的值变为160,但循环在122处退出。为什么?任何帮助都将不胜感激

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

请测试下一个代码:

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

一种更快的方法是将范围值导出到数组,然后进行比较。将最终输出存储到临时数组中,并将其写回工作表

如果你想遵循你的方法,那么这就是你正在尝试的吗?我已经对代码进行了注释,所以您在理解它时应该不会有问题。如果要重新检查要添加到行末尾的数据,基本上需要两个循环

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
在行动中


要获得您想要的行为,您需要一个
while
循环(或
do
循环)

请注意以下事项:

  • 在循环内部,我首先递增
    lastrow
    ,然后在以下两条语句中使用它(以减少加法操作的数量)
  • 在我的测试代码中,我将
    添加到这个工作簿.Sheets(“Sheet1”)
    中,以完全限定所有范围。不这样做是许多错误的根源,有时很难查明。一个人应该养成这样的习惯:在没有一点
    的情况下,永远不要写
    范围
    单元格

for
循环使用预定义的迭代次数。对于未知的迭代次数,您需要使用
while
循环

您的代码在解释时使用了
lastRow
的值,并且不再更新

这类似于:

lastRow = 1
Debug.Print lastRow
lastRow = lastRow + 1
Debug.Print lastRow
你会看到:

1 2 1. 2. 而不是

2 2 2. 2.
因为一旦执行了第一个
Debug
语句,更改
lastRow
的值将不再影响此特定输出。

lastRow的值为122,因此循环退出,在For循环开始时,“To”值只计算一次,因此,在该点之后更改
lastrow
不会影响循环结束的时间。但该值最初是,在循环结束时,lastrow的值为160…因此循环应持续到160。另外,更快的方法是将范围值导出到数组,然后进行比较。将最终输出存储到一个临时数组中,并将其写回工作表。@ab就像Tim说的,i=1到lastrow步骤1的
只计算一次,因此循环不关心该行之后的
lastrow
的值,它将在
i=122
时停止。不完全确定,但我认为他想要的行为如下:在你的样本中,B14应该评估为278(即400-122)。还应在稍后阶段在循环中检查,因此,应将值156(即278-122)添加到范围的末尾。之后再加上一个值34(即156-122)。这就是以400开头的链将结束的地方,因为34小于122.400=>278=>156=34(第18行)类似地'300=>178=>56(第17行),所以我现在已经测试了您的代码,它的工作原理与所描述的完全相同:)我对您的giff图像感到困惑,因为B14的值为122(最终是正确的值)。对不起,我弄错了。@SiddharthRout谢谢!你说得对!唯一一件事就是这个数字13被不必要地复制了。其余所有其他5个值122122,56,34均正确。我会检查我的程序,然后回来!整洁的如果i>LastRow,那么退出以获得超对称性如何:
LastRow
也可以工作,即使
LastRow
不断增加。。。我最初想用一个空单元格来退出循环,然后想办法在他的初始范围内避免空单元格。。。在这种情况下,它将再次迭代…:) 1 2 2 2