Строка поиска, фильтры и подсказки в форме 1С 8.3: от свойства таблицы до Elasticsearch

· 11 мин

Содержание

Чтобы добавить панель поиска в форму 1С 8.3, чаще всего хватает одного свойства: откройте форму списка в Конфигураторе, выделите элемент-таблицу и задайте Положение строки поиска — Командная панель или Верх. Платформа сама нарисует поле поиска и будет искать по видимым колонкам. Своё поле с кодом нужно, когда поиск должен работать по конкретному реквизиту, по нескольким полям сразу или с подсказками.

Выбор способа простой. Нужна обычная строка над списком — свойство таблицы. Нужны отборы «по складу», «по контрагенту» — быстрые отборы динамического списка. Нужен поиск по всей базе или по тексту файлов — полнотекстовый индекс. Миллионы строк и поиск «с опечатками» — внешний движок вроде Elasticsearch. Всё ниже — про управляемые формы и интерфейс «Такси»; обычным формам отведён отдельный раздел.

ЗадачаСпособКод нужен?Где работает
Строка поиска над спискомСвойство таблицы Положение строки поискаНетУправляемые формы
Отборы по реквизитамБыстрые отборы динамического спискаНетУправляемые формы
Поиск по одному полю с задержкойРеквизит формы + отбор спискаДа, 20–30 строкУправляемые формы
Подсказки при вводеСобытие АвтоПодбор или ввод по строкеДа / НетПоля ввода
Поиск по всей базеПолнотекстовый поискНет / немногоЛюбые формы
Нечёткий поиск по миллионам записейElasticsearch, ManticoreДа, плюс серверЛюбые формы

Какой поиск в 1С уже есть без доработок

Прежде чем трогать конфигурацию, проверьте, что умеет платформа. Часто «панель поиска» уже есть, просто пользователь о ней не знает.

  • 🔍 Строка поиска в списке. В типовых конфигурациях на «Такси» (БП 3.0, ЗУП 3.1, УТ 11) она стоит в командной панели почти всех списков. Ищет по тексту в видимых колонках.
  • ⌨️ Горячие клавиши . Ctrl+F ставит курсор в поиск, Alt+F открывает расширенный поиск по выбранной колонке, Ctrl+Q сбрасывает поиск.
  • 🧭 Глобальный поиск в заголовке главного окна. Ищет по командам, справке и данным базы. По данным — только если включён полнотекстовый поиск.
  • 📝 Ввод по строке. В поле ссылочного типа можно начать печатать название — программа предложит подходящие элементы справочника.
  • 🗂 Настройка списка. Через меню Ещё → Настроить список пользователь задаёт отбор по любому полю без программиста.

Полнотекстовый поиск в типовых конфигурациях включают в разделе Администрирование → Общие настройки, блок «Полнотекстовый поиск». Там же обновляют индекс и проверяют его актуальность.

Если пользователь жалуется «поиска нет», сначала проверьте его настройки формы. Поле поиска могли убрать через Ещё → Изменить форму. Команда Ещё → Изменить форму → Стандартные настройки вернёт форму к исходному виду.

Строка поиска в управляемой форме без программирования

Это первый и самый безопасный способ добавить поиск в 1С. Доработка занимает пару минут и не требует кода.

  1. Откройте конфигурацию в Конфигураторе. Если конфигурация на поддержке, лучше делать правку в расширении: так обновления не сотрут её.
  2. Найдите нужный объект, например справочник, и откройте его форму списка. Если формы нет, создайте её через конструктор форм.
  3. В дереве элементов выделите таблицу (обычно она называется Список).
  4. В палитре свойств найдите Положение строки поиска. Поставьте Командная панель — поле встанет справа на панели кнопок. Значение Верх разместит его отдельной строкой над таблицей.
  5. Там же есть Положение состояния просмотра и Положение управления поиском. Первое показывает, что список сейчас отфильтрован. Второе даёт кнопки управления поиском.
  6. Обновите конфигурацию базы данных (F7) или примените расширение и откройте форму в режиме «1С:Предприятие».

У таблицы в дереве элементов есть подчинённые элементы-дополнения: строка поиска, состояние просмотра, управление поиском. Их можно перетащить в любую группу формы. Так строку поиска ставят, например, в шапку над несколькими колонками.

Стандартная строка поиска ищет по колонкам, которые видны в таблице. Если нужного реквизита нет среди колонок, по нему она не найдёт. Добавьте колонку, пусть даже узкую.

Своя панель поиска с фильтрами

