При работе со старыми конфигурациями на базе обычных форм (например, УТ 10.3, УПП 1.3 или КА 1.1) программисты часто сталкиваются с необходимостью ограничить выбор данных при вводе текста в поле. Типичный пример — исключение «архивной» номенклатуры или закрытых контрагентов из выпадающего списка поиска. В отличие от управляемых форм, где существует мощный механизм ОбработкаПолученияДанныхВыбора, в обычных формах реализация такого функционала требует понимания работы низкоуровневых событий элементов управления.
В этой статье мы подробно разберем, как программно внедрить фильтрацию в механизм ввода по строке, проанализируем стандартные возможности платформы и рассмотрим способы оптимизации запросов для больших справочников.
Прежде всего, проанализируем, как работает стандартный поиск в 1С 8.2 для обычных форм. Когда пользователь начинает вводить символы в поле выбора, платформа автоматически пытается найти соответствие в справочнике по полям, указанным в свойстве «Ввод по строке» (обычно это Наименование и Код). Этот процесс происходит на уровне ядра системы, и напрямую «подсунуть» туда произвольный фильтр (например, ГДЕ Архив = Ложь) через свойства метаданных невозможно.
Рассмотрим два основных пути решения задачи: локальный (для конкретного поля в конкретной форме) и глобальный (изменение логики поиска для всей конфигурации).
Наиболее гибкий способ управления процессом — перехват события ОкончаниеВводаТекста у элемента управления ПолеВвода. Это событие возникает в тот момент, когда пользователь закончил ввод (нажал Enter или переключился на другое поле), но платформа еще не начала стандартную процедуру поиска.
Проанализируем алгоритм действий в обработчике:
СтандартнаяОбработка в значение Ложь, чтобы отключить системный поиск.Рассмотрим пример кода, который ограничивает поиск только теми элементами, которые содержат определенную строку и не помечены как архивные:
Процедура НоменклатураОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
// Отключаем встроенный поиск платформы
СтандартнаяОбработка = Ложь;
// Если текста нет, ничего не делаем
Если ПустаяСтрока(Текст) Тогда
Возврат;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Наименование ПОДОБНО &ТекстПоиска
| И Номенклатура.Архив = ЛОЖЬ"; // Наш кастомный отбор
// Используем спецсимвол % для поиска подстроки
Запрос.УстановитьПараметр("ТекстПоиска", "%" + Текст + "%");
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
// Если ничего не нашли, сообщаем пользователю
Значение = Неопределено;
Иначе
Выгрузка = РезультатЗапроса.Выгрузить();
МассивСсылок = Выгрузка.ВыгрузитьКолонку("Ссылка");
// Формируем список значений для выбора
СписокВыбора = Новый СписокЗначений;
СписокВыбора.ЗагрузитьЗначения(МассивСсылок);
// Передаем результат в параметр "Значение"
Значение = СписокВыбора;
КонецЕсли;
КонецПроцедуры
В данном примере мы используем объект Запрос, что позволяет нам накладывать любые условия, включая условия по дополнительным реквизитам или правам доступа. Важный момент: если запрос возвращает более одного элемента, платформа автоматически откроет небольшое выпадающее меню со списком найденных позиций. При необходимости искать позицию по данным контрагента пригодится инструмент для поиска номенклатуры по наименованию и коду поставщика.
В типовых конфигурациях, таких как «Управление торговлей 10.3», разработчики фирмы «1С» уже создали централизованный механизм для поиска по строке. Он реализован в общем модуле ПроцедурыПоискаПоСтроке. Использование этого модуля позволяет сократить объем кода в формах и сохранить единообразие интерфейса.
Выясним, как использовать процедуру ОкончаниеВводаТекстаВЭлементеУправления. Она принимает структуру отбора в качестве одного из параметров. Посмотрим на практическую реализацию в форме документа:
Процедура НоменклатураОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
// Создаем структуру отбора, где ключи — имена реквизитов справочника
СтруктураОтбора = Новый Структура;
СтруктураОтбора.Вставить("Архив", Ложь);
СтруктураОтбора.Вставить("Услуга", Истина); // Дополнительный пример фильтра
// Вызываем типовую функцию
ПроцедурыПоискаПоСтроке.ОкончаниеВводаТекстаВЭлементеУправления(
Элемент,
Текст,
Значение,
СтандартнаяОбработка,
СтруктураОтбора,
ЭтаФорма
);
КонецПроцедуры
Этот подход гораздо удобнее, так как типовой модуль сам сформирует нужный запрос, обработает пустые результаты и обеспечит стандартное поведение формы выбора. Однако помните, что СтруктураОтбора в типовом механизме обычно работает по принципу равенства (Реквизит = Значение). Если вам нужен сложный отбор (например, вхождение в список), придется модифицировать сам общий модуль. При необходимости расширить возможности фильтрации в УТ 10.3 и КА 1.1 можно использовать обработку для отбора номенклатуры по нескольким вхождениям слов.
Проанализируем ситуацию: в справочнике Номенклатура может быть 100 000 и более записей. Если мы добавляем в запрос условие ГДЕ Архив = Ложь, и при этом реквизит Архив не проиндексирован, система будет вынуждена сканировать всю таблицу при каждом вводе символа. Это приведет к значительным задержкам.
Чтобы избежать тормозов, выполните следующие действия в Конфигураторе:
Архив).Индексировать или Индексировать с доп. упорядочиванием.Важно: Индексация булевых полей эффективна только в том случае, если одно из значений встречается значительно реже другого (например, архивных товаров 5%, а рабочих 95%).
Даже после настройки всех фильтров вы можете заметить, что «архивные» элементы все равно появляются в подсказках. Это происходит из-за механизма Истории выбора. Платформа запоминает, что пользователь ранее выбирал этот элемент, и предлагает его снова, игнорируя программные фильтры в коде.
В обычных формах для борьбы с этим эффектом можно использовать метод ОчиститьИсториюВыбора() у объекта ПолеВвода, либо полностью отключить историю выбора в свойствах элемента управления (свойство АвтоВыборИзТекста или настройки пользователя).
Подведем итоги. Для реализации качественного отбора при вводе по строке в 1С 8.2 (Обычные формы) необходимо:
ОкончаниеВводаТекста для управления процессом подбора.СтандартнаяОбработка = Ложь для подмены системного поиска своим кодом.ПроцедурыПоискаПоСтроке для минимизации кода.Рассмотренные методы позволяют сделать работу пользователя более комфортной, исключая ошибки выбора неактуальных данных и ускоряя процесс заполнения документов.