Как реализовать отбор при вводе по строке в обычных формах 1С 8.2

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При работе со старыми конфигурациями на базе обычных форм (например, УТ 10.3, УПП 1.3 или КА 1.1) программисты часто сталкиваются с необходимостью ограничить выбор данных при вводе текста в поле. Типичный пример — исключение «архивной» номенклатуры или закрытых контрагентов из выпадающего списка поиска. В отличие от управляемых форм, где существует мощный механизм ОбработкаПолученияДанныхВыбора, в обычных формах реализация такого функционала требует понимания работы низкоуровневых событий элементов управления.

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

Ограничения стандартного механизма ввода по строке

Прежде всего, проанализируем, как работает стандартный поиск в 1С 8.2 для обычных форм. Когда пользователь начинает вводить символы в поле выбора, платформа автоматически пытается найти соответствие в справочнике по полям, указанным в свойстве «Ввод по строке» (обычно это Наименование и Код). Этот процесс происходит на уровне ядра системы, и напрямую «подсунуть» туда произвольный фильтр (например, ГДЕ Архив = Ложь) через свойства метаданных невозможно.

Рассмотрим два основных пути решения задачи: локальный (для конкретного поля в конкретной форме) и глобальный (изменение логики поиска для всей конфигурации).

Способ 1. Использование события «ОкончаниеВводаТекста»

Наиболее гибкий способ управления процессом — перехват события ОкончаниеВводаТекста у элемента управления ПолеВвода. Это событие возникает в тот момент, когда пользователь закончил ввод (нажал Enter или переключился на другое поле), но платформа еще не начала стандартную процедуру поиска.

Проанализируем алгоритм действий в обработчике:

  1. Устанавливаем параметр СтандартнаяОбработка в значение Ложь, чтобы отключить системный поиск.
  2. Выполняем собственный запрос к базе данных с учетом необходимых фильтров.
  3. Формируем список найденных значений и передаем его обратно в элемент управления.

Рассмотрим пример кода, который ограничивает поиск только теми элементами, которые содержат определенную строку и не помечены как архивные:


Процедура НоменклатураОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
    
    // Отключаем встроенный поиск платформы
    СтандартнаяОбработка = Ложь;
    
    // Если текста нет, ничего не делаем
    Если ПустаяСтрока(Текст) Тогда
        Возврат;
    КонецЕсли;

    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Ссылка КАК Ссылка
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |	Номенклатура.Наименование ПОДОБНО &ТекстПоиска
    |	И Номенклатура.Архив = ЛОЖЬ"; // Наш кастомный отбор

    // Используем спецсимвол % для поиска подстроки
    Запрос.УстановитьПараметр("ТекстПоиска", "%" + Текст + "%");

    РезультатЗапроса = Запрос.Выполнить();
    
    Если РезультатЗапроса.Пустой() Тогда
        // Если ничего не нашли, сообщаем пользователю
        Значение = Неопределено;
    Иначе
        Выгрузка = РезультатЗапроса.Выгрузить();
        МассивСсылок = Выгрузка.ВыгрузитьКолонку("Ссылка");
        
        // Формируем список значений для выбора
        СписокВыбора = Новый СписокЗначений;
        СписокВыбора.ЗагрузитьЗначения(МассивСсылок);
        
        // Передаем результат в параметр "Значение"
        Значение = СписокВыбора;
    КонецЕсли;

КонецПроцедуры

В данном примере мы используем объект Запрос, что позволяет нам накладывать любые условия, включая условия по дополнительным реквизитам или правам доступа. Важный момент: если запрос возвращает более одного элемента, платформа автоматически откроет небольшое выпадающее меню со списком найденных позиций. При необходимости искать позицию по данным контрагента пригодится инструмент для поиска номенклатуры по наименованию и коду поставщика.

Способ 2. Интеграция с типовым механизмом УТ 10.3

В типовых конфигурациях, таких как «Управление торговлей 10.3», разработчики фирмы «1С» уже создали централизованный механизм для поиска по строке. Он реализован в общем модуле ПроцедурыПоискаПоСтроке. Использование этого модуля позволяет сократить объем кода в формах и сохранить единообразие интерфейса.

Выясним, как использовать процедуру ОкончаниеВводаТекстаВЭлементеУправления. Она принимает структуру отбора в качестве одного из параметров. Посмотрим на практическую реализацию в форме документа:


Процедура НоменклатураОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
    
    // Создаем структуру отбора, где ключи — имена реквизитов справочника
    СтруктураОтбора = Новый Структура;
    СтруктураОтбора.Вставить("Архив", Ложь);
    СтруктураОтбора.Вставить("Услуга", Истина); // Дополнительный пример фильтра
    
    // Вызываем типовую функцию
    ПроцедурыПоискаПоСтроке.ОкончаниеВводаТекстаВЭлементеУправления(
        Элемент, 
        Текст, 
        Значение, 
        СтандартнаяОбработка, 
        СтруктураОтбора, 
        ЭтаФорма
    );

КонецПроцедуры

Этот подход гораздо удобнее, так как типовой модуль сам сформирует нужный запрос, обработает пустые результаты и обеспечит стандартное поведение формы выбора. Однако помните, что СтруктураОтбора в типовом механизме обычно работает по принципу равенства (Реквизит = Значение). Если вам нужен сложный отбор (например, вхождение в список), придется модифицировать сам общий модуль. При необходимости расширить возможности фильтрации в УТ 10.3 и КА 1.1 можно использовать обработку для отбора номенклатуры по нескольким вхождениям слов.

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

Проанализируем ситуацию: в справочнике Номенклатура может быть 100 000 и более записей. Если мы добавляем в запрос условие ГДЕ Архив = Ложь, и при этом реквизит Архив не проиндексирован, система будет вынуждена сканировать всю таблицу при каждом вводе символа. Это приведет к значительным задержкам.

Чтобы избежать тормозов, выполните следующие действия в Конфигураторе:

  1. Найдите нужный справочник и перейдите на вкладку «Данные».
  2. Выберите реквизит, по которому планируется отбор (например, Архив).
  3. В свойстве «Индексировать» установите значение Индексировать или Индексировать с доп. упорядочиванием.

Важно: Индексация булевых полей эффективна только в том случае, если одно из значений встречается значительно реже другого (например, архивных товаров 5%, а рабочих 95%).

Очистка истории выбора

Даже после настройки всех фильтров вы можете заметить, что «архивные» элементы все равно появляются в подсказках. Это происходит из-за механизма Истории выбора. Платформа запоминает, что пользователь ранее выбирал этот элемент, и предлагает его снова, игнорируя программные фильтры в коде.

В обычных формах для борьбы с этим эффектом можно использовать метод ОчиститьИсториюВыбора() у объекта ПолеВвода, либо полностью отключить историю выбора в свойствах элемента управления (свойство АвтоВыборИзТекста или настройки пользователя).

Резюме

Подведем итоги. Для реализации качественного отбора при вводе по строке в 1С 8.2 (Обычные формы) необходимо:

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

← На главную