При разработке отчетов на базе Системы Компоновки Данных (СКД) часто возникает задача вывести несколько значений из подчиненной таблицы в одну строку. Например, нам нужно собрать все электронные адреса или телефоны клиента и вывести их напротив каждого контрагента через запятую. Для таких задач идеально подходит встроенная функция агрегации СоединитьСтроки.
Однако на практике разработчики нередко сталкиваются с ситуацией: в консоли запросов данные есть, а в СКД при использовании функции выводится пустой отчет или пустые поля. Рассмотрим подробнее, почему так происходит и как правильно настроить объединение строк.
Проанализируем ситуацию: разработчик добавил запрос, собирающий электронные почты контрагентов и партнеров. На вкладке "Ресурсы" для поля Email было добавлено выражение СоединитьСтроки(ТаблицаЗначений(Email), ", ") с расчетом по группировке "Контрагенты". При формировании отчет оказывался абсолютно пустым.
В данном случае проблема крылась не в самой функции СКД, а в логике получения данных в запросе, а именно — в неверном обращении к реквизитам при связывании таблиц. Посмотрим на фрагмент исходного запроса:
ВЫБРАТЬ РАЗЛИЧНЫЕ
СтрокиРеализации.Ссылка.Контрагент КАК Контрагент,
СтрокиРеализации.Ссылка.Контрагент.Партнер КАК Партнер
ПОМЕСТИТЬ ВТ_Покупатели
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК СтрокиРеализации
...
Если в базе данных отключен раздельный учет по партнерам и контрагентам, обращение через точку СтрокиРеализации.Ссылка.Контрагент.Партнер может не возвращать ожидаемых данных или приводить к нарушению соединений в последующих пакетах запроса. Выясним причину: СКД строит свой итоговый запрос, и если в виртуальную таблицу контактов ничего не попадает из-за пустых связей, то и соединять функции будет нечего.
Решение этой конкретной ошибки заключалось в исправлении поля выборки:
// Неправильно:
// СтрокиРеализации.Ссылка.Контрагент.Партнер КАК Партнер
// Правильно:
СтрокиРеализации.Ссылка.Партнер КАК Партнер
После корректировки связей запрос начал корректно передавать данные в СКД, и функция СоединитьСтроки успешно отработала.
Разберем по шагам, как правильно применять эту функцию, чтобы избежать пустых значений или системных ошибок. Синтаксис функции выглядит следующим образом: СоединитьСтроки(Значение, РазделительЭлементов, РазделительКолонок).
ТаблицаЗначений() или Массив(). Если вам нужно объединить только одну колонку (например, только email), надежнее и проще использовать массив: СоединитьСтроки(Массив(Email), ", ").NULL, функция может склеить их, выведя текст <Пустое значение> или создав лишние запятые (например: mail@test.ru, , mail2@test.ru). Всегда отсекайте пустые контакты на уровне запроса с помощью условия: ГДЕ Поле <> "" И Поле ЕСТЬ НЕ NULL.Если стандартный подход не дает нужного результата из-за сложной структуры отчета или дублирования строк при соединениях, рассмотрим другие варианты реализации.
1. Использование функции вычисления по группировкам
Вместо простого массива можно принудительно собрать данные в разрезе нужной группировки до объединения строк. Выражение ресурса будет выглядеть так:
СоединитьСтроки(ВычислитьВыражениеСГруппировкойМассив("Email", "Контрагент"), ", ")
Это гарантирует, что массив адресов соберется именно в рамках конкретного контрагента, игнорируя дубли из детальных записей.
2. Вызов экспортных функций из общих модулей
Если вам требуется сложная логика (например, исключить одинаковые адреса электронной почты, отсортировать их по алфавиту или добавить префиксы), функционала СКД может не хватить. В этом случае вынесем логику в код 1С.
Создайте общий модуль (с флагами "Вызов сервера" или "Клиент (обычное приложение)"). В ресурсах СКД напишите:
МойОбщийМодуль.СклеитьИОбработатьАдреса(Массив(Email))
А внутри модуля напишите экспортную функцию, которая примет массив, удалит из него дубли с помощью объекта Соответствие и вернет результат, используя платформенную функцию СтрСоединить().
3. Групповая обработка
Для сложных составных строк (например, нужно склеить вид контакта, его значение и комментарий в один текстовый блок) можно использовать агрегатную функцию ГрупповаяОбработка. Она позволяет передать в свойства всю таблицу значений текущей группировки, которую затем можно обойти и скомпоновать программно.
Применяя эти правила и внимательно проверяя логику соединений в запросах, вы сможете легко формировать красивые и читаемые списки контактов в отчетах на СКД.