Метод Find объекта Range для поиска ячейки по ее данным в VBA Excel. Синтаксис и компоненты. Знаки подстановки для поисковой фразы. Простые примеры.
Метод Find объекта Range предназначен для поиска ячейки и сведений о ней в заданном диапазоне по ее значению, формуле и примечанию. Чаще всего этот метод используется для поиска в таблице ячейки по слову, части слова или фразе, входящей в ее значение.
Синтаксис метода Range.Find
Expression.Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat) |
Expression – это переменная или выражение, возвращающее объект Range, в котором будет осуществляться поиск.
В скобках перечислены параметры метода, среди них только What является обязательным.
Метод Range.Find возвращает объект Range, представляющий из себя первую ячейку, в которой найдена поисковая фраза (параметр What). Если совпадение не найдено, возвращается значение Nothing.
Если необходимо найти следующие ячейки, содержащие поисковую фразу, используется метод Range.FindNext.
Параметры метода Range.Find
Наименование | Описание |
---|---|
Обязательный параметр | |
What | Данные для поиска, которые могут быть представлены строкой или другим типом данных Excel. Тип данных параметра — Variant. |
Необязательные параметры | |
After | Ячейка, после которой следует начать поиск. |
LookIn | Уточняет область поиска. Список констант xlFindLookIn:
|
LookAt | Поиск частичного или полного совпадения. Список констант xlLookAt:
|
SearchOrder | Определяет способ поиска. Список констант xlSearchOrder:
|
SearchDirection | Определяет направление поиска. Список констант xlSearchDirection:
|
MatchCase | Определяет учет регистра:
|
MatchByte | Условия поиска при использовании двухбайтовых кодировок:
|
SearchFormat | Формат поиска – используется вместе со свойством Application.FindFormat. |
* Примечания имеют две константы с одним значением. Проверяется очень просто: MsgBox xlComments
и MsgBox xlNotes
.
В справке Microsoft тип данных всех параметров, кроме SearchDirection, указан как Variant.
Знаки подстановки для поисковой фразы
Условные знаки в шаблоне поисковой фразы:
- ? – знак вопроса обозначает любой отдельный символ;
- * – звездочка обозначает любое количество любых символов, в том числе ноль символов;
- ~ – тильда ставится перед ?, * и ~, чтобы они обозначали сами себя (например, чтобы тильда в шаблоне обозначала сама себя, записать ее нужно дважды: ~~).
Простые примеры
При использовании метода Range.Find в VBA Excel необходимо учитывать следующие нюансы:
- Так как этот метод возвращает объект Range (в виде одной ячейки), присвоить его можно только объектной переменной, объявленной как Variant, Object или Range, при помощи оператора Set.
- Если поисковая фраза в заданном диапазоне найдена не будет, метод Range.Find возвратит значение Nothing. Обращение к свойствам несуществующей ячейки будет генерировать ошибки. Поэтому, перед использованием результатов поиска, необходимо проверить объектную переменную на содержание в ней значения Nothing.
В примерах используются переменные:
- myPhrase – переменная для записи поисковой фразы;
- myCell – переменная, которой присваивается первая найденная ячейка, содержащая поисковую фразу, или значение Nothing, если поисковая фраза не найдена.
Пример 1
Sub primer1() Dim myPhrase As Variant, myCell As Range myPhrase = «стакан» Set myCell = Range(«A1:L30»).Find(myPhrase) If Not myCell Is Nothing Then MsgBox «Значение найденной ячейки: « & myCell MsgBox «Строка найденной ячейки: « & myCell.Row MsgBox «Столбец найденной ячейки: « & myCell.Column MsgBox «Адрес найденной ячейки: « & myCell.Address Else MsgBox «Искомая фраза не найдена» End If End Sub |
В этом примере мы присваиваем переменной myPhrase значение для поиска – "стакан"
. Затем проводим поиск этой фразы в диапазоне "A1:L30"
с присвоением результата поиска переменной myCell. Далее проверяем переменную myCell, не содержит ли она значение Nothing, и выводим соответствующие сообщения.
Ознакомьтесь с работой кода VBA в случаях, когда в диапазоне "A1:L30"
есть ячейка со строкой, содержащей подстроку "стакан"
, и когда такой ячейки нет.
Пример 2
Теперь посмотрим, как метод Range.Find отреагирует на поиск числа. В качестве диапазона поиска будем использовать первую строку активного листа Excel.
Sub primer2() Dim myPhrase As Variant, myCell As Range myPhrase = 526.15 Set myCell = Rows(1).Find(myPhrase) If Not myCell Is Nothing Then MsgBox «Значение найденной ячейки: « & myCell Else: MsgBox «Искомая фраза не найдена» End If End Sub |
Несмотря на то, что мы присвоили переменной числовое значение, метод Range.Find найдет ячейку со значением и 526,15
, и 129526,15
, и 526,15254
. То есть, как и в предыдущем примере, поиск идет по подстроке.
Чтобы найти ячейку с точным соответствием значения поисковой фразе, используйте константу xlWhole параметра LookAt:
Set myCell = Rows(1).Find(myPhrase, , , xlWhole) |
Аналогично используются и другие необязательные параметры. Количество «лишних» запятых перед необязательным параметром должно соответствовать количеству пропущенных компонентов, предусмотренных синтаксисом метода Range.Find, кроме случаев указания необязательного параметра по имени, например: LookIn:=xlValues
. Тогда используется одна запятая, независимо от того, сколько компонентов пропущено.
Пример 3
Допустим, у нас есть многострочная база данных в Excel. В первой колонке находятся даты. Нам необходимо создать отчет за какой-то период. Найти номер начальной строки для обработки можно с помощью следующего кода:
Sub primer3() Dim myPhrase As Variant, myCell As Range myPhrase = «01.02.2019» myPhrase = CDate(myPhrase) Set myCell = Range(«A:A»).Find(myPhrase) If Not myCell Is Nothing Then MsgBox «Номер начальной строки: « & myCell.Row Else: MsgBox «Даты « & myPhrase & » в таблице нет» End If End Sub |
Несмотря на то, что в ячейке дата отображается в виде текста, ее значение хранится в ячейке в виде числа. Поэтому текстовый формат необходимо перед поиском преобразовать в формат даты.
VIZ_VIZ Пользователь Сообщений: 106 |
#1 28.10.2019 09:21:11 Коллеги, в VBA не силен, поэтому идея с Find может быть глупой… Find привлек значительно более высокими скоростями поиска по сравнению с другими методами (например, с поиском в цикле, используя If).
Здесь old_wsh.Cells(oCell.Row,2).value — это переменная Nkl, Nm можно найти аналогично |
||
БМВ Модератор Сообщений: 21385 Excel 2013, 2016 |
#2 28.10.2019 09:29:35
— это не всегда так 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 По вопросам из тем форума, личку не читаю. |
||
VIZ_VIZ Пользователь Сообщений: 106 |
#3 28.10.2019 10:12:08
Можно чуть подробнее? Как я понимаю, Find найдет несколько совпадений в столбце №1, выберет самую верхнюю строку (первое совпадение), я проверю данные в соседнем столбце, они могут не совпасть с искомыми. Как мне перейти к следующему совпадению? |
||
Пытливый Пользователь Сообщений: 4587 |
Метод у диапазона бывает не только Find, но и FindNext. В справке по F1 есть пример использования. Кому решение нужно — тот пример и рисует. |
Jack Famous Пользователь Сообщений: 10852 OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome |
#5 28.10.2019 10:24:07
это вы ещё про массивы, видимо, не знаете. Обычно Find используется для поиска/замены с учётом формата. По реализации: без файла-примера разговор пустой… Изменено: Jack Famous — 28.10.2019 10:24:20 Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄ |
||
VIZ_VIZ Пользователь Сообщений: 106 |
#6 28.10.2019 11:02:36
понравился пример по F1, но есть один вопрос, может быть подскажете, как с ними поступить?
With Worksheets(1).Range(«a1:a500») — у нас нет конкретных границ таблицы (она постоянно растет), можно изменить код на такой? With Worksheets(1) |
||||
Hellmaster Пользователь Сообщений: 208 |
#7 28.10.2019 11:14:13 VIZ_VIZ, задайте переменную последней заполненной строки таблицы и сделайте
|
||
БМВ Модератор Сообщений: 21385 Excel 2013, 2016 |
#8 28.10.2019 11:37:10
не имеет смысла
будет достаточно так как Find сам справится с используемым диапазоном. По вопросам из тем форума, личку не читаю. |
||||
VIZ_VIZ Пользователь Сообщений: 106 |
#9 28.10.2019 11:44:44
Я вас правильно понял, с массивами VBA работает еще быстрее, чем с Find? Это полезная информация — буду знать. Спасибо! |
||
Jack Famous Пользователь Сообщений: 10852 OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome |
VIZ_VIZ, а вы файл-пример сделайте — там и сравним. Я Find не использую… Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄ |
Пытливый Пользователь Сообщений: 4587 |
#11 28.10.2019 12:04:55 Можно еще вычислить количество строк используемого диапазона. Если у вас таблица на листе начинается с первой строки, то можно вычислить количество используемых строк на листе через UsedRange:
А потом найденное значение задать в диапазоне, в котором применяете Find
Кому решение нужно — тот пример и рисует. |
||||
VIZ_VIZ Пользователь Сообщений: 106 |
Коллеги, спасибо всем, кто откликнулся. Думаю, что смогу допилить макрос на основе ваших подсказок. |
БМВ Модератор Сообщений: 21385 Excel 2013, 2016 |
#13 28.10.2019 12:34:26
Алексей, не надо навязывать свои методы, любовь все загрузить в массив — тоже не всегда уместна. А давайте найдем последнюю заполненую ячейку на листе если и срока и столбец интересует. А если это под миллион строк и несколько десятков столбцов — все в массив и перебор Так только загрузка в массив, займет время, а у некоторых и память может закончится :-). По вопросам из тем форума, личку не читаю. |
||||
Jack Famous Пользователь Сообщений: 10852 OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome |
#14 28.10.2019 12:49:30
где вы это увидели?
а где я писал, что это всегда уместно?
давайте — в чём проблема, собственно и какое отношение имеет к задаче?
а если нет? Я поэтому про пример и сказал…
очевидная истина, только как определить, что и когда нужно Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄ |
||||||||||
Юрий М Модератор Сообщений: 60586 Контакты см. в профиле |
#15 28.10.2019 12:58:52
Джек, откуда это? Я про «обычно» )) |
||
Jack Famous Пользователь Сообщений: 10852 OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome |
#16 28.10.2019 13:17:20 Юрий М, хорошо — перефразирую: я считаю, что Find практически незаменим для эффективного поиска (и замены) с учётом формата, т.к. массивы работают только со значениями. Find можно использовать и просто для поиска значений, но при прочих равных, массивы при правильном использовании будут быстрее Тут очень много может быть «если» и именно поэтому…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄ |
||
Юрий М Модератор Сообщений: 60586 Контакты см. в профиле |
Уже не так категорично, и это хорошо )) |
Jack Famous Пользователь Сообщений: 10852 OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome |
Юрий М, БМВ, прошу прощения, если это выглядело категорично — не вкладывал такой смысл… Разумеется, «методы всякие нужны, методы всякие важны» Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄ |
VIZ_VIZ Пользователь Сообщений: 106 |
Jack Famous, Заинтересовали ваши комментарии про массивы. Можете черкнуть пару строк кода под условия, которые я указал в предыдущем комментарии? |
БМВ Модератор Сообщений: 21385 Excel 2013, 2016 |
#20 28.10.2019 13:48:43
Алексей, не которое время назад занимались замерами и зависимость была такова, что на определенном размере массивы проигрывали и проигрыш был на времени загрузки Arr=Range. По вопросам из тем форума, личку не читаю. |
||
Jack Famous Пользователь Сообщений: 10852 OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome |
#21 28.10.2019 14:13:12
ну и что на входе))) и опять всё упирается в необходимость примера…
— то есть переменная должна быть вариативной и не массивной, и именно Value2 (проигрывает Value только на булевых, но совсем незаметно, зато в других случаях очень хорошо выигрывает), но это уже совершенно другая тема
строго говоря, это и под тему не очень попадает, т.к. у вас вопрос конкретно про Find. Если правда интересно, то создайте новую тему с перекрёстными ссылками и сделайте в ней файл-пример — разберём Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄ |
||||||
Дмитрий(The_Prist) Щербаков Пользователь Сообщений: 14182 Профессиональная разработка приложений для MS Office |
#22 28.10.2019 14:32:21 Немного дегтя в сторону Find: у него проблема при поиске данных из VBA, если применен фильтр или строки/столбцы скрыты. Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы… |
@JMB17
Unfortunately, I’m working on two computers. I cannot see the attached file because this computer does not have a full suite of Excel and the other is restricted for downloads.
Below is the VBA code I’m using and working perfectly. So instead of section CommandBox1 having only one search criteria, I want to have two and the ability to list up to ten orders (TextBox 2, 3, etc) that meet that criteria. Then when I add a date in TextBox14 and click the update button, those orders are updated.
Private Sub CommandButton1_Click()
Dim Current_Status As String
Currrent_Status=Trim(TextBox1.Text)
lastrow=Worksheets(«Overall»).Cells(Rows.Count, 1).End(x1Up).Row
For i =2 To lastrow
If Worksheets(«Overall»).Cells(i, 1).Value=Current_Status Then
TextBox2.Text=Worksheets(«Overall»).Cells(i, 3).Value
TextBox14.Text=Worksheets(«Overall»).Cells(i, 11).Value
End If
Next
End Sub
————————————————————
Private Sub CommandButton2_Click()
Dim Current_Status As String
Currrent_Status=Trim(TextBox1.Text)
lastrow=Worksheets(«Overall»).Cells(Rows.Count, 1).End(x1Up).Row
For i =2 To lastrow
If Worksheets(«Overall»).Cells(i, 1).Value=Current_Status Then
Worksheets(«Overall»).Cells(i, 3).Value=TextBox2.Text
Worksheets(«Overall»).Cells(i, 11).Value=TextBox14.Text
End If
Next
End Sub
Sorry for the long post but I hope it provides clarity to what I want to do.
Thank you,
Roy
Добрый день! Заранее прошу не кидаться тапками, второй день занимаюсь макросами, ранее с ними не сталкивалась.
Есть табличка, в первой колонке название города, в третьей — месяц. Остальные колонки — курсы валют.
Также есть файл на каждый город, в каждом файле вкладка на каждый месяц.
Необходимо для каждого города и каждого месяца найти строку с курсами валют и разнести их по файлам.
Повторов строк нет и я не стала указывать до какой строчки максимально спускаться, потому что подразумевается, что нужное значение точно найдется.
Он не хочет никак выбирать оба условия для if, выбирает только город и берет первую самую строчку с ним для любого месяца. В чем может быть ошибка?
Visual Basic | ||
|
Поиск в столбце по нескольким условиям |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |