VBA: Как удалить отфильтрованные строки в Excel?

У меня есть таблица Excel, содержащая некоторые данные. Используя следующий код vba, я пытаюсь фильтровать только пустые ячейки в некоторых полях и удалять эти строки

ActiveSheet.Range("$A$1:$I$" & lines).AutoFilter Field:=7, Criteria1:= _
        "="
ActiveSheet.Range("$A$1:$I$" & lines).AutoFilter Field:=8, Criteria1:= _
        "="
ActiveSheet.Range("$A$1:$I$" & lines).AutoFilter Field:=9, Criteria1:= _
        "="
ActiveSheet.UsedRange.Offset(1, 0).Resize(ActiveSheet.UsedRange.rows.Count - 1).rows.Delete
ActiveSheet.ShowAllData

Он работает только в том случае, если в этих столбцах есть пустые ячейки. Но я столкнулся с проблемой, когда у меня нет пустых ячеек, и, используя вышеприведенный код, весь мой диапазон удаляется с листа. Как избежать этой проблемы? Должен ли я изменить состояние фильтра или что-то еще?

Ответ 1

Используйте SpecialCells для удаления только строк, которые видны после автофильтрации:

ActiveSheet.Range("$A$1:$I$" & lines).SpecialCells _
    (xlCellTypeVisible).EntireRow.Delete

Если у вас есть строка заголовка в вашем диапазоне, которую вы не хотите удалять, добавьте смещение в диапазон, чтобы исключить его:

ActiveSheet.Range("$A$1:$I$" & lines).Offset(1, 0).SpecialCells _
    (xlCellTypeVisible).EntireRow.Delete

Ответ 2

В качестве альтернативы использованию UsedRange или предоставления явного адреса диапазона, свойство AutoFilter.Range также может указывать затронутый диапазон.

ActiveSheet.AutoFilter.Range.Offset(1,0).Rows.SpecialCells(xlCellTypeVisible).Delete(xlShiftUp)

Как используется здесь, Offset вызывает первую строку после того, как диапазон AutoFilter также будет удален. Чтобы этого избежать, я попытался бы использовать .Resize() после .Offset().