VBA для каждого цикла, не выполняющего правильное действие

#excel #vba #foreach

Вопрос:

у меня есть этот код, он должен перебирать все строки в определенном диапазоне, и если условие выполнено, он должен удалить всю строку.

 Sub zakat()
Dim cell As Range
Dim last As String

Sheets("payment sheet").Activate

Cells.EntireColumn.AutoFit

last = ActiveSheet.Range("A1").CurrentRegion.Rows.Count

Debug.Print (last)

For Each cell In Range("M2:M" amp; last)

If cell.Text Like "*4435*" Or cell.Text Like "*1292*" Or cell.Text Like "*1293*" Then

cell.Select
Selection.EntireRow.Select
Selection.Delete Shift:=xlUp


End If
Next cell


End Sub
 

Я просто попытался выделить желтым цветом, если условие выполнено, не удаляя транзакции, просто чтобы проверить, правильно ли он просматривает все записи и идентифицирует их все, и он выделил их все без проблем. просто когда я прошу его удалить строки, он удаляет не все из них, а только почти половину!

есть какие-нибудь предложения?

Комментарии:

1. Когда вы удаляете строки, выполните итерацию от последней к первой.

Ответ №1:

Это распространенная трудность, с которой большинство из нас сталкивалось в какой-то момент!
При удалении строки, как правило, все строки под ней сдвигаются вверх. Однако цикл переместится в «следующую» строку, вместо того чтобы проверять строку, которая заменила удаленную.
Чтобы преодолеть это, выполните петли в обратном направлении, начиная снизу, следующим образом:

 For a = Last to 2 Step -1 
    If Range("M" amp; a) Like "*4435*" Or _
        Range("M" amp; a) Like "*1292*" Or _
        Range("M" amp; a) Like "*1293*" Then _
    Rows(a).Delete shift:=xlUp
Next
 

Ответ №2:

Удаление ячеек, которые вы повторяете в цикле, всегда приводит к проблемам. Как только вы удаляете первый, вы перепутаете ссылки на все последующие.

Лучшее решение, которое я нашел, — это выполнить итерацию по индексу, считая в обратном порядке-таким образом, последующие ссылки не будут затронуты.

 For i = last To 1 Step -1
  If .... Then 
    Cells(i,1).EntireRow.Delete Shift:=xlUp
  End If
Next i