Vba - удалить видимые строки после применения фильтра

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

Однако он очень глючный, и мне нужна помощь, чтобы исправить это, пожалуйста.

Вот что должен делать второй макрос:

1) Просто удалите видимые строки после применения фильтра, кроме первой строки (заголовков). - в настоящее время он удаляет ВСЕ видимые строки, включая первую строку, хотя в моем коде есть функция Offset.

2) Удалить все фильтры - теперь работает нормально

Sub DeleteVisibleRows()

Dim ws1 As Worksheet
Dim WorkRng As Range

Set ws1 = ActiveWorkbook.Sheets("Consolidated")

On Error Resume Next

Set WorkRng = Application.Selection

Application.ScreenUpdating = False
With ws1

WorkRng.Offset(1, 0).Rows.SpecialCells(xlCellTypeVisible).EntireRow.Delete

ws1.AutoFilterMode = False

End With

Application.ScreenUpdating = True
End Sub

Проблема кроется в строке Set WorkRng = Application.Selection. Вам следует избегать использования Selection и попытаться лучше определить свой диапазон. Что такое Selection при запуске этого макроса? Вы можете смещать на 1, но все равно включать заголовки. Кроме того, On Error Resume Next не нужен, и если его не сбросить, вы не увидите других ошибок.

Darrell H 11.04.2018 14:26

@DarrellH выборка - это отфильтрованные данные после применения первого макроса. Поэтому я отфильтровываю дату с предыдущего дня, тогда отображаемые данные станут моим выбором. Я вижу, что многие люди категорически против возобновления ошибок в следующий раз, я не кодировщик VBA, поэтому я не знаю, почему это так. Что я могу сделать вместо этого?

Eitel Dagnin 11.04.2018 14:30

Я вижу, у вас сейчас много вариантов. Причина против On Error Resume Next в том, что вы не можете отлаживать то, чего не знаете. Бывают случаи, когда это применимо, но вы должны знать, почему.

Darrell H 11.04.2018 15:23

@DarrellH Хорошо, спасибо за совет :)

Eitel Dagnin 11.04.2018 16:34
0
4
14 312
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

Sub DeleteVisibleRows()
Dim ws As Worksheet
Dim lastrow As Long, i As Long

Set ws = ThisWorkbook.Worksheets("Consolidated")
With ws
    lastrow = .Cells(.Rows.Count, "B").End(xlUp).Row
    For i = lastrow To 2 Step -1 'To 2 Assuming first row contains headers
        If .Rows(i).Hidden = False Then
            .Rows(i).Delete
        End If
    Next
.ShowAllData 'remove filtered data
End With
End Sub

@EitelDagnin Например, я забыл добавить ссылку на ws в свой диапазон, который я редактировал сейчас. Такие ошибки могут привести к удалению данных с неправильных / активных в данный момент листов.

Tehscript 11.04.2018 14:42

Спасибо за ваш ответ. Я пробовал ваш код, к сожалению, код застревает в цикле, и я ждал около 2–3 минут, прежде чем фактически принудительно отменил макрос.

Eitel Dagnin 11.04.2018 16:28

@EitelDagnin Каков диапазон вашей таблицы в "Сводном" листе? Есть ли еще записи после вашей таблицы?

Tehscript 11.04.2018 16:36

В листе нет «таблицы». Это просто необработанные данные в ячейках. Я не создавал таблицу из данных.

Eitel Dagnin 11.04.2018 16:40

@EitelDagnin Хорошо, позвольте мне спросить вас вот так: какой у вас отфильтрованный диапазон, включая заголовки?

Tehscript 11.04.2018 16:44

Поэтому я копирую данные с 3 листов в консолидированный лист, но данные вставляются из строки 2 и далее, поскольку в строке 1 есть заголовки столбцов. Я фильтрую данные (длина которых будет изменяться при каждом импорте) в столбце B, который в первой строке имеет заголовок «Дата». Это фильтрует данные по дате, а затем мне нужно удалить то, что видно, пока применяется фильтр. Надеюсь, что удалось ответить на ваш вопрос?

Eitel Dagnin 11.04.2018 16:48

@EitelDagnin Я думаю, у вас нет данных по столбцу A. Это может быть проблемой. Я меняю последнюю строку из-за столбца B, поскольку вы упомянули, что фильтруете его. Я также нашел ошибку и поправил код. При этом не удалялись соседние значения, поэтому я перевернул цикл снизу вверх. Можешь попробовать сейчас?

Tehscript 11.04.2018 16:54

Еще раз спасибо за ответ, но код просто зависает. Я должен принудительно остановить макрос.

Eitel Dagnin 12.04.2018 10:04

Если вы используете SELECTION, нет необходимости определять рабочий лист. Все, что вам нужно, имеет отношение к вашему выбору - ваш выбор может отсутствовать на рабочем листе Consolidated, хотя он всегда будет на родительском объекте вашего выбора.

В приведенном ниже коде предполагается, что у вас применен фильтр - если это не так, все, что находится под заголовком, удаляется.

Public Sub DeleteVisibleRows()

    Dim WorkRng As Range

    Set WorkRng = Selection

    With WorkRng
        .Offset(1, 0).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible).EntireRow.Delete
    End With

    WorkRng.Parent.AutoFilterMode = False

End Sub  

Редактировать: Этот код слишком длинный, я избавлюсь от ненужного.

Public Sub DeleteVisibleRows()

    With Selection
        .Offset(1, 0).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible).EntireRow.Delete
        .Parent.AutoFilterMode = False
    End With

End Sub

Я получаю сообщение об ошибке, определяемой приложением или объектом, @Darren

Eitel Dagnin 11.04.2018 15:30

Странно. Не могу заставить работать нет. Я попытался поместить код за Sheet1 и выбрал диапазон в Sheet2, я попытался поместить код в Book2 и выбрать диапазон в Book1. Каждый раз он удалял видимые строки в выделении, оставляя заголовок. Так что же особенного в ваших данных, что может вызвать .... заблокированы ли ваши ячейки и защищен ли лист где-нибудь в строках, которые вы пытаетесь удалить? Это вызовет ошибку - когда он не может удалить ячейки, которые вы ему указываете.

Darren Bartrup-Cook 11.04.2018 15:41

Нет, ячейки не заблокированы, и на листе или в книге нет защиты. Я, честно говоря, не знаю, что здесь сказать. Я скопировал ТОЧНО код, который был в вашем блоке кода в разделе «Изменить» в вашем вопросе, а затем запустил код, и это ошибка, которую я получаю ..

Eitel Dagnin 11.04.2018 16:36

Вы выбрали только одну ячейку? Имея только одну ячейку, .Rows.Count вернет 1, а ?Selection.Resize(Selection.Rows.Count-1).Address вернет сообщение об ошибке (изменение размера выделения до 0 строк).

Darren Bartrup-Cook 11.04.2018 16:50

Спасибо @Darren, это не проблема, Davesexcel предоставил решение, и оно отлично работает. Тем не менее, спасибо за вашу помощь :)

Eitel Dagnin 12.04.2018 10:08
Ответ принят как подходящий

SpecialCells будет работать так же, как и предыдущий ответ.

    Sub Button1_Click()
    Dim sh As Worksheet, rng As Range, LstRw As Long

    Set sh = Sheets("Sheet1")
    With sh
        LstRw = .Cells(.Rows.Count, "A").End(xlUp).Row
        Set rng = .Range("A2:A" & LstRw).SpecialCells(xlCellTypeVisible)
        rng.EntireRow.Delete
        .AutoFilterMode = False
    End With
End Sub

Другие вопросы по теме