Страницы: 1
RSS
Самое быстрое удаление строк, The Fastest Rows Deleting
 
Приветствую!

Как известно, самое быстрое удаление строк - это удаление их одним блоком. Для этого удаляемые строки должны идти подряд. Достигается это проставлением критерия удаления в дополнительном столбце, сортировкой по нему и последующим удалением блока строк.
Кто не в курсе — исследование от ZVI с готовым решением, за что ему огромная благодарность.   8) :idea:

Я же предлагаю не удалять строки, а оставить в Таблице только те, что нужны — с сохранением формул и форматирования умной таблицы. Нужно иметь в в иду, что данные ВНЕ исходной Таблицы никак затронуты не будут, а "лишние" строки Таблицы снизу будут полностью очищены методом Range.Clear. Таблица растягивается макросом под новый меньший размер.

Минус состоит только в том, что при сохранении строк и заполнении их новыми данными, пользовательское форматирование, примечания и всё такое могут потерять свою актуальность (выделять и пояснять — не то).
Решение: для выделений использовать УФ, а для комментариев - отдельный столбец.  :idea:

Основным "спонсором" этого праздника является метод получения/вставки массива с учётом формул: Range.FormulaLocal, что позволяет сохранить формулы при вставке (и идентифицировать их при цикле внутри массива, если нужно).
Пример сделан на основе "Умной Таблицы", однако с обычным диапазоном всё будет ещё проще (т.к. не нужно "растягивать" диапазон объекта умной таблицы).
Получается всё быстро, легко и просто
UPD: Функция для обычного диапазона. Передавать диапазон без заголовков

Для фильтрации массива, в качестве демонстрации работы, а также уменьшения кода, используется моя недавняя функция - таким образом, процедура удаления строк может занимать всего одну строку: If ФункцияФильтра() Then ФункцияУдаления() (в примере расписал подробнее).
Конструктивные замечания и предложения приветствуются  :)

UPD 08/12/2022 15:00
Добавлен вариант для удаления строк с помощью моих функций умного объединения и нарезки адресов.
Добавлен очень быстрый вариант для удаления строк с помощью инструмента «Удалить дубликаты»
Изменено: Jack Famous - 08.12.2022 15:00:40
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Перенесено отсюда
Тест функций умного объединения и нарезки адресов для удаления строк
Мой SmartUnion быстрее штатного от нескольких раз до тысяч раз и далее (в моём примере для удаления 10 тыс отдельных строк даёт выигрыш в 3 раза), а нарезка строк, крайне эффективная при форматировании большого количества диапазонов, здесь совершенно не помогает…
Изменено: Jack Famous - 08.12.2022 14:45:55
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Перенесено оттуда же

doober, SmartUnion, конечно, позволяет существенно (10 и более раз) обогнать построчное удаление, однако с методом удаления дублей соперничать не в состоянии…
А вот сам метод можно улучшить более, чем в 2 раза
Удаление строк (в примере - скрытых) с помощью инструмента «Удалить Дубликаты»
Нужно помнить ещё, что удаление дублей местами скидывает форматирование ячейки на Обычный стиль, а также, что в большой таблице его применение может быть затруднено или вовсе не оправдано (в то время как SmartUnion позволяет просто удалять строки, как обычно, но быстрее).
Изменено: Jack Famous - 08.12.2022 14:52:47
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
скажите пожалуйста, почему макрос PRDX_RD()
ругается на ошибку тут:
With shZero.Range("B2:B" & UBound(aReserve, 1))
а ошибка  вот такая: Ошибка Run time error 13. Type mismatch
 
azma, shZero - кодовое имя листа в VBE. Чтобы заработало в другом файле, присвойте кодовое имя, как в моем файле или объявите одноимённую переменную листа, и присвойте ей лист:
Код
Dim shZero As Worksheet
Set shZero=Worksheets("имя вашего листа")

    Если же дело происходит в моём файле, значит у вас переменная aReserve не инициирована (она заполняется при автоматической подготовке данных для теста). Внимательно пройдитесь по коду теста и поймите, что он делает и в какой последовательности.
