Страницы: 1
RSS
Скопировать данные с одного листа на другой если несколько условий
 
Доброго дня. Есть vba который копирует данные с одного листа на другой если в поле E2 есть некая строка (слово). А как использовать несколько условий в поле E? то есть любое из слов в E2:E10. Если указываю диапазон то ошибка.  Если просто E2 то всё работает.

Нерабочий вариант
Код
If InStr(Sheets("Лист1").Cells(i, "F"), Sheets("Формулы").Range("E2:E10")) <> 0 Then  

А вот рабочий вариант

Код
If InStr(Sheets("Лист1").Cells(i, "F"), Sheets("Формулы").Range("E2")) <> 0 Then
Изменено: ole-van-de - 16.09.2019 18:02:07
 
ole-van-de, здравствуйте. Примитивно можно так
Код
…
dim x,arr

arr=Sheets("Формулы").Range("E2:E10").Value2
For each x in arr
If InStr(Sheets("Лист1").Cells(i, "F"),x)Then 'выполняем условие
next x
…
можно обойтись без цикла, сцепив в строку или наполнив словарь, но это уже совсем другая история
Изменено: Jack Famous - 16.09.2019 18:18:14
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Интересно, дома проверю, сейчас уже ухожу. А использовать принцип формулы условного форматирования, которая делает почти то же самое, только разукрашивает, можно?
Код
=СУММ(СЧЁТЕСЛИ($H1;"*"&Имя_Области&"*"))
Изменено: ole-van-de - 16.09.2019 18:23:17
 
Цитата
ole-van-de: использовать принцип формулы условного форматирования, которая делает почти то же самое, только разукрашивает, можно?
вам нужно скопировать данные, а этого функции листа не умеют. Как проверить вариантов несколько, но без примера в файле вряд ли что-то получится. Я просто сделал на примере вашего кода, чтобы работало
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
ole-van-de, пора бы уже показать небольшой файл-пример.
 
Ссори за задержку. Выкладываю файл. Есть два листа: "Все" (вся информация) и "Формулы" (здесь хранятся слова фильтры по которым надо искать). Нужно из листа "Все" скопировать данные на новый Лист на основании слов в столбце E2:E10 листа "Формулы". Всё просто. С одной ячейкой Е2 это получается, а вот диапазон воткнуть - пока нет. То есть имеется один макрос "Copy" и он работает с одной ячейкой E2.
Отдельная история - в этом файле есть правило условного форматирования, который подкрашивает строки в голубой цвет (пусть это не сбивает с толку) на основании  слов из диапазона A2:A100 опять же Листа "Формулы". Но это отдельная история, как уже говорил.
Я лишь хотел заметить, что и у условного форматирования и у макроса копирования данных применяется один и тот же принцип - находить строки по перечисленным словам в отдельном столбце другого листа "Формулы". И может быть в vba можно тоже обойтись всего одной строчкой в конструкции IF на подобии правила усл форматирования (я имею ввиду одну строчку только для IF, а не вообще одну строчку в макросе :) )
 
ole-van-de, у вас целое ТЗ развернулось. Уберите УФ и всё лишнее, оставив саму суть - копирование по условию. Потом попробуйте то, что я предложил
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Какое ТЗ? о чем вы? Вы впихиваете целый цикл в еще один имеющийся у меня здесь. Мне кажется можно обойтись countif и sum приспособив в конструкцию IF на подобии правила УФ, которое я спец оставил.  
 
ole-van-de, ну если уж вы считаете, что СЧЁТЕСЛИ или СУММЕСЛИ получают значение без цикла, то есть каким-то волшебным образом, то удачи  :D
А то, что вы цикл не видите, это ещё не значит, что его нет. К тому же я сказал, что есть способы ускорить процесс за счёт проверки, скажем, словаря или строки-сцепки, но разбираться во всех ваших вводных нет никакого желания…
Изменено: Jack Famous - 17.09.2019 11:01:00
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Ладно, допустим с циклом. Подготовил вариант. Но есть разочарование в VBA. В файле около 50 тыс строк и около 10 столбцов, при выборки на основе скрипта выше даже с одним условием, он захлебывается, уходит в глубокое раздумье на три мин и более и больше оттуда не выходит. Применять диапазон из 5-10 слов вообще нет смысла. (А я то проверял на примере из 150 строк и там всё работало). Что интересно, родной ручной фильтр Excel на 50 тыс строк работает быстро, секунда-две, но он ограничен двумя условиями ИЛИ (содержит слово..). А мне надо было до 6 условий. Неужели vba тугодумный...

