Страницы: 1
RSS
Удаление строки по 2 условиям
 
Прошу помочь,
как удалить строки из большой таблицы, которые есть уже в 2 разных таблицах на других листах.

Есть 3 таблицы на 6 тысяч строк и 62 столбца, где столбцы c E по BH скрыты
Нужно чтобы из Таблицы_1 удалялись полностью строки, которые есть в Таблице_2 и Таблице_3
Уникальный ключ: Артикул

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

Но им можно удалять только по одному артикулу, а у меня несколько тысяч строк.

Как модифицировать этот макрос, чтобы условия для удаления можно было задавать в столбце - скажем вставить список артикулов, которые надо удалить в столбце.
Изменено: Home1 - 29.01.2013 17:41:34
 
Цитата
Home1 пишет:
Нужно чтобы из Таблицы_1 удалялись полностью строки, которые есть в Таблице_2 и Таблице_3
Как вариант, если подобное надо делать постоянно и на больших объемах, обратиться к Access. И в нем все это делать одним запросом - записи без подчиненных, или же по ключевому/мым полю/ям... ;)
"Ctrl+S" - достойное завершение ваших гениальных мыслей!.. ;)
 
А если в Excel?
 
Вам бы в "Приемы" заглянуть, и оценить возможности - свои и Его Величества XL'я
- http://www.planetaexcel.ru/techniques/2/92/
- http://www.planetaexcel.ru/techniques/2/99/
а потом решать: своими силами обойдетесь (с помощью или без), или проще решение заказать - http://www.planetaexcel.ru/forum/index.php?PAGE_NAME=list&FID=7 ... ;)
"Ctrl+S" - достойное завершение ваших гениальных мыслей!.. ;)
 
А артикулы в Таблица_2 и Таблица_3 не повторяются?

Макрос в модуль листа "Таблица_1"

Option Explicit

Sub Udalenie()
Dim artikul As String
Dim FoundArtikul As Range
Dim iLastRow As Long
Dim i As Long
iLastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = iLastRow To 2 Step -1
artikul = Cells(i, 1)
Set FoundArtikul = Sheets("Таблица_2").Columns(1).Find(artikul, , xlFormulas, xlWhole)
If Not FoundArtikul Is Nothing Then
Cells(i, 1).EntireRow.Delete
End If
Set FoundArtikul = Sheets("Таблица_3").Columns(1).Find(artikul, , xlFormulas, xlWhole)
If Not FoundArtikul Is Nothing Then
Cells(i, 1).EntireRow.Delete
End If
Next
End Sub
 
Артикулы в Таблице_2 и Таблице_3 не повторяются - это в моём конкртеном случае, но бывает и повторяются.
 
"Subscrip out of range"

предположу, что ввиду того что скрыты столбцы с c E по BH во всех таблица и на всех листах
 
Прекрасно понимаю, что самый быстрый способ быть посланным в сад в поиск - это создать тему или даже вопрос на тему "поиск сроки с условием". Поэтому последние 3-4 часа копался сам. Около 20 тем есть только на этом форуме. Тем не менее, то ли лыжи..

В общем, вынужден снова попросить вашей помощи.

Описание задачи:
На листе есть несколько сотен тысяч строк. Пустых строк нет. Надо организовать быстрое удаление строк при одновременном выполнении двух условий: 1) в указанной колонке есть слово "Все". 2) поле Дата данной строки (колонка С) не должна быть меньше "даты зачистки" DateFrom.
При этом, условие 1) имеет некую особенность - если макрос вызывается для колонки В (артикул товара), то вместо слова "Все" при вызове процедуры используется слово "_CSKU". В этом случае удалению подлежат все строки, в которых число в колонке CSKU >= 1 000 000. При этом второе условие (дата) также должно выполняться.

Таким образом данная часть макроса должна вырезать сводные данные начиная с некой даты. В последующем сводные данные по всем складам будут снова перерассчитаны и перезалиты на данный лист. Хотя наверное, это уже лишняя информация  :)  .

К сожалению, подавляющее большинство примеров не учитывает скорость работы макроса, и в результате работает со скоростью 200..5000 строк в минуту. В итоге 600 000 / 5000 - получаем вечность. Но подходящее решение было найдено в виде ссылки на этом форуме http://www.sql.ru/forum/722758/udalenie-strok-v-bolshom-eksel-fayle.

А чуть позже в архиве найдена целая тема, в которой данный макрос был модифицирован автором по просьбам трудящихся:
http://planetaexcel.ru/forum/index.php?PAGE_NAME=message&FID=8&TID=24531&tags=&q=http%3A%2F%2Fwww.sql.ru%2Fforum%2F722758&FORUM_ID[0]=0&DATE_CHANGE=0&order=relevance&s=%D0%9D%D0%B0%D0%B9%D1%82%D0%B8&PAGEN_1=2

Но к сожалению, даже это, как говорится, разжеванное для особо одаренных, мне не помогло.

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

Прикладываю пример. В нем условно датой урезания принято 01.07.13
Для удобства, во всех строках, где я покопался, я поставил комментарий "!!!"
После запуска test_del_row должны удалиться все строки с красными ячейками.
Желтые удалятся, когда я запущу макрос для колонок D, и потом - F (я решил не делать это в одном вызове - меня устроит 3 вызова, т.к. макрос будет использоваться в разных частях и универсальность мне важнее).
Зеленые строки не будут удалены никогда, т.к. находятся до даты урезания. К сожалению, сейчас макрос этого не понимает и удаляет их.


