Как реализовать выбор элемента справочника по коду в табличной части документа?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Вариант 1. Использование штатного механизма «Ввод по строке» (рекомендуемый способ)

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

Рассмотрим по шагам настройку в конфигураторе:

  1. Настройка индексирования реквизита. Перейдем в свойства нужного справочника и найдем дополнительный реквизит (например, КодОтчета или Артикул). В палитре свойств реквизита установим свойство Индексировать в значение Индексировать или Индексировать с доп. упорядочиванием. Индексация является обязательным условием для использования поля во вводе по строке. Обратите внимание, что реквизит должен иметь тип Строка или Число фиксированной длины (неограниченная длина и составные типы не поддерживаются).
  2. Включение реквизита во «Ввод по строке». Откроем свойства самого справочника и перейдем к свойству Ввод по строке. Добавим наш индексированный реквизит в список полей ввода по строке наряду со стандартными полями Код и Наименование.
  3. Проверка свойств поля ввода на форме. На форме документа в табличной части убедимся, что у элемента формы (колонки со ссылкой на справочник) включены свойства АвтовыборНезаполненного и БыстрыйВыбор при необходимости.

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

Вариант 2. Тонкая настройка поиска через событие «ОбработкаПолученияДанныхВыбора»

Если стандартного сопоставления по строке недостаточно (например, требуется удалять лидирующие нули, отсекать пробелы, искать с учетом специфических фильтров или владельца), переопределим логику поиска на стороне сервера.

Для этого в модуле менеджера справочника используем экспортный обработчик ОбработкаПолученияДанныхВыбора:


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

Вариант 3. Реализация через отдельную колонку ввода кода

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

Разберем алгоритм создания такой механики:

  1. Добавим в реквизиты формы (в коллекцию колонок табличной части на форме) строковое поле КодВвода. Добавлять его в сам документ в метаданных не обязательно, чтобы не дублировать информацию в базе данных.
  2. Для созданного элемента формы определим событие ПриИзменении.
  3. В обработчике события выполним поиск элемента по введенной строке и заполним основную колонку документа.

Посмотрим на пример реализации кода на форме документа:


&НаКлиенте
Процедура ТоварыКодВводаПриИзменении(Элемент)
    
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    Если ПустаяСтрока(ТекущиеДанные.КодВвода) Тогда
        ТекущиеДанные.Номенклатура = ПредопределенноеЗначение("Справочник.Номенклатура.ПустаяСсылка");
        Возврат;
    КонецЕсли;
    
    НайденнаяСсылка = НайтиЭлементПоКодуНаСервере(ТекущиеДанные.КодВвода);
    
    Если ЗначениеЗаполнено(НайденнаяСсылка) Тогда
        ТекущиеДанные.Номенклатура = НайденнаяСсылка;
    Иначе
        ТекущиеДанные.Номенклатура = ПредопределенноеЗначение("Справочник.Номенклатура.ПустаяСсылка");
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Элемент с кодом """ + ТекущиеДанные.КодВвода + """ не найден!";
        Сообщение.Поле = "Товары[" + Элементы.Товары.ТекущаяСтрока + "].КодВвода";
        Сообщение.Сообщить();
    КонецЕсли;
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция НайтиЭлементПоКодуНаСервере(Знач КодПоиска)
    
    // Очищаем строку от лишних символов
    КодПоиска = СокрЛП(КодПоиска);
    
    // Использование запроса предпочтительнее НайтиПоРеквизиту для контроля дублей
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |	Номенклатура.Ссылка КАК Ссылка
        |ИЗ
        |	Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |	Номенклатура.КодОтчета = &КодОтчета
        |	И НЕ Номенклатура.ПометкаУдаления";
        
    Запрос.УстановитьПараметр("КодОтчета", КодПоиска);
    РезультатЗапроса = Запрос.Выполнить();
    
    Если НЕ РезультатЗапроса.Пустой() Тогда
        Выборка = РезультатЗапроса.Выбрать();
        Выборка.Следующий();
        Возврат Выборка.Ссылка;
    КонецЕсли;
    
    Возврат Справочники.Номенклатура.ПустаяСсылка();
    
КонецФункции

Важные нюансы и подводные камни

Проанализируем технические особенности, которые необходимо учитывать при разработке:

  1. Лидирующие нули. Если пользовательский код хранится в виде строки с лидирующими нулями (например, 0000452), а оператор вводит 452, прямое сравнение вернет отрицательный результат. Перед поиском следует форматировать входящее значение строковыми функциями или функцией Формат.
  2. Дублирование значений. Если реквизит поиска не является уникальным в пределах справочника, запрос или метод НайтиПоРеквизиту вернет произвольную первую ссылку. В таких сценариях рекомендуется открывать форму выбора с установленным отбором по введенному значению.
  3. Двусторонняя синхронизация. При использовании отдельной колонки формы обязательно предусмотрите обратное заполнение кода при выборе номенклатуры вручную через форму выбора или при чтении уже сохраненного документа на сервере в процедуре ПриЧтенииНаСервере.
← На главную