Ну и вот вариант по нескольким условиям:

Код
Sub Copy()
Dim i, LastRow
LastRow = Sheets("All").Range("A" & Rows.Count).End(xlUp).Row
Sheets("Sheet2").Cells.Clear
Worksheets("All").Rows(1).Copy Destination:=Worksheets("Sheet2").Rows(1)
For i = 2 To LastRow
    For j = 2 To 10
If InStr(Sheets("All").Cells(i, "F"), Sheets("FilterWords").Cells(j, "E")) <> 0 Then
Sheets("All").Cells(i, "A").EntireRow.Copy Destination:=Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Offset(1)
End If
    Next j
Next i
End Sub
Изменено: ole-van-de - 17.09.2019 18:26:48
 
Цитата
ole-van-de: родной ручной фильтр Excel на 50 тыс строк работает быстро, секунда-две, но он ограничен двумя условиями ИЛИ (содержит слово..). А мне надо было до 6 условий. Неужели vba тугодумный...
обычно дело в прокладке…между рулём и сиденьем, как говорят механики  :)

Действительно, откуда разница, если я сравниваю 2 критерия с 6ю, притом диапазон со словами проверки у меня вообще на 9 ячеек (а значит и условий 9), да ещё я копирую по одной строке, да ещё и целиком, да ещё и обновление экрана не отключаю. Действительно, одно и то же  :D
Погуглите про методы и способы ускорения работы макросов…

Так должно быть пошустрее (проверьте диапазон проверяемых фраз)
Код
Sub Copy()
Dim x, arr, arrList, r&, n&, c As Byte
 
arrList = ActiveWorkbook.Worksheets("FilterWords").Cells(2, 5).Resize(10, 1).Value2 ' массив слов для поиска: со второй строки 5-го столбца берём 10 строк вниз
If Not IsArray(arrList) Then arrList = Array(arrList)
arr = ActiveWorkbook.Worksheets("Sheet2").UsedRange.Value2                          ' берём в массив всю рабочую область листа, откуда копировать
n = 1                                                                               ' оставляем первую строку с шапкой
 
    For r = 2 To UBound(arr, 1)                                                     ' проходим по всему массиву со 2ой строки
        For Each x In arrList                                                       ' проходим по всему списку слов
            If arr(r, 6) Like "*" & x & "*" Then                                    ' если слово содержится, то наполняем массив
                n = n + 1
                For c = 1 To UBound(arr, 2)
                    arr(n, c) = arr(r, c)
                Next c
                Exit For
            End If
        Next x
    Next r
If n = 1 Then Exit Sub                                                              ' если счётчик не изменился, то вставлять нечего
 
Application.ScreenUpdating = False
Worksheets.Add
ActiveSheet.Cells(1, 1).Resize(n, UBound(arr, 2)).Value2 = arr
Application.ScreenUpdating = True
End Sub
Изменено: Jack Famous - 18.09.2019 16:01:53 (Добавил строку проверки на массив)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Здорово конечно. Видно что работает быстро, конечно этих нюансов я не знал. Правда при повторном запуске, если пытаюсь изменить Resize(10, 1) на допустим Resize(1, 1) вываливается ошибка на 9 строку For Each x In arrList, и потом уже и возврат обратно не помогает пока не перезапустишь файл. Кстати фильтр так и не отработал, он копирует всё, но суть ясна, принцип хороший безусловно и скоростной.    
 
Цитата
ole-van-de: вываливается ошибка
добавьте после 4ой строки "arrList=" строку "If Not IsArray(arrList) Then arrList=Array(arrList)" (добавил строку в пост выше)
И изучайте массивы, раз их используете  ;)
Цитата
ole-van-de: возврат обратно не помогает
после выполнения любого (ну или практически любого) макроса, команда Undo (Отменить операцию) не работает
Цитата
ole-van-de: фильтр так и не отработал, он копирует всё
вот тут ничего не понял. Фильтр Excel мы не трогали и "фильтровали" (отбирали) данные внутри кода
Изменено: Jack Famous - 18.09.2019 16:04:49
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Спасибо!
 
ole-van-de, пожалуйста  ;)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Страницы: 1
Наверх