Как вывести несколько штрихкодов одной позиции в одну строку в документе 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При доработке форм документов, таких как ОтборРазмещениеТоваров в 1С:Управление торговлей 11.4, часто возникает потребность вывести дополнительную информацию, например, штрихкоды номенклатуры. Однако при попытке просто добавить РегистрСведений.ШтрихкодыНоменклатуры в запрос через левое соединение, мы сталкиваемся с проблемой дублирования строк.

Это происходит из-за того, что связь между номенклатурой и ее штрихкодами имеет тип «один-ко-многим». Если у товара три штрихкода, в результирующей выборке одна строка документа превратится в три, что ломает структуру табличной части. Давайте разберем, как грамотно обойти это ограничение и получить желаемый результат.

Вариант 1: Использование Системы Компоновки Данных (СКД)

Самый правильный и современный способ решить задачу — перевести вывод данных на Систему Компоновки Данных. СКД обладает встроенными инструментами для агрегации данных, которые позволяют «склеить» значения без изменения базового запроса до неузнаваемости.

  1. Создание вычисляемого поля: В настройках СКД добавьте вычисляемое поле, например, ШтрихкодыСтрокой.
  2. Использование функции СоединитьСтроки: Используйте стандартную функцию СоединитьСтроки. Она позволяет объединить значения из группировки по номенклатуре в одну строку через нужный разделитель (например, запятую или перенос строки).
  3. Группировка: В настройках отчета установите группировку по номенклатуре. В детальных записях система автоматически соберет все найденные штрихкоды в одну ячейку.

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

Вариант 2: Программная обработка результата запроса (Оптимальный подход)

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

Разберем алгоритм по шагам:

  1. Основной запрос: Выполните запрос для получения данных документа, но без присоединения таблицы штрихкодов.
  2. Сбор номенклатуры: Соберите все уникальные ссылки на номенклатуру из результата запроса в массив или список значений.
  3. Выборка штрихкодов: Выполните отдельный запрос к РегиструСведений.ШтрихкодыНоменклатуры, передав собранный массив номенклатуры в условие ГДЕ Номенклатура В (&МассивНоменклатуры).
  4. Формирование соответствия: При обходе результата второго запроса сформируйте объект Соответствие, где ключом будет номенклатура, а значением — строка со штрихкодами.

Посмотрим на пример логики формирования строки:


// Пример логики в коде модуля
Если СоответствиеШтрихкодов.Свойство(СтрокаДокумента.Номенклатура, Штрихкоды) Тогда
    СтрокаДокумента.Код = СтрСоединить(Штрихкоды, ", ");
КонецЕсли;

Почему не стоит пытаться «склеить» всё в одном запросе?

Язык запросов 1С не поддерживает агрегатную функцию типа STRING_AGG, привычную для SQL. Попытки сделать это через вложенные запросы или сложные ОБЪЕДИНИТЬ приведут к получению огромных временных таблиц, которые будут потреблять много оперативной памяти сервера.

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

Подведем итоги:

Чтобы вывести штрихкоды в одну клетку и не задвоить строки:

Используя эти рекомендации, вы не только решите поставленную бизнес-задачу, но и сохраните высокую скорость работы системы, избежав проблем с производительностью в будущем.

← На главную