Как можно удалить все строки в диапазоне?

Я новичок в vba, и я написал код ниже, но не могу понять, почему он не работает.

Sub DataValidationDeleteWrongOrigin()
'
'Description: Goes through and deletes rows that are called out on the delete entry column.
'


'Dimension Worksheet
Dim DataValWs As Worksheet
Set DataValWs = Worksheets("Data Validation")

'Find the size of the table and store it as LastDataRow
Dim LastDataRow As Long
LastDataRow = DataValWs.Range("A5").End(xlDown).Row


'ThisRow will be the current row as the for loop goes through each row.
Dim ThisRow As Long
Dim DeleteRange As Range
Dim CurrentRow As Range
'Start the for loop from row 5
For ThisRow = 5 To LastDataRow

    'Check the Delete Entry row to see if it says Yes, delete the row. Use DeleteRange to add cells to it and delete them all at the end (much _
    faster than deleting them one at a time, and you don't have to re-find the size of the table after each row is deleted).

    If Cells(ThisRow, 16) = "Yes" Then
        If Not DeleteRange Is Nothing Then
            Set CurrentRow = DataValWs.Rows(ThisRow)
            Set DeleteRange = Union(CurrentRow, DeleteRange)
        Else
            Set DeleteRange = DataValWs.Cells(ThisRow, 16)
        End If


    End If

Next ThisRow

'DeleteRange.Select
DeleteRange.EntireRow.Delete



End Sub

В настоящее время код дает мне

Ошибка выполнения 1004: не удалось удалить метод класса Range.

«DeleteRange.Select», который закомментирован в конце кода, выбирает правильный диапазон, поэтому я знаю, что диапазон строится точно.

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

Я посмотрел в Интернете и нашел пару решений, которые включают итеративное прохождение DeleteRange и удаление каждой строки из него, но это дает мне ту же проблему удаления строк по одной за раз. Есть ли лучший способ справиться с этим? Или, что еще лучше, я ошибся в определении DeleteRange?

Благодарю вас!

Изменить:

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


person sa.key    schedule 15.01.2020    source источник
comment
Не проверено, но поскольку DeleteRange уже включает всю строку, работает ли DeleteRange.Delete?   -  person BigBen    schedule 15.01.2020
comment
Лист защищен? Какие-то объединенные ячейки?   -  person SJR    schedule 15.01.2020
comment
@BigBen Только что проверил это, выдает ту же ошибку - разочаровался, я не подумал попробовать это, хотя.   -  person sa.key    schedule 15.01.2020
comment
@SJR На листе нет защиты, и есть объединенные ячейки. Однако объединенные ячейки находятся за пределами DeleteRange и объединяются только между столбцами (без многострочных ячеек). Спасибо за вопросы!   -  person sa.key    schedule 15.01.2020


Ответы (2)


Я мог воспроизвести вашу проблему только тогда, когда рядом с диапазоном был объект (т.е. ListObject )

введите здесь описание изображения

Проверьте данные на листе и, если это так, используйте rDelete.Delete Shift:=xlUp.

Предполагая, что ваши ДАННЫЕ находятся в диапазоне A5:P# (где # — последняя строка данных), используйте этот код.

Sub Delete_Rows()
Dim ws As Worksheet
Dim rDelete As Range
Dim rData As Range, rRow As Range, lRw As Long

    Set ws = Worksheets("Data Validation")
    With ws
        lRw = .Range("A5").End(xlDown).Row
        Set rData = Range(.Range("A5"), Range("P" & lRw))    'adjust as required
    End With

    For Each rRow In rData.Rows
        If rRow.Cells(16) = "Yes" Then
            If rDelete Is Nothing Then
                Set rDelete = rRow

            Else
                Set rDelete = Union(rDelete, rRow)

    End If: End If: Next

    rDelete.Delete Shift:=xlUp

    End Sub
person EEM    schedule 15.01.2020
comment
Идеальный! Мои данные на самом деле были рядом с таблицей, о чем я сейчас понимаю, возможно, мне стоило упомянуть. Но указание направления сдвига решило проблему — я полагаю, что таблицы нуждаются в большем руководстве, чем неформатированный диапазон. Спасибо. - person sa.key; 16.01.2020

Добавьте в строку свойство «EntireRow» следующим образом:

Set DeleteRange = DataValWs.Cells(ThisRow, 16).EntireRow
person Allen    schedule 15.01.2020