Скрытый текст
Изменено: Alex-M - 09.09.2013 01:43:51
 
Этот макрос написан для анализа одного столбца.
Если нужно анализировать сразу несколько столбцов - тогда почти половину кода нужно переписывать.
Цикл For Each нужно менять на for x= n to m, чтоб привязаться к другому массиву.
Сейчас реализовывать некогда...
 
А точно макрос нужен?
Обычным фильтром это делается в три щелка.
 
Цитата
А точно макрос нужен?
Обычным фильтром это делается в три щелка.
точно. каждый день несколько десятков отчетов из 1С будут экспортироваться и обрабатываться. В ручную это просто не реально.
 
Цитата
Этот макрос написан для анализа одного столбца.
Если нужно анализировать сразу несколько столбцов - тогда почти половину кода нужно переписывать.
Цикл For Each нужно менять на for x= n to m, чтоб привязаться к другому массиву.
Сейчас реализовывать некогда...

Да я что-то такое подозревал. Сейчас тоже голова уже не варит. Попробую посмотреть еще раз модицикации макроса автором на другие темы, по-моему там было несколько колонок. Но самая шальная мысль была изначально - тупо создать для столбца дат массив-зеркало, который бы подглядывал на индекс основного массива, подсказывал ему что там с датой по этой же строке и при этом полностью бы дублировал все действия с индексами/размерами основного массива. Вся проблема опять-таки в законе подлости - именно массивы я не изучил детально и кое-какие моменты перевода мысли автора даются с трудом. Как говорится, будем искать :) Вот нюхом чувствую, что буквально парой фраз тут где-то должно быть счастье - уж очень не хочется менять макрос на другой - там ведь тоже могут быть свои грабли. Жаль что в копилке идей так и не появилось "самого правильного макроса для удаления строки по нескольким критериям" :)
Огромное спасибо за поддержку!
 
Ответ есть в теме другого форума, на которую Вы ссылались, в сообщении AndreTM
http://www.sql.ru/forum/722758-2/udalenie-strok-v-bolshom-eksel-fayle?mid=13221500#13221500

"Надо просто делать так: сначала в каком-нибудь одном столбце сформируйте с помощью формул некоторые значения, а затем уже примените DelRows к этому столбцу, указав значение, по которому нужно удалять."

Применительно к Вашему примеру, нужно сделать так:

1. Запишите, например, в ячейку AA2 такую формулу:
=--ЕСЛИ(C2>=ДАТА(2013;7;1); ИЛИ( B2>=1000000; D2="Все"; F2="Все" ) )

В начале формулы для удобства добавлены два минуса, чтобы строки удаления помечать единичкой, а не логическим значением ИСТИНА.

2. Скопируйте или протяните ячейку с формулой вниз до последней строки с данными

3. Используйте любую версию макроса DelRows для удаления строк.
При этом в качестве столбца значений укажите AA (27-й столбец), а в качестве DelValue укажите единичку.

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

Если при этом включить макрорекордер, и немного причесать код, то все 4 пункта могут выполняться и автоматически.

P.S. Вариант макроса (версия 7) для любых сложных критериев отбора уже сделал, после документирования выложу отдельно, здесь приведу ссылку.
Изменено: ZVI - 09.09.2013 10:23:17
 
Если это всё задумывается для обработки отчётов 1С - то может быть лучше сразу писать код для импорта только нужного из txt?
Я не знаю какие там отчёты выгружаете, но может быть удобнее выгружать текст, затем макросом выбирать только нужные строки.
Или как вариант - подключать текст как источник внешних данных к ACCESS и там уже запросом выбирать нужное.
Или ещё вариант - брать только нужное в EXCEL с помощью MSQuery.
Изменено: Hugo - 09.09.2013 09:35:59
 
ZVI, спасибо! Видимо, я вчера уже "поплыл" и пропустил этот момент, возможно из-за того, что что-либо писать в ячейки воспринимал как прямой риск сделать процедуру еще дольше. Сейчас понимаю, что если формулу прописать с умом, то получится очень даже ничего - то что и надо.
Спасибо!

Hugo, из txt итак берутся данные, которые нужны. Проблема в том, что эти данные могут в течение 1-2 недель корректироваться (задним числом) и мне надо каждый день просто перезаливать последние 2 недели.

Я подозреваю, что рано или поздно я столкнусь или с проблемами со скоростью (вернее это произошло уже сейчас, но они пока решаются, т.к. причина в моих кривых руках) или упрусь в количество строк на листе Excel. Понятно, что сегментированием проблему можно будет отсрочить, но рано или поздно это может стать серьезной преградой - все-таки Excel не база данных. Но здесь хорошие новости в том, что я сам управляю глубиной истории в данных и как только начну упираться в предел емкости или производительности - просто отрежу 1 квартал. А сейчас именно Excel + макросы дают мне беспрецедентное удобство в создании прототипа будущей серьезной системы (она будет на 1С). Это такой новый вид написания технического задания для программистов 1С - вместо "вот наброски на бумаге как это примерно может выглядеть" получаем "вот вам работающий код на VBA - сделайте тоже самое в 1С" :).

Спасибо Вам за помощь!

Ребята, вы реально делаете очень благое дело!
Сейчас посмотрел во скольких темах в людям помогаете - реально круто!
МОЛОДЦЫ!
Страницы: 1
Читают тему
Наверх