Поле поиска в 1С 8.3: от реквизита формы до кода
Содержание
Проще всего поле поиска добавить так: открыть форму в Конфигураторе, завести строковый реквизит, положить его на форму и в обработчике ПриИзменении передать текст в отбор динамического списка. Это 10–15 строк кода и ни одной внешней библиотеки.
Но «поле поиска» в 1С 8.3 бывает разным. Иногда достаточно встроенного поиска, который платформа уже дала динамическому списку. Иногда нужен свой реквизит с отбором по нескольким полям. А когда ищут по тексту внутри документов и комментариев — подключают полнотекстовый поиск. Ниже — все рабочие способы, код для управляемой формы и то, как не посадить производительность на больших справочниках.
Какой способ поиска выбрать
Сначала определитесь с задачей — от неё зависит объём работы.
- 🔍 Встроенный поиск списка — ничего не программируете. Пользователь жмёт
Ctrl+Fили начинает печатать в списке, платформа ищет по видимым колонкам. Подходит в 90% случаев. - 🧩 Свой реквизит + отбор — отдельное поле ввода над таблицей, фильтрует динамический список по нужным полям (наименование, артикул, ИНН). Нужно, когда поиск должен работать по не видимым в таблице реквизитам.
- 📑 Запрос или СКД — когда данные собираются из нескольких таблиц или с расчётами, и список формируется не напрямую из справочника.
- 🌐 Полнотекстовый поиск — поиск слова сразу по всем объектам базы (как у поисковика). Для «найти всё, где встречается этот артикул или фамилия».
Если конфигурация на поддержке, не снимайте её с замка ради одного поля — используйте расширение конфигурации (последний раздел).
Дальше — по порядку, от самого простого к коду.
Встроенный поиск динамического списка
Любая таблица формы, построенная на динамическом списке, уже умеет искать. Отдельное поле заводить не обязательно.
Пользователю доступны:
- Быстрый поиск — встать в таблицу и начать печатать. Платформа подсветит первую подходящую строку по текущей колонке.
- Поиск по
Ctrl+F— откроется строка поиска с выбором колонки и режима (с начала строки / любое вхождение). - Расширенный отбор — команда «Ещё» → «Настроить список» → вкладка «Отбор», где задают условия по любому реквизиту.
Чтобы быстрый поиск вообще работал, у динамического списка в свойствах формы должно стоять свойство ПоискПриВводе (включено по умолчанию). Проверить это стоит, если поиск «не печатается»: откройте форму в Конфигураторе, выделите таблицу и посмотрите свойство в палитре.
Если нужно, чтобы по умолчанию список искал по артикулу, а не по наименованию, — поменяйте порядок колонок или задайте колонку поиска в настройках динамического списка. Отдельный код для этого не нужен.
Этого хватает, пока не требуется своё поле ввода с особым поведением. Если требуется — переходим к реквизиту формы.
Реквизит формы для ввода запроса
Чтобы над таблицей появилось собственное поле поиска, заводят реквизит формы и кладут его на форму.
Порядок в Конфигураторе:
- Откройте нужную форму (например, форму списка справочника
Номенклатура). - Вкладка «Реквизиты» формы → кнопка «Добавить». Назовите реквизит, например
ТекстПоиска, тип —Строка(длина 0 — неограниченная или, скажем, 150). - Перетащите реквизит из «Реквизитов» в дерево «Элементы» — на форме появится поле ввода.
- В свойствах элемента задайте заголовок («Поиск»), а в поле
РежимРедактированияТекстапри желании —МногострочныйРежим = Ложь. - Чтобы поиск срабатывал на каждый символ, в свойствах поля включите
РежимИзменения→ «ПриИзменении» (а не «ПриЗавершении»), тогда событие будет вызываться по мере ввода.
Теперь поле есть, но оно ничего не делает. Логику добавим в следующем разделе — через отбор динамического списка.
Длинную строку поиска без ограничения лучше не делать: пользователь может вставить абзац текста, и это уйдёт в условие отбора. 100–150 символов достаточно.
Отбор динамического списка через код
Самый частый сценарий: ввёл текст — список отфильтровался по вхождению. Отбор динамического списка меняется на сервере, поэтому клиентский обработчик вызывает серверную процедуру.
Клиентская часть — обработчик события поля ТекстПоиска:
&НаКлиенте
Процедура ТекстПоискаПриИзменении(Элемент)
УстановитьОтборПоиска(ТекстПоиска);
КонецПроцедуры
Серверная часть — собирает условие отбора:
&НаСервере
Процедура УстановитьОтборПоиска(Текст)
Список.Отбор.Элементы.Очистить();
Если ПустаяСтрока(Текст) Тогда
Возврат;
КонецЕсли;
Элемент = Список.Отбор.Элементы.Добавить(
Тип("ЭлементОтбораКомпоновкиДанных"));
Элемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Наименование");
Элемент.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит;
Элемент.ПравоеЗначение = Текст;
Элемент.Использование = Истина;
КонецПроцедуры
Разберём ключевые моменты:
Список— имя реквизита формы с динамическим списком (у типовой формы списка он так и называется).ВидСравненияКомпоновкиДанных.Содержитищет любое вхождение подстроки. Для «начинается с» возьмитеНачинаетсяС, для точного совпадения —Равно.- Перед добавлением нового условия старое чистим через
Очистить(), иначе отборы будут накапливаться. - Пустой текст очищает отбор и возвращает полный список — без этого пользователь не сможет «сбросить» поиск.
Если нужно искать сразу по нескольким полям (наименование ИЛИ артикул), добавьте группу отбора с типом Или:
Группа = Список.Отбор.Элементы.Добавить(
Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
Группа.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;
Для Каждого ИмяПоля Из СтрРазделить("Наименование,Артикул", ",") Цикл
Условие = Группа.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Условие.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ИмяПоля);
Условие.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит;
Условие.ПравоеЗначение = Текст;
Условие.Использование = Истина;
КонецЦикла;
Этот подход хорош тем, что динамический список сам дочитывает данные порциями — вы не грузите весь справочник в память.
Поиск через запрос и СКД
Когда список формируется не напрямую из справочника, а запросом (например, остатки с ценами из нескольких регистров), поиск встраивают в сам запрос.
Простой вариант — параметр в условии ГДЕ:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка,
Номенклатура.Наименование КАК Наименование,
Номенклатура.Артикул КАК Артикул
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Наименование ПОДОБНО &Текст
Параметр подставляют со спецсимволами шаблона:
Запрос.УстановитьПараметр("Текст", "%" + ТекстПоиска + "%");
% в операторе ПОДОБНО означает «любое число любых символов». %слово% — вхождение в любом месте, слово% — в начале.
Если список выводится через систему компоновки данных (СКД) — например, в отчёте или в форме с полем табличного документа — текст поиска передают как параметр компоновки, а в схеме делают отбор:
&НаСервере
Процедура ПрименитьПоискСКД(Текст)
КомпоновщикНастроек = Отчёт.КомпоновщикНастроек;
ЭлементыОтбора = КомпоновщикНастроек.Настройки.Отбор.Элементы;
ЭлементыОтбора.Очистить();
Если НЕ ПустаяСтрока(Текст) Тогда
Отб = ЭлементыОтбора.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Отб.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Наименование");
Отб.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит;
Отб.ПравоеЗначение = Текст;
Отб.Использование = Истина;
КонецЕсли;
КонецПроцедуры
В СКД отбор по «Содержит» транслируется в тот же ПОДОБНО на уровне запроса к СУБД, поэтому правила те же, что и выше.
Не подставляйте текст поиска прямым склеиванием в текст запроса. Только через УстановитьПараметр или элемент отбора — это и безопаснее, и позволяет СУБД переиспользовать план запроса.
Клиент и сервер: как разнести код правильно
Управляемое приложение разделяет выполнение на клиент и сервер, и поиск — наглядный пример, где это важно.
Коротко, что где работает:
| Директива | Где выполняется | Что можно |
|---|---|---|
&НаКлиенте | на компьютере пользователя | ловить события поля, читать введённый текст |
&НаСервере | на сервере, с контекстом формы | менять Список.Отбор, выполнять запрос |
&НаСервереБезКонтекста | на сервере, без формы | тяжёлые выборки, где контекст формы не нужен |
Правила, которые экономят нервы:
- Отбор динамического списка (
Список.Отбор) меняют только на сервере — на клиенте этот объект недоступен для записи. - Запросы к базе выполняются на сервере. Клиент запрос выполнить не может в принципе.
- Чем меньше контекста формы вы тащите на сервер, тем быстрее вызов. Если процедуре поиска нужен только текст — выносите её в
&НаСервереБезКонтекстаи передавайте текст параметром, возвращая готовый результат.
Типичная ошибка новичка — попытка поменять отбор прямо в клиентском обработчике. Платформа выдаст ошибку компиляции: нужный объект на клиенте «не виден». Решение всегда одно — серверная процедура, как в примерах выше.
Полнотекстовый поиск по всей базе
Когда ищут не по одному справочнику, а «везде, где встречается это слово» (в наименованиях, комментариях, реквизитах документов), подключают полнотекстовый поиск платформы.
Чтобы он работал, индекс должен быть включён и построен. Обновление индекса обычно ставят в регламентное задание:
ПолнотекстовыйПоиск.ОбновитьИндекс(Ложь);
Сам поиск из кода:
СписокПоиска = ПолнотекстовыйПоиск.СоздатьСписок(ТекстПоиска, 20);
СписокПоиска.ПервыйЧасть();
Для Каждого Элемент Из СписокПоиска Цикл
Сообщить(Элемент.Значение);
КонецЦикла;
- Второй параметр
СоздатьСписок— размер порции результатов. - Полнотекстовый поиск понимает морфологию: по запросу «договор» найдёт и «договора», и «договору». Это его главное отличие от
ПОДОБНО. - Индекс не обновляется мгновенно: только что созданный документ попадёт в поиск после ближайшего
ОбновитьИндекс.
Полнотекстовый поиск — отдельный механизм, он не заменяет отбор списка, а дополняет его для глобального поиска по базе.
Чем способы отличаются на практике
Сводная таблица — чтобы выбрать под свою задачу:
| Способ | Код нужен | По каким полям | Нагрузка | Когда брать |
|---|---|---|---|---|
| Встроенный поиск списка | нет | видимые колонки | минимальная | большинство форм списка |
| Реквизит + отбор | ~15 строк | любые поля объекта | низкая | своё поле над таблицей |
| Запрос / СКД | средне | любые, в т.ч. из регистров | зависит от запроса | сложные списки и отчёты |
| Полнотекстовый поиск | ~10 строк | вся база, с морфологией | индекс + его обновление | глобальный поиск по слову |
Общее правило: не усложняйте. Если хватает встроенного поиска — не пишите код. Отдельный реквизит оправдан, когда нужно искать по невидимым полям или по нескольким сразу.
Производительность: почему поиск тормозит
На справочнике в сотни тысяч строк неудачный поиск «думает» секундами. Чаще всего виноват один из пунктов ниже.
ПОДОБНО '%текст%' не может использовать индекс СУБД — она читает все строки. Для частых поисков по началу строки используйте НачинаетсяС ('текст%'): такое условие индекс поддерживает. Для поиска по вхождению в большой базе — полнотекстовый поиск вместо Содержит.ПриИзменении шлёт запрос на сервер на каждую букву. На медленном канале это заметно. Включите у поля задержку ввода или переведите обработку на ПриЗавершении, чтобы отбор срабатывал после паузы, а не на каждый символ.ПолнотекстовыйПоиск.ОбновитьИндекс.Список.Отбор.Элементы перед добавлением нового условия. Добавьте Очистить() в начале.Ещё две вещи, которые помогают держать поиск быстрым:
- 🏎️ Индексируйте поля поиска. Для реквизита справочника в Конфигураторе есть свойство «Индексировать». Для частого поиска по артикулу — включите его.
- 📦 Не грузите всё в память. Динамический список читает данные порциями сам. Не заменяйте его на загрузку всего справочника в таблицу значений ради поиска — это и есть причина «зависаний» на больших базах.
Поле поиска через расширение конфигурации
Если основная конфигурация на поддержке и снимать её с замка нельзя, поле поиска добавляют расширением — не трогая типовую форму.
Порядок действий:
- В Конфигураторе: меню «Конфигурация» → «Расширения конфигурации », создайте расширение (назначение — «Адаптация»).
- В расширение добавьте нужную форму — платформа предложит заимствовать её из основной конфигурации.
- В заимствованной форме добавьте свой реквизит
ТекстПоискаи элемент поля, как описано выше. - Обработчик события и серверную процедуру напишите в модуле формы расширения.
При обновлении типовой конфигурации расширение, как правило, продолжает работать — вы не меняли саму форму, а дополнили её. Это штатный способ дорабатывать типовые решения без снятия с поддержки.
Если типовая форма сильно изменится в новом релизе, заимствованная форма в расширении может потребовать правки. После крупных обновлений проверяйте, что поле поиска на месте и работает.
Частые вопросы
Почему мой обработчик поиска не вызывается при вводе?
Можно ли сделать поиск без программирования вообще?
Ctrl+F и быстрый поиск при вводе) работает без единой строки кода. Код нужен только для своего поля над таблицей или для нестандартной логики.Как искать сразу по наименованию и по коду?
Регистр букв важен при поиске?
ПОДОБНО и «Содержит» регистр обычно не учитывается — зависит от настроек сравнения базы данных. Полнотекстовый поиск регистр не различает в принципе.