Изменено: Jack Famous - 09.12.2022 09:30:13 (Добавил решение второй возможной причины и ссылку на кодовое имя листа)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Добрый вечер, Алексей!
Хорошая тема и наработки!
Удалить скрытые ячейки (см. #3) можно по-быстрому так:
Код
Sub Zvi_ClearHidden()
  Dim i&, j&
  j = UBound(aReserve)
  With shZero.Range("A2:B" & j)
    .Columns(2).Value2 = 1
    If shZero.FilterMode Then shZero.ShowAllData
    .Sort .Cells(2), xlAscending, Header:=xlNo
    i = WorksheetFunction.Count(.Columns(2))
    .Columns(2).Resize(i).ClearContents
    .Columns(1).Offset(i).Resize(j - i).Clear
  End With
End Sub
Изменено: ZVI - 08.12.2022 23:41:18
 
ZVI, приветствую!
Большое спасибо за такую положительную оценку моих (и не только) изысканий — очень приятно  :oops:

Полная очистка ячеек всё же не то же самое, что удаление строк, поэтому немного изменил ваш код и добавил к сравнению. Он быстрее примерно в 2 раза, чем мой  :D Дело мастера боится  8)
Файл и Код

Теперь о тестах:
    • изменил процедуру наполнения и фильтрации - теперь она запрашивает множитель исходных данных (целое положительное число), я тестировал, как и ранее, на x1, x10 и x100
    • тест теперь состоит из 2ух этапов: наполнение + фильтрация и запуск удаления (выбранный в коде вариант). 1ый этап запускается по даблклику в жёлтой A1, второй — в зелёной B1. Сделано это, чтобы можно было перед тестом заполнить данные вне удаляемого диапазона и посмотреть, как они меняются.
    • раздельный запуск позволил выяснить интересную особенность работы удаления дублей: "удаляются" только те строки, которые относятся к диапазону удаления дублей. То есть, удаляются не строки, а ячейки (со смещением вверх) пересечения строки с диапазоном удаления. То есть, данные в "строке удаления", находящиеся ВНЕ диапазона удаления, никуда не денутся. Может быть очень удобно.
    • методы успешно работают в умных таблицах (для удаления дублей в диапазон должна входить только умная таблица или её часть — диапазон для удаления дублей, состоящий из таблицы (или её части) и обычного диапазона вызовет ошибку (ожидаемо).
Изменено: Jack Famous - 09.12.2022 15:55:37
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал: ...не то же самое, что удаление строк...
Алексей, хорошо, но удаление ячеек в данном случае мало чем отличается от Clear - не важно  :)
Изменено: ZVI - 09.12.2022 14:09:53
 
Цитата
ZVI: удаление ячеек в данном случае мало чем отличается от Clear
очистка ячеек (.Clear или .ClearContents) про другое же. Для решения этой задачи могут использоваться указанные алгоритмы, но в рамках текущей задачи хотелось бы всё-таки рассмотреть именно удаление строк (или то, что даёт такой же результат).

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

Принципиальная важность удаления именно строки целиком заключается в гарантированном сохранении построчной связи данных. С помощью удаления ячеек со сдвигом или удалении дубликатов, нужно контролировать это самому (может быть полезно).
Изменено: Jack Famous - 09.12.2022 15:56:03
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Хорошо. Просто в 1-м сообщении: "...не удалять строки" и "... данные ВНЕ исходной Таблицы никак затронуты не будут, а 'лишние' строки Таблицы снизу будут полностью очищены методом Range.Clear."
 
Цитата
ZVI: очищены методом Range.Clear."
ааааа  :D  а шо ж вы ссылаетесь на #3 тогда?  :)
    Сказали бы, что это к первому методу "фильтр на месте с очищением строк вместо удаления"  :)
    Ваш вариант подходит лучше, т.к. позволяет сохранить все форматы и, безусловно, является отличным решением!  8)
Спасибо! :idea:
Изменено: Jack Famous - 09.12.2022 15:43:56
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Страницы: 1
Наверх