При разработке отчетов на базе Системы компоновки данных (СКД) часто возникает задача вывести данные из подчиненной таблицы (например, список сотрудников бригады) не отдельными строками, а одной строкой через запятую. Если просто соединить основную таблицу с табличной частью в запросе, количество строк в отчете увеличится, что приведет к «раздуванию» итогов и дублированию записей. В этой статье мы разберем, как правильно реализовать объединение строк, сохранив корректность числовых показателей.
Рассмотрим ситуацию: у нас есть документ или запись регистра, связанная с «Бригадой», а у бригады есть табличная часть «Состав» с несколькими сотрудниками. Проанализируем типичную ошибку. Если мы используем ЛЕВОЕ СОЕДИНЕНИЕ в одном запросе, то на каждую строку основной таблицы система создаст столько строк, сколько сотрудников числится в бригаде. Если в упаковке участвовала бригада из 5 человек, количество упаковок в отчете увеличится в 5 раз. Выясним, как этого избежать.
Если нам нужно просто склеить фамилии сотрудников, мы можем воспользоваться встроенными функциями агрегации СКД. Для этого не обязательно объединять всё в одном запросе, достаточно правильно настроить Вычисляемые поля или Ресурсы.
Рассмотрим алгоритм действий:
Сотрудник в схему компоновки.СоставБригады), напишем выражение:
СоединитьСтроки(Массив(Сотрудник))Бригада или Документ).Посмотрим подробнее на возможности функции СоединитьСтроки. Её полный синтаксис позволяет управлять разделителем:
СоединитьСтроки(Массив(Сотрудник), "; ", "Нет сотрудников")
Где "; " — это строка-разделитель, а третий параметр — текст, который выведется, если список пуст.
Как мы заметили в обсуждении, использование одного запроса часто приводит к дублированию количественных показателей (номенклатуры, веса, суммы). Проанализируем более профессиональный подход — разделение данных на два независимых набора.
Шаг 1: Создание основного набора данных.
В первом наборе данных (запросе) мы выбираем только основные сведения, без обращения к составу бригад. Пример кода:
ВЫБРАТЬ РАЗЛИЧНЫЕ
Регистр.Серия,
Регистр.Сотрудник КАК Бригада,
Регистр.ДатаУпаковки,
Регистр.Серия.Владелец КАК Номенклатура
ИЗ
РегистрСведений.ПС_УпаковкаПродукцииСотрудниками КАК Регистр
ГДЕ
Регистр.ДатаУпаковки МЕЖДУ &ДатаНачала И &ДатаОкончания
Шаг 2: Создание второго набора данных.
Создаем второй набор данных (запрос), который выбирает только состав бригад:
ВЫБРАТЬ
БригадыТЧСостав.Сотрудник КАК Сотрудник,
БригадыТЧСостав.Ссылка КАК СсылкаНаБригаду
ИЗ
Справочник.Бригады.ТЧСостав КАК БригадыТЧСостав
Шаг 3: Настройка связей.
Переходим на закладку Связи наборов данных. Указываем:
Бригада).СсылкаНаБригаду).Шаг 4: Настройка ресурса.
Теперь, когда данные связаны, в поле ресурса пишем уже знакомое нам выражение:
СоединитьСтроки(Массив(Сотрудник))
Такой подход гарантирует, что количество номенклатуры в первом наборе данных не увеличится, так как связь происходит на уровне компоновки результата, а не на уровне SQL-запроса.
Иногда простого объединения недостаточно. Разберем ситуации, когда данные нужно упорядочить или исключить дубли внутри самой строки.
1. Исключение дублей внутри строки.
Если один и тот же человек может встретиться в составе несколько раз (например, при сложной структуре данных), используйте ключевое слово РАЗЛИЧНЫЕ внутри функции массива (доступно в актуальных версиях платформы 8.3):
СоединитьСтроки(Массив(Различные Сотрудник.Наименование), ", ")
2. Сортировка списка.
Чтобы фамилии всегда шли в алфавитном порядке, используйте функцию Упорядочить:
СоединитьСтроки(Упорядочить(Массив(Сотрудник.Наименование)), ", ")
3. Решение проблемы с итогами через функции группировки.
Если вы всё же используете один набор данных и итоги задваиваются, можно применить "тяжелую артиллерию" — функцию ВычислитьВыражениеСГруппировкойТаблицаЗначений в ресурсах. Это позволит рассчитать максимум по показателю внутри группировки, а затем просуммировать эти максимумы, игнорируя дубли строк от левого соединения:
Сумма(ВычислитьВыражениеСГруппировкойТаблицаЗначений("Максимум(Количество)", "Номенклатура, Серия"))
Для объединения строк табличной части в СКД наиболее надежным и производительным способом является использование двух наборов данных, связанных между собой в самой схеме компоновки. Это позволяет:
Массив() и СоединитьСтроки().Рассмотренные методы позволяют создавать чистые и понятные отчеты, где информация представлена компактно, а итоговые суммы всегда остаются корректными.