В процессе автоматизации складского учета часто возникает потребность видеть наличие зарегистрированных штрихкодов непосредственно в форме документа поступления (в 1С:УТ 11 это документ Приобретение товаров и услуг). Это позволяет сотруднику склада или менеджеру оперативно выявлять позиции, для которых штрихкод еще не заведен, и своевременно распечатывать этикетки. Рассмотрим, как реализовать этот функционал программно, используя современные механизмы платформы 1С:Предприятие 8.3.
В конфигурации «Управление торговлей», редакция 11, штрихкоды хранятся в независимом регистре сведений РегистрСведений.ШтрихкодыНоменклатуры. Особенность структуры в том, что на одну единицу номенклатуры может быть назначено несколько штрихкодов (например, для разных упаковок или разных производителей). Наша задача — вывести хотя бы один основной штрихкод в строку табличной части Товары, чтобы визуально подтвердить его наличие в базе.
Важное замечание по архитектуре: мы не будем изменять структуру метаданных основного документа в типовой конфигурации. Вместо этого мы воспользуемся механизмом расширений, добавив «виртуальный» реквизит в форму документа.
Для начала создадим расширение и добавим в него форму документа Приобретение товаров и услуг. Выполним следующие действия:
Объект и его табличную часть Товары.Штрихкод и типом Строка.Товары.Поскольку штрихкод не хранится в самом документе, нам необходимо динамически считывать его из регистра при открытии формы. Разберем наиболее эффективный метод заполнения через один запрос к базе данных, чтобы избежать замедления работы системы при большом количестве строк.
Проанализируем следующий программный код, который следует разместить в модуле формы (в обработчике ПриСозданииНаСервере):
&НаСервере
Процедура ФЛ_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Подготовим запрос для получения штрихкодов по всем товарам документа
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Товары.НомерСтроки КАК НомерСтроки,
| МАКСИМУМ(Штрихкоды.Штрихкод) КАК Штрихкод
|ИЗ
| Документ.ПриобретениеТоваровУслуг.Товары КАК Товары
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ШтрихкодыНоменклатуры КАК Штрихкоды
| ПО Товары.Номенклатура = Штрихкоды.Номенклатура
| И Товары.Характеристика = Штрихкоды.Характеристика
| И Товары.Упаковка = Штрихкоды.Упаковка
|ГДЕ
| Товары.Ссылка = &Ссылка
|ГРУППИРОВАТЬ ПО
| Товары.НомерСтроки";
Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
// Заполняем созданную нами колонку в таблице формы
Для каждого СтрокаТЧ Из Объект.Товары Цикл
ПараметрыПоиска = Новый Структура("НомерСтроки", СтрокаТЧ.НомерСтроки);
НайденныеСтроки = РезультатЗапроса.НайтиСтроки(ПараметрыПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
СтрокаТЧ.Штрихкод = НайденныеСтроки[0].Штрихкод;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
В данном примере мы используем ЛЕВОЕ СОЕДИНЕНИЕ, чтобы получить данные даже для тех товаров, у которых штрихкод отсутствует. Использование функции МАКСИМУМ позволяет нам корректно свернуть результат, если на одну позицию (номенклатура + характеристика + упаковка) заведено несколько кодов.
Выясним, как поддерживать актуальность данных при редактировании документа. Если пользователь добавит новый товар или изменит текущий, колонка штрихкода должна обновиться. Для этого нам нужно создать обработчик события ПриИзменении для колонки Номенклатура.
Рассмотрим пример кода для обновления штрихкода в реальном времени:
&НаСервере
Функция ПолучитьШтрихкодНаСервере(Номенклатура, Характеристика, Упаковка)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1 Штрихкод
|ИЗ РегистрСведений.ШтрихкодыНоменклатуры
|ГДЕ Номенклатура = &Номенклатура
|И Характеристика = &Характеристика
|И Упаковка = &Упаковка";
Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
Запрос.УстановитьПараметр("Характеристика", Характеристика);
Запрос.УстановитьПараметр("Упаковка", Упаковка);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.Штрихкод;
КонецЕсли;
Возврат "";
КонецФункции
&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)
ТекущаяСтрока = Элементы.Товары.ТекущиеДанные;
Если ТекущаяСтрока <> Неопределено Тогда
ТекущаяСтрока.Штрихкод = ПолучитьШтрихкодНаСервере(
ТекущаяСтрока.Номенклатура,
ТекущаяСтрока.Характеристика,
ТекущаяСтрока.Упаковка
);
КонецЕсли;
КонецПроцедуры
Проанализируем ситуацию, когда у товара зарегистрировано более одного штрихкода. Выводить их все через запятую в узкую ячейку таблицы неудобно для чтения. Рассмотрим альтернативные варианты:
УсловноеОформление формы таким образом, чтобы строки с пустым штрихкодом подсвечивались красным цветом. Это избавит пользователя от необходимости смотреть в отдельную колонку.ШтрихкодированиеНоменклатуры. Это обеспечит совместимость вашего кода с будущими обновлениями конфигурации от фирмы 1С.Если в вашем документе поступления количество строк исчисляется тысячами, заполнение колонки штрихкода при открытии может вызвать задержку в несколько секунд. Посмотрим, как этого избежать:
Таким образом, мы разобрали основные методы вывода штрихкодов в документ. Использование расширений и оптимизированных запросов позволяет решить задачу, сохраняя при этом высокую производительность и чистоту типовой конфигурации 1С.