Excel vba удаление строк умной таблицы

Обновлено: 04.07.2024

Цель: в таблице разрешить пользователям выбирать строки (строки, в которых находится SELECTION), нажать короткий отрезок и удалить эти строки. Независимо от того, фильтруются ли они, а выбор находится в непересекающихся диапазонах или нет.

У меня есть код ниже, который я получил с другого сайта и изменил его:

Проблемы, которые я получаю, варьируются: от ошибки времени выполнения 1004: переместить ячейки в отфильтрованном диапазоне или таблицу, чтобы удалить метод clase (или что-то, это происходит реже, чем первый)

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

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

При программном удалении нескольких непоследовательных строк/столбцов/ячеек/областей лучше всего сделать это в обратном порядке.

Когда вы удаляете строку, Excel сдвигает строки под ней. Поэтому последующие номера строк легко путаются, вызывая ошибки или, что еще хуже, непреднамеренно потерянные данные.

пример

Представьте, что вы хотите удалить строки 1, 4, 5 and 7 . Если вы удаляете их по одному за раз, начиная с вершины, то вы удаляете строку 1 , которая позволяет номерам других строк удалять 3, 4 and 6 . Удалите 3 и теперь вам нужно удалить 3 and 5 .

Чтобы удалить строки 1, 4, 5 and 7 одному, начиная сверху, вам действительно нужно удалить строки 1, 3, 3, and 4 (да, вы бы дважды удалили строку 3 ).

Есть несколько способов обойти это:

Удалите все строки сразу. Вы можете присоединиться к каждой из выбранных строк с помощью метода Union а затем удалить весь диапазон в одном.

Или, мои предпочтения:

Перемещайтесь по строкам назад, начиная с нижней части данных и прокладывая себе путь вверх. Так как For..Each петля не может быть For..Each в обратном направлении, вам нужно переключиться на For..Next .

Вы можете найти последнюю заполненную строку (используя столбец A в моем примере) с свойством Range.End , а затем использовать метод Intersect для сравнения каждой строки с пользователем. .Selection строк и/или ячеек. Если они пересекаются, то вы можете. .Delete строку.

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

Предположу, что почти каждый сталкивался с ситуацией, когда необходимо удалить только определенные строки: имеется большая таблица и необходимо удалить из неё только те строки, которые содержат какое-то слово (цифру, фразу). Для выполнения подобной задачи можно воспользоваться несколькими способами.

