Как в 1С вывести несколько связанных значений в одну строку через запятую или в отдельные колонки

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

При разработке отчетов в 1С часто возникает типовая задача: у одного родительского объекта (например, контрагента) есть несколько подчиненных записей в регистре или табличной части (например, назначенные ответственные менеджеры). При обычном соединении таблиц в запросе одна запись контрагента дублируется столько раз, сколько у него менеджеров. В результате вместо компактной таблицы получается избыточный список строк.

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

Оптимизация и корректировка текста запроса

Прежде чем переходить к настройке вывода данных, проанализируем исходный запрос и устраним потенциальные узкие места, влияющие на производительность и полноту выборки.

В исходном варианте отбор накладывается в секции ГДЕ после выполнения среза последних, а главной таблицей выступает регистр сведений. Это приводит к двум проблемам:

  1. Контрагенты, у которых еще нет записей в регистре, полностью выпадут из отчета.
  2. Срез последних без параметров сначала выберет данные по всей базе, и только потом отфильтрует их, что существенно замедляет выполнение запроса.

Посмотрим на исправленный и оптимизированный вариант запроса:


ВЫБРАТЬ
    Контрагенты.Ссылка КАК Контрагент,
    МТТ.Менеджер КАК Менеджер
ИЗ
    Справочник.Контрагенты КАК Контрагенты
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.МТТ_СведенияОРазмерахВознагражденияМенеджеров.СрезПоследних(, Контрагент = &Ссылка) КАК МТТ
    ПО (МТТ.Контрагент = Контрагенты.Ссылка)
ГДЕ
    Контрагенты.Ссылка = &Ссылка

Если отчет строится без жесткого отбора по одной ссылке, условие среза последних и секцию ГДЕ можно опустить или доверить управление параметрами самой Системе компоновки данных.

Вариант 1. Сворачивание значений в одну строку через запятую в СКД

В языке запросов 1С отсутствуют встроенные агрегатные функции для конкатенации строк (аналоги GROUP_CONCAT или STRING_AGG в SQL). Однако Система компоновки данных предоставляет мощные встроенные функции агрегации коллекций.

Разберем по шагам, как вывести список менеджеров через запятую в одной ячейке:

  1. В схеме компоновки данных перейдем на вкладку Ресурсы.
  2. Добавим поле Менеджер в список ресурсов.
  3. В колонке Выражение укажем следующую конструкцию: СоединитьСтроки(Массив(Менеджер), ", ") Если требуется исключить возможное дублирование одинаковых значений, можно использовать конструкцию с таблицей значений: СоединитьСтроки(ТаблицаЗначений(Менеджер), ", ")
  4. На вкладке Настройки добавим группировку по полю Контрагент, а в список выбранных полей выведем Контрагент и ресурс Менеджер.

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

Вариант 2. Разворот данных в кросс-таблицу (колонки) в СКД

Если требуется отобразить каждого менеджера в отдельном столбце с отметкой или значением, наиболее простым и гибким решением является использование структуры Таблица в настройках отчета СКД.

Разберем по шагам порядок настройки структуры:

  1. В запросе или вычисляемых полях добавим вспомогательное поле-маркер (например, число 1 или булево Истина) и объявим его ресурсом с выражением Максимум(ЕстьМенеджер) или Количество(Менеджер).
  2. На вкладке Настройки удалим стандартную группировку и добавим элемент Таблица.
  3. В секцию Строки таблицы перетащим группировку по полю Контрагент (вертикаль).
  4. В секцию Колонки таблицы перетащим группировку по полю Менеджер (горизонталь).
  5. В выбранные поля структуры выведем наш ресурс-отметку.

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

Вариант 3. Программная обработка выборки на встроенном языке

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

Посмотрим на пример обработки результата запроса:


// Создаем соответствие для группировки менеджеров по контрагентам
МенеджерыПоКонтрагентам = Новый Соответствие;

Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
    Если ЗначениеЗаполнено(Выборка.Менеджер) Тогда
        СписокМенеджеров = МенеджерыПоКонтрагентам[Выборка.Контрагент];
        Если СписокМенеджеров = Неопределено Тогда
            СписокМенеджеров = Новый Массив;
            МенеджерыПоКонтрагентам.Вставить(Выборка.Контрагент, СписокМенеджеров);
        КонецЕсли;
        
        // Добавляем представление менеджера, избегая повторов
        ПредставлениеМенеджера = Строка(Выборка.Менеджер);
        Если СписокМенеджеров.Найти(ПредставлениеМенеджера) = Неопределено Тогда
            СписокМенеджеров.Добавить(ПредставлениеМенеджера);
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

// Получение склеенной строки для конкретного контрагента
МассивДляВывода = МенеджерыПоКонтрагентам[ТекущийКонтрагент];
СтрокаМенеджеров = ?(МассивДляВывода <> Неопределено, СтрСоединить(МассивДляВывода, ", "), "Не назначены");

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

← На главную