Страницы: 1
RSS
можно ли использовать метод Find для поиска по нескольким параметрам?, нужно найти информацию в таблице по двум ключевым столбцам - можно ли для этого использовать метод Find?
 
Коллеги, в VBA не силен, поэтому идея с Find может быть глупой... Find привлек значительно более высокими скоростями поиска по сравнению с другими методами (например, с поиском в цикле, используя If).
Задача: имеем таблицу, в которой первый и второй столбец содержат уникальный цифровой ключ клиента (ключ состоит из двух частей), необходимо выбрать определенного клиента. Необходимо иметь в виду, что "половинки" ключа не уникальны - могут быть одинаковыми у разных клиентов - то есть нужно искать клиента именно по полному ключу). Если такая возможность для Find существует, то прошу поделиться примером кода.
Для наглядности предлагаю считать, что две переменные (половинки) ключа нам известны:  Nm - код №1, а Nkl - код №2.
Если кому-то пригодиться, то вот оригинальный устаревший код, который искал информацию ориентируясь только на половинку кода - именно его я и адаптирую под текущую потребность.
Код
Set old_base_act = old_wb.sheets("База клиентов").Colomns(1).Find(what:=old_wsh.Cells(oCell.Row,2).value, Lookat:=xlWhole, Lookin:=xlFormulas)
Здесь old_wsh.Cells(oCell.Row,2).value - это переменная Nkl, Nm можно найти аналогично
Если Find не умеет искать по двум параметрам, то прошу подсказать другие быстрые методы (про СУММАМН для VBA знаю, именно ее и планирую использовать как запасной вариант, но, думаю, что Find будет быстрее).
Спасибо всем, кто откликнется.
 
Цитата
VIZ_VIZ написал:
Find привлек значительно более высокими скоростями поиска по сравнению
- это не всегда так
вы не код приводите в примере а что за данные у вас и по какому признаку надо и что найти.
Если искать надо в двух столбцах, то сперва ищется в одном и проверяется выполнения условия во втором, если не выполнилось , повторяется с поиска в первом.
https://www.planetaexcel.ru/forum/index.php?PAGE_NAME=message&FID=1&TID=121840&TITLE_SEO=121840-pri-pomoshchi-find-osushchestvit-poisk-po-stseplennym-dvum-stolbtsam&MID=1008529#message1008529
По вопросам из тем форума, личку не читаю.
 
Цитата
БМВ написал:
сперва ищется в одном и проверяется выполнения условия во втором, если не выполнилось , повторяется с поиска в первом.
Можно чуть подробнее? Как я понимаю, Find найдет несколько совпадений в столбце №1, выберет самую верхнюю строку (первое совпадение), я проверю данные в соседнем столбце, они могут не совпасть с искомыми. Как мне перейти к следующему совпадению?
И я не уверен, что Find умеет искать все совпадения, предполагаю, что данный метод выбирает самое первое совпадение и останавливается - это верно или я не прав?
За пример с циклами спасибо, но нам это не подходит - очень большие таблицы - циклы будут тормозить. Вместо циклов я планирую использовать ЕСЛИМН - думаю, что он будет быстрее, чем циклы. Либо я не разобрался в примере...
 
Метод у диапазона бывает не только Find, но и FindNext. В справке по F1 есть пример использования.
Кому решение нужно - тот пример и рисует.
 
Цитата
VIZ_VIZ: Find привлек значительно более высокими скоростями поиска по сравнению с другими методами (например, с поиском в цикле, используя If)
это вы ещё про массивы, видимо, не знаете. Обычно Find используется для поиска/замены с учётом формата.

По реализации: без файла-примера разговор пустой…
Изменено: Jack Famous - 28.10.2019 10:24:20
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Пытливый написал:
бывает не только Find, но и FindNext.
понравился пример по F1, но есть один вопрос, может быть подскажете, как с ними поступить?
Код
With Worksheets(1).Range("a1:a500")
     Set c = .Find(2, lookin:=xlValues)
     If Not c Is Nothing Then
        firstAddress = c.Address 'вместо этой строки поставлю проверку по второму столбцу
        Do 'в этот цикл добавлю свой код
            c.Value = 5
            Set c = .FindNext(c)
        If c is Nothing Then
            GoTo DoneFinding
        End If
        Loop While c.Address <> firstAddress
      End If
      DoneFinding:
End With
With Worksheets(1).Range("a1:a500") - у нас нет конкретных границ таблицы (она постоянно растет), можно изменить код на такой? With Worksheets(1)
Будет макрос работать или нужен другой код?
 
VIZ_VIZ, задайте переменную последней заполненной строки таблицы и сделайте
Код
With Worksheets(1).Range("a1:a" & lastrow)
 
Цитата
Hellmaster написал:
задайте переменную последней заполненной строки таблицы и сделайте
не имеет смысла
Код
With Worksheets(1).Range("a:a") 
будет достаточно так как Find сам справится с используемым диапазоном.
По вопросам из тем форума, личку не читаю.
 
