О чем будем говорить
Задача поиска элементов справочника по наименованию — одна из самых частых в практике 1С-разработчика. В платформе 1С:Предприятие 8.5 (актуально и для современных версий 8.3) есть несколько способов её решения. Каждый метод имеет свои сильные и слабые стороны, и выбор конкретного зависит от вашей задачи.
Метод НайтиПоНаименованию()
НайтиПоНаименованию() — встроенный метод менеджера справочника. Ищет по точному совпадению или по началу наименования.
Синтаксис:
НайтиПоНаименованию(<Наименование>, <ТочноеСоответствие>, <Родитель>, <Владелец>)- <Наименование> — что ищем.
- <ТочноеСоответствие> (необязательный, по умолчанию
Ложь):- Истина — полное совпадение.
- Ложь — совпадение с началом наименования.
- <Родитель> (необязательный) — группа справочника.
- <Владелец> (необязательный) — для подчинённых справочников.
// Поиск точного совпадения
НайденныйЭлемент = Справочники.Номенклатура.НайтиПоНаименованию("Стул офисный", Истина);
// Поиск по началу наименования (найдёт "Ручка шариковая", "Ручка перьевая")
НайденныйЭлемент = Справочники.Контрагенты.НайтиПоНаименованию("Ручка", Ложь);
// Поиск в конкретной группе
НайденныйЭлемент = Справочники.Товары.НайтиПоНаименованию("Мышь", Ложь, ГруппаКомплектующие);Возвращает: ссылку на элемент или пустую ссылку. Если есть дубли, возвращается первый попавшийся.
Достоинства: предельная простота, относительно высокая скорость (использует индекс).
Недостатки: не умеет искать произвольную подстроку (например, найти все наименования, содержащие «орг»).
Поиск через запрос
Запрос позволяет искать по любым шаблонам, в том числе по вхождению подстроки.
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
| ИЗ Справочник.Номенклатура КАК Номенклатура
| ГДЕ Номенклатура.Наименование ПОДОБНО &ИскомаяСтрока";
// Ищем номенклатуры, где в наименовании есть: "прот"
Запрос.УстановитьПараметр("ИскомаяСтрока", "%" + "прот" + "%");
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();Служебные символы в шаблоне:
%— любое количество любых символов._— ровно один любой символ.[...]— один символ из диапазона (например,[а-я]).[^...]— один символ, кроме указанных.
Поиск с перебором в цикле
Самый очевидный способ для новичка: пройтись по всем элементам и проверить вхождение подстроки.
ИскомаяПодстрока = "стол";
Результаты = Новый Массив;
Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
Если Найти(Выборка.Наименование, ИскомаяПодстрока) > 0 Тогда
Результаты.Добавить(Выборка.Ссылка);
КонецЕсли;
КонецЦикла;
Для Каждого Ссылка Из Результаты Цикл
Сообщить(Ссылка);
КонецЦикла;Как работает:
Найти(ГдеИщем, ЧтоИщем) возвращает позицию первого вхождения (или 0, если не найдено). Условие > 0 означает, что подстрока присутствует.
Достоинства: простота.
Недостатки:
- Очень низкая производительность на больших данных. При 10 000 записей будет 10 000 итераций и 10 000 поисков подстроки.
- Не использует индексы СУБД.
- При долгом выполнении может блокировать таблицы.
Опытные разработчики избегают этого метода в рабочих конфигурациях. Чаще всего это подходит лишь в качестве учебной задачи.
Регулярные выражения
Регулярные выражения нужны, когда нужно проверить или извлечь данные сложного формата: телефон, email, артикул, код валюты, номер документа и т.п. Это не является отдельным способом поиска по наименованию. Скорее это дополнительный полезный инструмент, который можно использовать в комбинации с приведенными методами поиска по наименованию. Начиная с версии 8.3.23 в платформе появились собственные средства для работы с регулярными выражениями:
- СтрПодобнаПоРегулярномуВыражению() — проверяет, соответствует ли строка шаблону
- СтрНайтиПоРегулярномуВыражению() — находит первое вхождение по шаблону
- СтрНайтиВсеПоРегулярномуВыражению() — находит все вхождения по шаблону
- СтрЗаменитьПоРегулярномуВыражению() — заменяет все вхождения на указанную подстроку
Специальные символы для построения регулярных выражений:
Символ Значение Пример
\d Любая цифра \d{2} — две цифры
\D Не цифра \D+ — один или несколько не-цифр
\s Пробел, табуляция \s* — ноль или более пробелов
\S Не пробел
\w Буква, цифра, подчёркивание
\W Не буква/цифра/подчёркивание
^ Начало строки ^\d — строка начинается с цифры
$ Конец строки \d$ — строка заканчивается цифрой
[а-я] Один символ из диапазона [0-9A-F] — шестнадцатеричная цифра
[^а-я] Любой символ, кроме указанных
| ИЛИ (кот|пёс) — либо "кот", либо "пёс"
() Группа (ab)+ — повторение "ab"
{n,m} От n до m повторений \d{2,4} — от двух до четырёх цифр
* 0 или более раз \s*
+ 1 или более раз \d+
? 0 или 1 раз -? — необязательный минусПример проверки формата артикула:
СтрокаДляПроверки = "ABC123";
РегулярноеВыражение = "^[A-Z]{3}\d{3}$";
Если СтрПодобнаПоРегулярномуВыражению(СтрокаДляПроверки, РегулярноеВыражение) Тогда
Сообщить("Артикул корректен");
Иначе
Сообщить("Ошибка формата");
КонецЕсли;