#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