Цитата
Jack Famous написал:
это вы ещё про массивы, видимо, не знаете.
Я вас правильно понял, с массивами VBA работает еще быстрее, чем с Find? Это полезная информация - буду знать. Спасибо!
 
VIZ_VIZ, а вы файл-пример сделайте - там и сравним. Я Find не использую…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Можно еще вычислить количество строк используемого диапазона. Если у вас таблица на листе начинается с первой строки, то можно вычислить количество используемых строк на листе через UsedRange:
Код
RowNum=Activesheet.UsedRange.Rows.Count

А потом найденное значение задать в диапазоне, в котором применяете Find
Код
Range("A1:A" & RowNum).Find(.....)
Кому решение нужно - тот пример и рисует.
 
Коллеги, спасибо всем, кто откликнулся. Думаю, что смогу допилить макрос на основе ваших подсказок.
Пример файла выложить не могу - под местный ресурс его очень долго обрезать - много весит. Да и интересного там ничего нет - две таблицы на разных страницах. В каждой первый и второй столбец - это составные части уникального номера клиента. Соответственно из первой таблицы макрос узнает номер нужного клиента, а из второй таблицы находит доп. информацию для данного клиента.
 
Цитата
Jack Famous написал:
Я Find не использую…
Цитата
Jack Famous написал:
Обычно Find используется для поиска/замены с учётом формата.
Алексей, не надо навязывать свои методы, любовь все загрузить в массив - тоже не всегда уместна. А давайте найдем последнюю заполненую ячейку на листе если и срока и столбец интересует.  А если это под миллион строк и несколько десятков столбцов - все в массив и перебор Так только загрузка в массив, займет время, а у некоторых и память может закончится :-).
Так что использовать надо то что нужно, и не использовать то что ненужно.
По вопросам из тем форума, личку не читаю.
 
Цитата
БМВ: не надо навязывать свои методы
где вы это увидели?
Цитата
БМВ: любовь все загрузить в массив - тоже не всегда уместна
а где я писал, что это всегда уместно?
Цитата
БМВ: давайте найдем последнюю заполненую ячейку на листе если и срока и столбец интересует
давайте - в чём проблема, собственно и какое отношение имеет к задаче?
Цитата
БМВ: А если это под миллион строк и несколько десятков столбцов
а если нет? Я поэтому про пример и сказал…
Цитата
БМВ: использовать надо то что нужно, и не использовать то что ненужно
очевидная истина, только как определить, что и когда нужно  ;)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
Обычно Find используется для поиска/замены с учётом формата.
Джек,  откуда это? Я про "обычно" ))
 
Юрий М, хорошо - перефразирую: я считаю, что Find практически незаменим для эффективного поиска (и замены) с учётом формата, т.к. массивы работают только со значениями. Find можно использовать и просто для поиска значений, но при прочих равных, массивы при правильном использовании будут быстрее

Тут очень много может быть "если" и именно поэтому…
Цитата
Jack Famous: По реализации: без файла-примера разговор пустой…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Уже не так категорично, и это хорошо ))
 
Юрий М, БМВ, прошу прощения, если это выглядело категорично - не вкладывал такой смысл… Разумеется, "методы всякие нужны, методы всякие важны"  :D
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous, Заинтересовали ваши комментарии про массивы. Можете черкнуть пару строк кода под условия, которые я указал в предыдущем комментарии?
 
Цитата
Jack Famous написал:
просто для поиска значений, но при прочих равных, массивы при правильном использовании будут быстрее
Алексей, не которое время назад занимались замерами и зависимость была такова, что на определенном размере массивы проигрывали и проигрыш был на времени загрузки Arr=Range.
Что касается конкретного вопроса, то простой SQL запрос с проверкой двух ключей, возможно , уделает и find и Arr. Вопрос, только в том, что нужно на выходе получить.
По вопросам из тем форума, личку не читаю.
 
Цитата
БМВ: Вопрос, только в том, что нужно на выходе получить
ну и что на входе))) и опять всё упирается в необходимость примера…
Самый быстрый (по моим наблюдениям и тестам  :D ) вариант передачи диапазона в массив - это
Код
Dim arr
arr=Range.Value2
— то есть переменная должна быть вариативной и не массивной, и именно Value2 (проигрывает Value только на булевых, но совсем незаметно, зато в других случаях очень хорошо выигрывает), но это уже совершенно другая тема
Цитата
VIZ_VIZ: Заинтересовали ваши комментарии про массивы
строго говоря, это и под тему не очень попадает, т.к. у вас вопрос конкретно про Find. Если правда интересно, то создайте новую тему с перекрёстными ссылками и сделайте в ней файл-пример — разберём  ;)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Немного дегтя в сторону Find: у него проблема при поиске данных из VBA, если применен фильтр или строки/столбцы скрыты.
А в остальном: не всегда Find предпочтительнее, но и массивы далеко не всегда выигрывают. При поиске в больших текстовых массивах Find будет в подавляющем большинстве случаев быстрее. Но все как всегда зависит от многих факторов.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Страницы: 1
Наверх