Как в СКД сгруппировать данные по строке, собранной из табличной части, без написания кода

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

В процессе разработки отчетов на системе компоновки данных (СКД) часто возникает задача: вывести данные табличной части документа не отдельными строками, а одной общей строкой в основной записи. Например, если у нас есть документ «Заказ», в котором в табличной части «Специалисты» указано несколько сотрудников, мы хотим видеть в отчете одну строку по заказу, где в одной колонке через запятую перечислены все специалисты. Более того, часто требуется не просто вывести эту строку, но и использовать её в качестве группировки. Рассмотрим, как решить эту задачу, используя только штатные механизмы СКД, избегая написания программного кода.

Проблема использования ресурсов для группировки

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

Метод 1: Использование функции СоединитьСтроки в вычисляемых полях

Начиная с современных версий платформы 8.3.15 и выше, возможности функции СоединитьСтроки были расширены. Теперь её можно использовать не только в ресурсах, но и в выражениях вычисляемых полей. Проанализируем, как это настроить.

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

Синтаксис функции выглядит следующим образом:

СоединитьСтроки(Таблица.Поле, "Разделитель", "ПорядокСортировки")

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

Метод 2: Связи наборов данных (самый надежный способ)

Рассмотрим пошагово алгоритм, который позволяет получить строку из табличной части и сделать её доступной для группировки без единой строчки кода в модулях.

Шаг 1: Создание наборов данных

В схеме компоновки данных создадим два набора данных — оба типа «Запрос»:

  1. НаборДанных1 (Основной): Здесь мы выбираем основные данные документов, например: Ссылка, Номер, Дата, Сумма.
  2. НаборДанных2 (Специалисты): Здесь мы выбираем данные из табличной части: Ссылка (внешний ключ для связи) и Сотрудник.Наименование (само значение).

Шаг 2: Настройка связей

Переходим на вкладку «Связи наборов данных». Это ключевой этап. Мы связываем НаборДанных1 (источник) с НаборДанных2 (приемник) по полю Ссылка.

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

Чтобы получить объединенную строку, в современных версиях платформы мы можем создать в НаборДанных1 вычисляемое поле, выражение которого будет собирать данные из связанного НаборДанных2. Выясним причину, по которой это работает: СКД выполняет соединение наборов и позволяет агрегировать данные подчиненного набора для каждой записи родительского.

Шаг 3: Вычисляемое поле для группировки

На вкладке «Вычисляемые поля» создаем поле ГруппировкаСпециалисты. В выражении используем:


СоединитьСтроки(ВычислитьВыражениеСГруппировкойТаблица("Сотрудник", "Ссылка"), ", ")

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

Метод 3: Использование вложенных схем

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

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

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

Особенности и ограничения

Рассмотрим важные нюансы, которые могут встретиться в работе:

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

Пример правильного выражения с сортировкой:

СоединитьСтроки(Специалисты.Сотрудник, "; ", "Сотрудник Возр")

Заключение

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

← На главную