Ваш пересчет CoRow
не влияет на конец цикла!
Обратите внимание, что в циклах For
после запуска цикла
For i = 1 To CoRow
любое изменение значенияCoRow
не влияет на конец цикла !Цикл For
всегда использует значение CoRow
, которое было установлено при запуске цикла.
В следующем примере:
Dim i As Long
Dim iEnd As Long
iEnd = 10
For i = 1 To iEnd
iEnd = 20 'this has NO EFFECT on the end of the For loop
Debug.Print i, iEnd
Next i
Этот цикл будет запускаться только с 1 … 10
, поскольку один разцикл начался с For i = 1 To iEnd
любое изменение iEnd = 20
не влияет на конец цикла.
Решение
Замените его на цикл Do
.
Dim i As Long
Dim iEnd As Long
iEnd = 10
i = 1 'initialization needed before Do loops
Do While i <= iEnd
iEnd = 20
Debug.Print i, iEnd
i = i + 1 'manual increase of counter needed in the end of Do loops
Loop
Обратите внимание, что для циклов Do
необходимо инициализировать свой счетчик i = 1
, а также увеличить его вручную i = i + 1
.На этот раз вступают в силу изменения iEnd = 20
, и цикл запускается с 1 … 20
, поскольку цикл Do
оценивает условие i <= iEnd
на на каждой итерации (не только на старте, как For
цикл делает).
Альтернатива
Другое решение (если вы вставляете или удаляете строки) - запустить цикл в обратном направлении:
Dim CoRow As Long 'make it a variable not a function then
CoRow = Cells(Row.Count, 1).End(xlUp).Row
Dim i As Long
For i = CoRow To 1 Step -1
'runs backwards starting at the last row ending at the first
Next i
Но если это возможно или нетзависит от ваших данных и от того, какие действия вы выполняете в цикле.
Улучшение
Обратите внимание, что это CoRow = Cells(Rows.Count, 1).End(xlUp).Row
съест некоторое время.Вместо того чтобы делать CoRow
функцией, сделайте ее переменной и просто увеличивайте ее на 1 CoRow = CoRow + 1
каждый раз, когда вы вставляете строку, что будет намного быстрее, чем определение последней строки снова и снова.