Как объединить строки табличной части в одну строку в отчете СКД?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Промышленность, строительство и АПК
← На главную

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

Причина проблемы: Почему обычное соединение не подходит

Рассмотрим ситуацию: у нас есть документ или запись регистра, связанная с «Бригадой», а у бригады есть табличная часть «Состав» с несколькими сотрудниками. Проанализируем типичную ошибку. Если мы используем ЛЕВОЕ СОЕДИНЕНИЕ в одном запросе, то на каждую строку основной таблицы система создаст столько строк, сколько сотрудников числится в бригаде. Если в упаковке участвовала бригада из 5 человек, количество упаковок в отчете увеличится в 5 раз. Выясним, как этого избежать.

Решение №1: Использование ресурсов и функции СоединитьСтроки

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

Рассмотрим алгоритм действий:

  1. Добавим поле Сотрудник в схему компоновки.
  2. Перейдем на вкладку Ресурсы.
  3. Для поля, в котором должен выводиться список (например, СоставБригады), напишем выражение: СоединитьСтроки(Массив(Сотрудник))
  4. В колонке "Рассчитывать по..." укажем ту группировку, внутри которой нужно объединять строки (например, по группировке Бригада или Документ).

Посмотрим подробнее на возможности функции СоединитьСтроки. Её полный синтаксис позволяет управлять разделителем:

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

Где "; " — это строка-разделитель, а третий параметр — текст, который выведется, если список пуст.

Решение №2: Использование двух наборов данных (Наборы данных - связи)

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

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

В первом наборе данных (запросе) мы выбираем только основные сведения, без обращения к составу бригад. Пример кода:


ВЫБРАТЬ РАЗЛИЧНЫЕ
    Регистр.Серия,
    Регистр.Сотрудник КАК Бригада,
    Регистр.ДатаУпаковки,
    Регистр.Серия.Владелец КАК Номенклатура
ИЗ
    РегистрСведений.ПС_УпаковкаПродукцииСотрудниками КАК Регистр
ГДЕ
    Регистр.ДатаУпаковки МЕЖДУ &ДатаНачала И &ДатаОкончания

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

Создаем второй набор данных (запрос), который выбирает только состав бригад:


ВЫБРАТЬ
    БригадыТЧСостав.Сотрудник КАК Сотрудник,
    БригадыТЧСостав.Ссылка КАК СсылкаНаБригаду
ИЗ
    Справочник.Бригады.ТЧСостав КАК БригадыТЧСостав

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

Переходим на закладку Связи наборов данных. Указываем:

Шаг 4: Настройка ресурса.

Теперь, когда данные связаны, в поле ресурса пишем уже знакомое нам выражение:

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

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

Продвинутые приемы агрегации в СКД

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

1. Исключение дублей внутри строки.

Если один и тот же человек может встретиться в составе несколько раз (например, при сложной структуре данных), используйте ключевое слово РАЗЛИЧНЫЕ внутри функции массива (доступно в актуальных версиях платформы 8.3):

СоединитьСтроки(Массив(Различные Сотрудник.Наименование), ", ")

2. Сортировка списка.

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

СоединитьСтроки(Упорядочить(Массив(Сотрудник.Наименование)), ", ")

3. Решение проблемы с итогами через функции группировки.

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

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

Выводы

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

  1. Избежать дублирования числовых показателей.
  2. Легко манипулировать списком объектов через функции Массив() и СоединитьСтроки().
  3. Обеспечить высокую скорость работы отчета за счет механизма передачи параметров связи списком.

Рассмотренные методы позволяют создавать чистые и понятные отчеты, где информация представлена компактно, а итоговые суммы всегда остаются корректными.

← На главную