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