Как объединить несколько штрихкодов номенклатуры в одну строку через запятую в 1С

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

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

Ограничения языка запросов 1С

Проанализируем работу самого языка запросов platform 1C. В нем отсутствуют функции вертикальной агрегации строк (аналоги SQL-функций STRING_AGG или GROUP_CONCAT). Стандартная агрегатная функция СУММА применяется только к числовым значениям, а оператор сложения строк + объединяет значения только по горизонтали — между колонками в рамках одной записи.

Сгруппировать строки с текстом непосредственно в самом SQL-запросе платформы 1С невозможно, поэтому задачу следует решать на этапе обработки результатов или с помощью средств компоновки данных.

Способ 1. Программный обход выборки и сцепка строк в BSL

Это наиболее распространенный и универсальный подход при формировании макетов печатных форм в модуле менеджера документа. Разберем его по шагам:

  1. В запросе организуем группировку или иерархию (итоги) по номенклатуре.
  2. При обходе группировок выбираем детальные записи со штрихкодами и помещаем их в Массив.
  3. Формируем итоговую строку с помощью платформенной функции СтрСоединить() или метода БСП СтроковыеФункцииКлиентСервер.СоединитьСтрокиВСписок().
  4. Передаем полученную строку в параметр области макета табличного документа.

Рассмотрим пример кода BSL:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Штрихкоды.Владелец КАК Номенклатура,
    |	Штрихкоды.Штрихкод КАК Штрихкод
    |ИЗ
    |	РегистрСведений.ШтрихкодыНоменклатуры КАК Штрихкоды
    |ИТОГИ ПО
    |	Номенклатура";

РезультатЗапроса = Запрос.Выполнить();
ВыборкаНоменклатура = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Пока ВыборкаНоменклатура.Следующий() Цикл
    
    МассивШтрихкодов = Новый Массив;
    ВыборкаДетали = ВыборкаНоменклатура.Выбрать();
    
    Пока ВыборкаДетали.Следующий() Цикл
        Если ЗначениеЗаполнено(ВыборкаДетали.Штрихкод) Тогда
            МассивШтрихкодов.Добавить(ВыборкаДетали.Штрихкод);
        КонецЕсли;
    КонецЦикла;
    
    // Объединяем элементы массива через запятую
    СтрокаШтрихкодов = СтрСоединить(МассивШтрихкодов, ", ");
    
    // Выводим данные в область макета
    // ОбластьМакета.Параметры.Штрихкод = СтрокаШтрихкодов;
    
КонецЦикла;

Способ 2. Использование Системы компоновки данных (СКД) из кода

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

Даже если у вас нет формы отчета и код выполняется в модуле менеджера, вы можете инициализировать схему компоновки данных программно. Посмотрим, как настроить ресурс в СКД:

  1. В схеме компоновки данных на вкладке Ресурсы добавляем поле Штрихкод.
  2. В поле Выражение указываем агрегатную функцию:

СоединитьСтроки(Массив(Различные Штрихкод), ", ")

При выполнении компоновки данных объекты ПроцессорКомпоновкиДанных и ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент автоматически сгруппируют штрихкоды по номенклатуре и выведут их через указанный разделитель в конечный ТабличныйДокумент.

Способ 3. Предварительная денормализация данных

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

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

← На главную