Как в СКД объединить значения из нескольких строк в одну с помощью СоединитьСтроки()?

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

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

Проблема обычно выглядит так: у нас есть исходные данные:


Номенклатура      Цвет
------------------------
Товар1            Желтый
Товар1            Синий
Товар2            Красный

А получить мы хотим следующий результат:


Номенклатура      Цвет
--------------------------------
Товар1            Желтый, Синий
Товар2            Красный

Интуитивно разработчик добавляет на вкладку "Ресурсы" выражение СоединитьСтроки(Цвет, ", "), но вместо ожидаемого результата получает исходную таблицу, а в общем итоге по отчету видит строку "Желтый, Синий, Красный". Выясним, почему так происходит и как это исправить.

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

Решение 1: Правильная настройка группировки и ресурса (самый простой способ)

Этот метод является наиболее корректным и простым для решения нашей задачи. Он не требует написания сложного кода и полностью выполняется в конструкторе настроек СКД.

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

  1. Создайте группировку. На вкладке "Настройки" в дереве отчета создайте группировку по полю, которое должно быть уникальным в итоговых строках. В нашем случае это Номенклатура. Если вам не нужны детальные записи (каждый цвет на отдельной строке), можно удалить или отключить вложенную группировку "Детальные записи".
  2. Настройте вычисляемое поле (ресурс). Перейдите на вкладку "Ресурсы". Создайте новое поле. В колонке "Выражение" напишите нашу функцию: СоединитьСтроки(Цвет, ", "). Можете задать для него псевдоним, например, "ВсеЦвета".
  3. Укажите контекст расчета. Это самый важный шаг. В той же строке ресурса найдите колонку "Рассчитывать по...". По умолчанию она пустая, что означает расчет по общему итогу. Нажмите на кнопку выбора (...) в этой ячейке и выберите из списка группировку, которую вы создали на первом шаге, — "Номенклатура".

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

Решение 2: Использование агрегатной функции Массив()

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

Выражение в ресурсе будет выглядеть так:

СоединитьСтроки(Массив(Цвет), ", ")

Как и в первом решении, критически важно указать в колонке "Рассчитывать по..." нужную группировку ("Номенклатура"). Этот подход делает логику вычислений более явной: сначала собираем массив, потом соединяем его элементы в строку.

Дополнительная возможность: если в ваших данных могут быть дубликаты (например, "Товар1 - Желтый", "Товар1 - Желтый"), и их нужно выводить только один раз, используйте ключевое слово РАЗЛИЧНЫЕ внутри функции Массив(). Это позволит собрать только уникальные значения.

СоединитьСтроки(Массив(РАЗЛИЧНЫЕ Цвет), ", ")

Решение 3: Использование функций "ВычислитьВыражениеСГруппировкой..." (сложный метод)

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

Тем не менее, полезно знать, как они работают. Например, можно создать вычисляемое поле с таким выражением:


СоединитьСтроки(ВычислитьВыражениеСГруппировкойМассив("Цвет", "Номенклатура"), ", ")

Здесь мы явно указываем, что нужно собрать массив значений поля "Цвет" в контексте группировки "Номенклатура". Этот метод может быть полезен, когда нужно вывести объединенную строку не в самой группировке, а, например, в общем итоге или в другой части отчета. Для нашей задачи первые два способа гораздо проще и эффективнее.

Решение 4: Предварительная обработка данных в запросе

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

  1. Первый запрос пакета: данные группируются, а нужные значения собираются в какую-либо структуру (например, в строку, если СУБД это позволяет, или во временную таблицу).
  2. Второй запрос пакета: выбирает уже обработанные данные из временной таблицы и передает их в СКД как готовый набор данных.

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

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

← На главную