Стандартной строки мало, когда нужен поиск только по одному реквизиту, по артикулу и наименованию сразу или набор фильтров «Склад + Контрагент + Период». Здесь два пути.

Быстрые отборы динамического списка

Это поиск по реквизитам без кода.

  1. Откройте реквизит формы Список и нажмите «Открыть» у его настроек.
  2. На закладке «Отбор» добавьте нужные поля, например Склад и Контрагент.
  3. Для каждого поля задайте Режим отображения — Быстрый доступ.
  4. Создайте на форме обычную группу, например ГруппаОтборы.
  5. У таблицы Список в свойстве Группа пользовательских настроек укажите эту группу.

После этого над списком появятся поля отбора. Пользователь выбирает склад — список сразу фильтруется. Значения сохраняются в его настройках формы.

Поле поиска с отбором из кода

Когда нужна строка, которая ищет «по мере ввода» и только по одному полю, делают реквизит формы и обработчик.

  1. Создайте реквизит формы СтрокаПоиска с типом Строка и перетащите его на форму.
  2. У поля ввода назначьте обработчик события ИзменениеТекстаРедактирования.
  3. Вставьте код.
&НаКлиенте
Процедура СтрокаПоискаИзменениеТекстаРедактирования(Элемент, Текст, СтандартнаяОбработка)
	// Реквизит обновится только после выхода из поля, поэтому берём Текст
	СтрокаПоиска = Текст;
	ОтключитьОбработчикОжидания("ПрименитьПоиск");
	ПодключитьОбработчикОжидания("ПрименитьПоиск", 0.6, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ПрименитьПоиск()
	Значение = СокрЛП(СтрокаПоиска);
	ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(
		Список, "Наименование", Значение,
		ВидСравненияКомпоновкиДанных.Содержит, , ЗначениеЗаполнено(Значение));
КонецПроцедуры

Два приёма, без которых поле работает плохо:

  • ⏱ Задержка через обработчик ожидания. Без неё список перечитывается на каждую букву. Слово «Поставщик» — это девять запросов к серверу. С задержкой 0,6 секунды — один.
  • ✍️ Параметр Текст вместо реквизита. Пока курсор в поле, значение реквизита ещё старое. Код, который читает только реквизит, будет отставать на шаг.

Функция УстановитьЭлементОтбораДинамическогоСписка есть в Библиотеке стандартных подсистем, то есть во всех современных типовых. В конфигурации без БСП добавьте элемент в Список.Отбор.Элементы с типом ЭлементОтбораКомпоновкиДанных и заполните ЛевоеЗначение, ВидСравнения, ПравоеЗначение и Использование.

Чтобы искать сразу по двум полям, например по наименованию и артикулу, добавьте группу отбора ИЛИ (ГруппаЭлементовОтбораКомпоновкиДанных с типом ГруппаИли) и положите в неё два условия «Содержит».

Обычные формы: поиск в толстом клиенте

Обычные формы живут в старых конфигурациях и в доработках, которые не переводили на «Такси». Работают они только в толстом клиенте. Строки поиска как свойства таблицы там нет, поэтому поиск собирают руками.

  1. Добавьте на форму списка поле ввода и реквизит СтрокаПоиска.
  2. Рядом поставьте кнопку «Найти» или назначьте обработчик ПриИзменении поля.
  3. В обработчике установите отбор основного реквизита формы.
Процедура СтрокаПоискаПриИзменении(Элемент)
	ЭлементОтбора = СправочникСписок.Отбор.Наименование;
	ЭлементОтбора.ВидСравнения = ВидСравнения.Содержит;
	ЭлементОтбора.Значение = СокрЛП(СтрокаПоиска);
	ЭлементОтбора.Использование = Не ПустаяСтрока(СтрокаПоиска);
КонецПроцедуры

Для набора фильтров повторите то же для Отбор.Владелец, Отбор.Родитель или реквизитов справочника. Встроенный быстрый поиск по первым буквам в обычных формах тоже есть: пользователь печатает прямо в таблице, курсор прыгает к совпадению в отсортированной колонке.

Если базу переводят на «Такси», не переносите такой поиск один в один. Удалите самодельную панель и включите стандартную строку поиска — меньше кода на поддержке.

Подсказки при вводе: автоподбор в поле поиска

Подсказки — это выпадающий список вариантов, пока пользователь печатает. Тут тоже два варианта.

Без кода — ввод по строке. Если поле поиска имеет ссылочный тип (например, СправочникСсылка.Номенклатура), подсказки даёт сама платформа. В свойствах справочника задаются поля ввода по строке (наименование, код, можно добавить артикул) и способ поиска: по началу строки или по любой части. Там же можно разрешить полнотекстовый поиск при вводе по строке.

С кодом — событие АвтоПодбор. Нужен, когда поле строковое или подсказки берутся из другого источника. Создайте обработчик через палитру свойств: конструктор подставит параметры, которые ожидает ваша версия платформы. Затем заполните тело.

&НаКлиенте
Процедура СтрокаПоискаАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
	Если СтрДлина(СокрЛП(Текст)) < 3 Тогда
		Возврат;
	КонецЕсли;
	СтандартнаяОбработка = Ложь;
	ДанныеВыбора = ПодсказкиНаСервере(СокрЛП(Текст));
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПодсказкиНаСервере(Текст)
	Шаблон = СтрЗаменить(Текст, "~", "~~");
	Шаблон = СтрЗаменить(Шаблон, "%", "~%");
	Шаблон = СтрЗаменить(Шаблон, "_", "~_");
	Запрос = Новый Запрос(
	"ВЫБРАТЬ ПЕРВЫЕ 10
	|	Номенклатура.Наименование КАК Наименование
	|ИЗ
	|	Справочник.Номенклатура КАК Номенклатура
	|ГДЕ
	|	Номенклатура.Наименование ПОДОБНО &Шаблон СПЕЦСИМВОЛ ""~""
	|	И НЕ Номенклатура.ПометкаУдаления
	|УПОРЯДОЧИТЬ ПО
	|	Наименование");
	Запрос.УстановитьПараметр("Шаблон", Шаблон + "%");
	Результат = Новый СписокЗначений;
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		Результат.Добавить(Выборка.Наименование);
	КонецЦикла;
	Возврат Результат;
КонецФункции

Что здесь сделано по-взрослому:

  • 🔢 подсказки начинаются с трёх символов — на одну-две буквы найдётся пол-справочника;
  • 🧱 символы % и _ в тексте пользователя экранируются через СПЕЦСИМВОЛ, иначе ввод «50%» сломает шаблон;
  • 📏 ПЕРВЫЕ 10 ограничивает выдачу, длинный выпадающий список никто не листает;
  • 🎯 шаблон «по началу строки» (Текст + "%") быстрее, чем «по вхождению», — об этом в разделе про большие базы.

Внешние поисковые движки: Elasticsearch и Sphinx

Внешний движок нужен, когда встроенного поиска не хватает: каталог на сотни тысяч позиций, поиск с опечатками, морфология, ранжирование по релевантности. 1С при этом остаётся источником данных, а движок — отдельным сервером.

Схема из трёх частей:

  1. Выгрузка в индекс. Регламентное задание или план обмена отправляет изменённые элементы в движок. В индекс кладут уникальный идентификатор ссылки (УникальныйИдентификатор()) и поля для поиска.
  2. Запрос из формы. Панель поиска отправляет текст по HTTP и получает список идентификаторов.
  3. Показ результата. По идентификаторам 1С получает ссылки и ставит отбор списка «В списке».

Пример запроса к Elasticsearch с сервера 1С:

&НаСервереБезКонтекста
Функция НайтиВElasticsearch(Текст)
	Тело = Новый Структура("query, size",
		Новый Структура("match", Новый Структура("name", Текст)), 20);
	Запись = Новый ЗаписьJSON;
	Запись.УстановитьСтроку();
	ЗаписатьJSON(Запись, Тело);

	Соединение = Новый HTTPСоединение("search.local", 9200, , , , 10);
	Запрос = Новый HTTPЗапрос("/goods/_search");
	Запрос.Заголовки.Вставить("Content-Type", "application/json");
	Запрос.УстановитьТелоИзСтроки(Запись.Закрыть(), КодировкаТекста.UTF8);
	Ответ = Соединение.ОтправитьДляОбработки(Запрос);

	Чтение = Новый ЧтениеJSON;
	Чтение.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
	Данные = ПрочитатьJSON(Чтение, Истина);

	Ссылки = Новый Массив;
	Для Каждого Хит Из Данные["hits"]["hits"] Цикл
		Ид = Новый УникальныйИдентификатор(Хит["_source"]["uuid"]);
		Ссылки.Добавить(Справочники.Номенклатура.ПолучитьСсылку(Ид));
	КонецЦикла;
	Возврат Ссылки;
КонецФункции

ПрочитатьJSON с параметром Истина возвращает соответствие: так ключи вроде _source читаются без ограничений на имена. Порядок результатов из движка сохраняется только в массиве. Если показывать их через отбор динамического списка, сортировка будет по полю списка, а не по релевантности.

Sphinx обычно ставят в виде его форка Manticore Search: у него есть HTTP API с JSON, и подключение строится так же. Классический SphinxQL работает по протоколу MySQL, из 1С до него добираются через внешний источник данных или ODBC — это сложнее и требует драйвера на сервере.

Не открывайте порт поискового сервера в интернет: в индексе лежат ваши данные, а в старых версиях Elasticsearch авторизация по умолчанию выключена.

Готовые обработки и подсистемы для поиска

Писать всё с нуля приходится редко.

  • 📚 БСП, подсистема «Полнотекстовый поиск». Входит в типовые конфигурации. Даёт форму поиска по всем данным, регламентное обновление индекса и настройки в администрировании. В своей конфигурации на БСП её достаточно внедрить.
  • 🧩 Объект платформы ПолнотекстовыйПоиск. Для своей формы поиска по базе хватит десятка строк: ПолнотекстовыйПоиск.СоздатьСписок(Текст, 50), затем ПерваяЧасть() и обход элементов списка. У каждого элемента есть Значение (найденная ссылка) и Представление.
  • 🛠 Обработки «Поиск и замена значений», «Поиск ссылок на объект» в составе типовых — для служебного поиска, не для пользователей.
  • 🛒 Сторонние обработки с маркетплейсов разработчиков: универсальный поиск по всем справочникам, поиск по реквизитам документов. Перед установкой открывайте модуль и смотрите, что код делает с данными: внешняя обработка выполняется с правами пользователя.

У полнотекстового поиска в Конфигураторе у каждого объекта и реквизита есть свойство Полнотекстовый поиск — Использовать или Не использовать. Реквизиты с «Не использовать» в индекс не попадут, сколько его ни обновляй.

Как ускорить поиск в большой базе

На базе в 50 тысяч элементов любой из способов выше работает мгновенно. На миллионах строк начинаются тормоза, и причины почти всегда одни и те же.

Что тормозитПочемуЧто сделать
Отбор «Содержит»Шаблон %текст% не использует индекс, СУБД читает всю таблицуДля артикулов и кодов — «Начинается с»; для текста — полнотекстовый индекс
Поиск по реквизитуУ реквизита нет индексаСвойство реквизита Индексировать → Индексировать
Поиск на каждую буквуДесятки запросов на одно словоОбработчик ожидания 0,5–1 с, минимум 3 символа
Динамический список с произвольным запросомОтбор по вычисляемому полю идёт поверх всего запросаОтбор по реальным полям таблицы, основная таблица задана
Устаревший полнотекстовый индексНовые записи не находятся, пользователи ищут повторноРегламентное обновление индекса; слияние — ночью
Ограничения доступа на уровне записейКаждый запрос проверяет права построчноПроверить план запроса, упростить шаблоны ограничений

Обновление полнотекстового индекса с объединением (слиянием) на крупной базе идёт долго и нагружает сервер. Запускайте его в нерабочее время, а днём оставляйте только инкрементное обновление.

Добавление индекса к реквизиту меняет структуру базы. Обновление конфигурации БД потребует монопольного доступа, все пользователи должны выйти. Планируйте это на вечер.

Если поиск не работает или находит не то

Диагностика: выберите симптом

Частые вопросы

Можно ли добавить строку поиска в форму, которая открывается из типовой, не снимая её с поддержки?
Да. Создайте расширение конфигурации, заимствуйте форму и задайте свойство таблицы или добавьте своё поле в расширении. Основная конфигурация останется на полной поддержке.
Чем полнотекстовый поиск отличается от строки поиска в списке?
Строка поиска фильтрует один список по его колонкам. Полнотекстовый поиск ищет по индексу сразу во всех объектах базы, понимает словоформы, но требует обновления индекса.
Работает ли своя панель поиска в веб-клиенте и мобильном клиенте?
Да, код на управляемых формах с &НаКлиенте и &НаСервере работает в тонком, веб- и мобильном клиенте. Обычные формы работают только в толстом клиенте.
Можно ли искать без учёта регистра?
Да. Условие «Содержит» и оператор ПОДОБНО в 1С не различают регистр букв. Отдельно приводить строку к верхнему регистру не нужно.
Нужны ли права, чтобы пользователь видел поиск?
Строка поиска и отборы не требуют отдельных прав. Пользователь найдёт только те записи, которые ему разрешено читать.