Как сделать поиск по справочнику и в запросах 1С 8.3
Содержание
Самый простой поиск в 1С уже встроен: встаньте на список и начните печатать — курсор прыгнет на подходящую строку. Но как только нужно искать сразу по наименованию и ИНН, подсказывать варианты при вводе или находить «сапоги» по запросу «сапог», штатного поиска по колонке не хватает.
Разберём пять рабочих механизмов — от поиска в форме без единой строки кода до полнотекстового поиска с морфологией и автоподбора с подсказками. Для каждого дам рабочий фрагмент на встроенном языке 1С 8.3 (интерфейс «Такси») и скажу, где он уместен, а где нет.
Поиск в списке справочника без программирования
В любой форме списка поиск работает сразу, кода писать не нужно.
- Поиск по текущей колонке. Кликните заголовок нужной колонки и начните набирать текст — список отфильтруется по совпадению. Это самый быстрый способ найти элемент по наименованию или коду.
- Строка поиска. Нажмите
Ctrl+Fили команду поиска в командной панели списка (значок с лупой). Появится поле ввода: вводите фрагмент, список показывает только подходящие строки. Поиск идёт по видимым колонкам. - Отбор списка. Команда
Еще → Настроить список → Отборпозволяет задать условие вручную: равно, содержит, в списке. Отбор сохраняется в настройках формы и переживает перезапуск.
Если поиск по колонке находит не то, проверьте, не включён ли уже отбор: он сужает выборку ещё до того, как вы начали искать.
Отдельный нюанс — иерархические справочники (номенклатура, подразделения). По умолчанию поиск идёт внутри открытой группы. Чтобы искать по всему справочнику сразу, переключите список в линейный вид: команда Еще → Режим просмотра → Список убирает дерево групп, и поиск охватывает все элементы.
Этого хватает для повседневной работы пользователя. Программировать приходится, когда поиск нужен нестандартный: по нескольким полям одновременно, с подсказками или по большому объёму данных.
Поиск сразу по нескольким реквизитам через отбор динамического списка
Задача: ввёл строку — нашлись контрагенты, у которых совпадает наименование или ИНН или код. Обычный отбор динамического списка соединяет условия через «И», поэтому для поиска «или по одному, или по другому полю» задают произвольный запрос списка с параметром.
В обработчике ПриСозданииНаСервере переводим список на произвольный запрос:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Список.ПроизвольныйЗапрос = Истина;
Список.ТекстЗапроса =
"ВЫБРАТЬ
| Контрагенты.Ссылка КАК Ссылка,
| Контрагенты.Наименование КАК Наименование,
| Контрагенты.ИНН КАК ИНН,
| Контрагенты.Код КАК Код
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.Наименование ПОДОБНО &Строка
| ИЛИ Контрагенты.ИНН ПОДОБНО &Строка
| ИЛИ Контрагенты.Код ПОДОБНО &Строка";
Список.Параметры.УстановитьЗначениеПараметра("Строка", "%");
КонецПроцедуры
На форму добавляем реквизит СтрокаПоиска (тип «Строка») и одноимённое поле ввода. В обработчике его изменения передаём значение в параметр запроса, обрамляя процентами:
&НаКлиенте
Процедура СтрокаПоискаПриИзменении(Элемент)
УстановитьПоиск(СтрокаПоиска);
КонецПроцедуры
&НаСервере
Процедура УстановитьПоиск(Текст)
Список.Параметры.УстановитьЗначениеПараметра("Строка", "%" + Текст + "%");
КонецПроцедуры
Оператор ПОДОБНО — это аналог LIKE в SQL. Знак % заменяет любое число символов, _ — ровно один. Шаблон %текст% находит вхождение в любом месте строки.
Если в искомых данных могут встречаться сами символы % и _ (например, в наименовании), экранируйте их: ПОДОБНО &Строка СПЕЦСИМВОЛ "~" и подставляйте в параметр ~%, ~_. Иначе пользовательский % сломает логику шаблона.
По умолчанию ПОДОБНО в большинстве баз сравнивает без учёта регистра, но это зависит от настроек СУБД. Чтобы не гадать, приведите обе стороны к одному регистру через ВРЕГ(): условие ВРЕГ(Контрагенты.Наименование) ПОДОБНО &Строка, а в параметр подставьте ВРег(Текст).
Тот же приём работает не только для списков, но и для поиска в обработке или отчёте: запрос с ПОДОБНО по нескольким полям и параметром строки поиска — универсальная заготовка. Разница лишь в том, куда отдаётся результат: в динамический список формы, в таблицу значений или в дерево. Чтобы совпадения «с начала строки» шли выше, добавьте в запрос вычисляемое поле признака и упорядочивайте по нему.
Полнотекстовый поиск, когда оператора ПОДОБНО уже не хватает
ПОДОБНО ищет по подстроке в конкретных полях. Когда надо искать по всей базе сразу, по комментариям и табличным частям, да ещё и с учётом словоформ — используют встроенный полнотекстовый поиск платформы.
Его сначала готовят:
- В свойствах объектов метаданных (справочников, документов) включите реквизиты в полнотекстовый поиск — свойство
Полнотекстовый поиск=Использовать. - Разрешите механизм:
ПолнотекстовыйПоиск.УстановитьРежимПолнотекстовогоПоиска(РежимПолнотекстовогоПоиска.Разрешить). - Постройте индекс:
ПолнотекстовыйПоиск.ОбновитьИндекс(). В рабочей базе это делает регламентное задание, вручную индекс обновляют черезАдминистрированиеили код.
Сам поиск выглядит так:
СписокФТ = ПолнотекстовыйПоиск.СоздатьСписок("резиновые сапоги", 20);
СписокФТ.ПерваяЧасть();
Для Сч = 0 По СписокФТ.Количество() - 1 Цикл
Элемент = СписокФТ.Получить(Сч);
Сообщить(Элемент.Значение);
КонецЦикла;
Второй параметр СоздатьСписок — размер порции. Полнотекстовый поиск отдаёт результаты частями: ПерваяЧасть(), затем СледующаяЧасть(). Свойство Значение элемента — это ссылка на найденный объект.
Если индекс не построен или устарел, полнотекстовый поиск не найдёт ничего либо выдаст неполный результат — это самая частая причина «поиск не работает ».
Полнотекстовый поиск понимает операторы: кавычки для точной фразы, * для усечения, И/ИЛИ/НЕ для логики, # для нечёткого поиска с опечатками. Это ровно тот случай, когда простым ПОДОБНО не обойтись.
Чтобы показать пользователю не только ссылку, но и фрагмент с подсвеченным совпадением, у списка полнотекстового поиска есть метод получения оформленного результата в виде текста с выделением найденных слов. Это удобно, когда результаты выводятся не в обычный список формы, а в поле HTML-документа — как в глобальном поиске самой платформы.
Автоподбор: поиск с подсказками прямо при вводе
Поля ввода ссылочных типов в 1С уже подсказывают варианты при наборе — это встроенный автоподбор. Для своего поля (например, строки поиска) подсказки делают через событие АвтоПодбор.
На поле ввода назначьте обработчик события «АвтоПодбор»:
&НаКлиенте
Процедура ПолеПоискаАвтоПодбор(Элемент, Текст, ДанныеВыбора,
Параметры, Ожидание, СтандартнаяОбработка)
Если Ожидание = 0 Тогда
// Быстрый выбор без паузы — не дёргаем сервер
Возврат;
КонецЕсли;
Если СтрДлина(Текст) < 2 Тогда
Возврат; // ждём хотя бы два символа
КонецЕсли;
ДанныеВыбора = ПодобратьВарианты(Текст);
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПодобратьВарианты(Текст)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 10
| Контрагенты.Ссылка КАК Ссылка,
| Контрагенты.Наименование КАК Наименование
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.Наименование ПОДОБНО &Текст";
Запрос.УстановитьПараметр("Текст", Текст + "%");
Результат = Новый СписокЗначений;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Результат.Добавить(Выборка.Ссылка, Выборка.Наименование);
КонецЦикла;
Возврат Результат;
КонецФункции
Параметр Ожидание — пауза перед срабатыванием. Пока она равна нулю, пользователь ещё печатает; обращаться к базе на каждый символ не нужно. Поиск по префиксу Текст + "%" (без ведущего %) работает заметно быстрее, потому что может использовать индекс.
Отбирайте ПЕРВЫЕ 10 строк. Выпадающий список на сотни позиций неудобен и грузит сервер при каждом нажатии клавиши.
Морфология: поиск по разным формам слова
ПОДОБНО — это сравнение символов: по запросу «сапог» элемент «сапоги» не найдётся. Чтобы поиск понимал словоформы русского языка, нужна морфология, а её из коробки даёт только полнотекстовый поиск.
Полнотекстовый поиск платформы использует морфологические словари. По запросу «сапог» он найдёт «сапоги», «сапогам», «сапогом» — приводит слова к начальной форме перед сравнением. Отдельно это включать не нужно: морфология работает в полнотекстовом поиске по умолчанию.
Если нужно найти слово строго в заданной форме, заключите его в кавычки — тогда морфология для этого слова отключается. Нечёткий поиск с учётом опечаток включается оператором #: запрос #трансформатор найдёт и «транформатор».
Вывод простой: нужна словоформа — это полнотекстовый поиск. Через ПОДОБНО морфологию не сделать, не изобретайте для этого самодельные словари.
Как ускорить поиск в больших базах
На справочнике в сотни тысяч строк разница между правильным и наивным поиском — это секунды против минут. Что влияет сильнее всего:
| Приём | Эффект |
|---|---|
| Индекс на искомом поле | Поиск по префиксу идёт по индексу, а не перебором |
Шаблон текст% вместо %текст% | Ведущий % отключает индекс — полный перебор таблицы |
ВЫБРАТЬ ПЕРВЫЕ N | Ограничивает выборку, не тянет всю базу в форму |
| Полнотекстовый поиск | На больших объёмах быстрее множества ПОДОБНО |
Пауза Ожидание в автоподборе | Один запрос вместо запроса на каждый символ |
Главный момент — индексы. Чтобы поиск по реквизиту был быстрым, в конфигураторе у реквизита установите свойство Индексировать = Индексировать (или Индексировать с доп. упорядочиванием, если по полю ещё и сортируете). Если фильтруете часто сразу по двум полям (например, организация + контрагент), помогает не два отдельных индекса, а один составной — его создают через индексы объекта метаданных.
Ещё один резерв — не тянуть в форму лишние колонки. В тексте запроса динамического списка оставляйте только те поля, что реально показываются и участвуют в поиске. Каждая лишняя колонка — это дополнительное соединение и чтение данных на каждое открытие формы.
Шаблон с ведущим процентом %текст% индекс использовать не может в принципе — СУБД вынуждена просмотреть каждую строку. На больших таблицах это и есть причина «тормозит поиск».
Если по смыслу подходит поиск «начинается с», всегда предпочитайте префиксный шаблон текст%. Поиск «содержит в середине» на больших данных лучше переводить на полнотекстовый механизм.
ПОДОБНО через ИЛИ.АвтоПодбор поля ввода + запрос по префиксу Текст% с лимитом ПЕРВЫЕ 10.ПолнотекстовыйПоиск.СоздатьСписок.Частые ошибки при реализации поиска
Ошибки повторяются от проекта к проекту:
ПОДОБНОбез процентов.ПОДОБНО &Строкабез%— это точное совпадение, а не поиск по части. Процент добавляют в параметр, а не в текст запроса.- Ведущий
%на большой таблице. Шаблон%текст%отключает индекс. На справочнике в сотни тысяч строк это главный тормоз. - Запрос на каждый символ. Без проверки
Ожиданиев автоподборе сервер получает запрос на каждое нажатие клавиши. Проверяйте паузу и минимальную длину строки. - Полнотекстовый индекс не обновлён. Поиск «не находит» часто означает, что индекс не построен или устарел. Проверьте регламентное задание обновления индекса.
- Регистр. Если поиск в вашей СУБД чувствителен к регистру, нормализуйте обе стороны через
ВРЕГ(). - Неэкранированные спецсимволы. Символы
%и_в искомом тексте безСПЕЦСИМВОЛломают шаблон. Для пользовательского ввода экранирование обязательно.
Частые вопросы
Можно ли искать по нескольким полям без произвольного запроса списка?
ИЛИ в условии.Чем `ПОДОБНО` отличается от полнотекстового поиска?
ПОДОБНО сравнивает символы в конкретных полях и не понимает словоформы. Полнотекстовый поиск ищет по всей базе, учитывает морфологию и опечатки, но требует включённого и обновлённого индекса.Почему полнотекстовый поиск ничего не находит?
Как сделать подсказки при вводе в своём поле?
ДанныеВыбора списком значений. Запрос стройте по префиксу Текст% и ограничивайте ПЕРВЫЕ 10.Поиск по подстроке тормозит — что делать?
%текст% на префиксный текст% и проиндексируйте поле. Для поиска вхождения в середину строки на больших данных переходите на полнотекстовый поиск.