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