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