Способ первый:
Использовать встроенное средство Excel - фильтр. Сначала его необходимо "установить" на листе:

  • Выделяем таблицу с данными, включая заголовки. Если их нет - то выделяем с самой первой строки таблицы, в которой необходимо удалить данные
  • устанавливаем фильтр:
    • для Excel 2003 : Данные-Фильтр-Автофильтр
    • для Excel 2007-2010 : вкладка Данные (Data) -Фильтр (Filter)(или вкладка Главная (Home) -Сортировка и фильтр (Sort&Filter) -Фильтр (Filter) )

    Теперь выбираем условие для фильтра:

    • в Excel 2003 надо выбрать Условие и в появившейся форме выбрать непосредственно условие("равно", "содержит", "начинается с" и т.д.), а напротив значение в соответствии с условием.
    • Для 2007-2010 Excel нужно выбрать Текстовые фильтры (Text Filters) и либо сразу выбрать одно из предлагаемых условий, либо нажать Настраиваемый фильтр (Custom Filter) и ввести значения для отбора в форме

    После этого удалить отфильтрованные строки. В 2007 Excel могут возникнуть проблемы с удалением отфильтрованных строк, поэтому рекомендую сначала так же прочитать статью: Excel удаляет вместо отфильтрованных строк - все?! Как избежать.


    Способ второй:
    применить код VBA, который потребует только указания значения, которое необходимо найти в строке и номер столбца, в котором искать значение.

    Если значение sSubStr не будет указано, то будут удалены строки, ячейки указанного столбца которых, пустые.
    Данный код необходимо поместить в стандартный модуль. Вызвать с листа его можно нажатием клавиш Alt + F8 , после чего выбрать Del_SubStr и нажать Выполнить. Если в данном коде в строке
    If -(InStr(Cells(li, 1), sSubStr) > 0) = lMet Then
    вместо = lMet указать <> lMet , то удаляться будут строки, не содержащие указанное для поиска значение. Иногда тоже удобно.
    Но. Данный код просматривает строки на предмет частичного совпадения указанного значения. Например, если Вы укажете текст для поиска "отчет", то будут удалены все строки, в которых встречается это слово("квартальный отчет", "отчет за месяц" и т.д.). Это не всегда нужно. Поэтому ниже приведен код, который будет удалять только строки, указанные ячейки которых равны конкретно указанному значению:

    Здесь так же, как и в случае с предыдущим кодом можно заменить оператор сравнения( Cells(li, lCol) = sSubStr ) с равно на неравенство( Cells(li, lCol) <> sSubStr ) и тогда удаляться будут строки, значения ячеек которых не равно указанному.

    УДАЛЕНИЕ СТРОК НА ОСНОВАНИИ СПИСКА ЗНАЧЕНИЙ(МНОЖЕСТВЕННЫЕ КРИТЕРИИ)
    Иногда бывают ситуации, когда необходимо удалить строки не по одному значению, а по нескольким. Например, если строка содержит или Итог или Отчет. Ниже приведен код, при помощи которого можно удалить строки, указав в качестве критерия диапазон значений.
    Значения, которые необходимо найти и удалить перечисляются на листе с именем "Лист2". Т.е. указав на "Лист2" в столбце А(начиная с первой строки) несколько значений - они все будут удалены. Если лист называется иначе(скажем "Соответствия") в коде необходимо будет "Лист2" заменить на "Соответствия". Удаление строк происходит на активном в момент запуска кода листе. Это значит, что перед запуском кода надо перейти на тот лист, строки в котором необходимо удалить.

    Чтобы код выше удалял строки не по точному совпадению слов, а по частичному(например, в ячейке записано "Привет, как дела?", а в списке есть слово "привет" - надо удалить, т.к. есть слово "привет"), то надо строку:

    If CStr(arr(li, 1)) = sSubStr Then

    заменить на такую:

    If InStr(1, arr(li, 1), sSubStr, 1) > 0 Then

    УДАЛЕНИЕ ИЗ ЛИСТА СТРОК, КОТОРЫХ НЕТ В СПИСКЕ ЗНАЧЕНИЙ(МНОЖЕСТВЕННЫЕ КРИТЕРИИ)
    Т.к. в последнее время стало поступать все больше и больше вопросов как не удалять значения по списку, а наоборот - оставить в таблице только те значения, которые перечислены в списке - решил дополнить статью и таким кодом.
    Значения, которые необходимо оставить перечисляются на листе с именем "Лист2". Т.е. указав на "Лист2" в столбце А(начиная с первой строки) несколько значений - после работы кода на листе будут оставлены только те строки, в которых присутствует хоть одно из перечисленных в списке значений. Если лист называется иначе(скажем "Соответствия") в коде необходимо будет "Лист2" заменить на "Соответствия". Удаление строк происходит на активном в момент запуска кода листе. Это значит, что перед запуском кода надо перейти на тот лист, строки в котором необходимо удалить.
    В отличие от приведенных выше кодов, данный код ориентирован на то, что значения в списке указаны не полностью. Т.е. если необходимо оставить только те ячейки, в которых встречается слово "активы", то в списке надо указать только это слово. В этом случае если в ячейке будет записана фраза "Нематериальные активы" или "Активы сторонние" - эти ячейки не будут удалены, т.к. в них встречается слово "активы". Регистр букв при этом неважен.

    Чтобы код выше сравнивал значения таблицы со значениями списка по точному совпадению слов, а не по частичному, то надо строку:

    If InStr(1, arr(li, 1), sSubStr, 1) > 0 Then

    заменить на такую:

    If CStr(arr(li, 1)) = sSubStr Then

    Для всех приведенных кодов можно строки не удалять, а скрывать. Для этого надо строку:

    If Not rr Is Nothing Then rr.EntireRow.Delete

    заменить на такую:

    If Not rr Is Nothing Then rr.EntireRow.Hidden = True

    По умолчанию все коды начинают просмотр строк с первой по последнюю заполненную на листе. И если необходимо удалять строки не с первой или не по последнюю, то надо внести корректировки в эту строку:

    For li = 1 To lLastRow 'цикл с первой строки до конца

    1 - это первая строка; lLastRow - определяется автоматически кодом и равна номеру последней заполненной строки на листе. Если надо начать удалять строки только с 7-ой строки(например, в первых 6-ти шапка), то код будет выглядеть так:

    Включение и отключение макросов через меню разработчика

    Основное внимание мы уделим процедуре включения и отключения макросов в самой популярной и распространённой на сегодня версии программы — Excel 2010. Потом, более бегло поговорим о том, как это сделать в других версиях приложения.

    Включить или отключить макросы в Microsoft Excel можно через меню разработчика. Но, проблема состоит в том, что по умолчанию данное меню отключено. Чтобы его включить, переходим во вкладку «Файл». Далее, кликаем по пункту «Параметры».


    В открывшемся окне параметров, переходим в раздел «Настройка ленты». В правой части окна данного раздела устанавливаем галочку около пункта «Разработчик». Жмем на кнопку «OK».


    После этого, на ленте появляется вкладка «Разработчик».

    Переходим во вкладку «Разработчик». В самой правой части ленты расположен блок настроек «Макросы». Чтобы включить или отключить макросы, кликаем по кнопке «Безопасность макросов».


    Открывается окно центра управления безопасностью в разделе «Макросы». Для того, чтобы включить макросы, переставляем переключатель в позицию «Включить все макросы». Правда, данное действие разработчик не рекомендует выполнять в целях безопасности. Так что, всё выполняется на свой страх и риск. Жмем на кнопку «OK», которая расположена в нижнем правом углу окна.


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

    1. Отключить все макросы без уведомления;
    2. Отключить все макросы с уведомлением;
    3. Отключить все макросы, кроме макросов с цифровой подписью.

    В последнем случае, макросы, у которых будет иметься цифровая подпись, смогут выполнять задачи. Не забываем жать на кнопку «OK».


    Включение и отключение макросов через параметры программы

    Существует ещё один способ включения и отключения макросов. Прежде всего, переходим в раздел «Файл», и там жмем на кнопку «Параметры», как и в случае включения меню разработчика, о чем мы говорили выше. Но, в открывшемся окне параметров, переходим не в пункт «Настройка ленты», а в пункт «Центр управления безопасностью». Кликаем по кнопке «Параметры центра управления безопасностью».


    Открывается то же самое окно Центра управления безопасностью, в которое мы переходили через меню разработчика. Переходим в раздел «Параметры макросов», и там включаем или отключаем макросы тем же способом, как делали это в прошлый раз.


    Настройка макросов в Параметрах программы


    1. Заходим в меню «Файл», и выбираем в нем пункт «Параметры» – аналогично первому пункту в рассмотренном ранее примере.
    2. Но теперь вместо настроек ленты, выбираем раздел “Центр управления безопасностью”. В правой части окна щелкаем на кнопку “Параметры центра управления безопасностью…”
    3. В итоге система нас направит в окно с настройками макросов, которое открывалось и при выполнении операции во вкладке Разработчика. Далее выбираем нужную нам опцию и кликаем “OK”.

    Встроенная функция рабочего листа

    Функция VBA Trim удаляет пробелы только по краям строки, не затрагивая двойные, тройные и т.д. пробелы внутри текста. Для удаления всех лишних пробелов следует использовать встроенную функцию Trim рабочего листа Excel.

    Пользовательская функция

    Можно бороться с лишними пробелами и с помощью пользовательской функции:

    Удаление при помощи сортировки

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

    Удаление при помощи выделения группы ячеек

    Макрос для удаления пустых строк

    Как удалить строку макросом? Если нужно сделать так чтобы макрос автоматически не только выделял, но и сам удалял пустые целые и смежные диапазоны ячеек без использования других инструментов, тогда в конце кода для переменной diapaz2.Select следует изменить метод на [Delete]:

    Sub DelLine()
    Dim i As Long
    Dim diapaz1 As Range
    Dim diapaz2 As Range
    Set diapaz1 = Application.Range(ActiveSheet.Range( "A1" ), _
    ActiveSheet.Cells.SpecialCells(xlCellTypeLastCell))
    For i = 1 To diapaz1.Rows.Count
    If WorksheetFunction.CountA(diapaz1.Rows(i).EntireRow) = 0 Then
    If diapaz2 Is Nothing Then
    Set diapaz2 = diapaz1.Rows(i).EntireRow
    Else
    Set diapaz2 = Application.Union(diapaz2, diapaz1.Rows(i).EntireRow)
    End If
    End If
    Next
    If diapaz2 Is Nothing Then
    MsgBox "Ненайдено ниодной пустой строки!"
    Else
    diapaz2.[Delete]
    End If
    End Sub

    Пример второго VBA-кода:


    Макрос для скрытия пустых строк

    Как скрыть пустые строки макросом? Но если вам нужно не удалить, а только скрыть (например, при подготовке документа на печать), тогда эту строку кода следует модифицировать несколько иначе:

    Читайте также: