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