Как в СКД вывести значения строк в одну строку или распределить по отдельным колонкам?

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

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

Способ 1: Объединение значений в одну ячейку с помощью функции СоединитьСтроки

Если ваша цель — получить результат вида «Значение: 1, 2, 3» в одной ячейке, то наиболее современным и эффективным методом является использование встроенной функции агрегации СоединитьСтроки. Этот метод доступен в версиях платформы 8.3 и выше.

Разберем по шагам, как это настроить:

  1. Откроем схему компоновки данных и перейдем на вкладку «Ресурсы».
  2. Выберем поле Параметр, которое мы хотим склеить.
  3. В колонке «Выражение» напишем следующую конструкцию:

СоединитьСтроки(Параметр, ", ", "Параметр")

Проанализируем параметры этой функции:

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

Способ 2: Распределение данных по колонкам через настройки «Таблицы»

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

Рассмотрим алгоритм настройки:

  1. В конструкторе схемы на вкладке «Настройки» добавим новый элемент — «Таблица».
  2. В «Строки» таблицы добавим группировку по полю Знач.
  3. В «Колонки» таблицы добавим группировку по полю Параметр (или по вычисляемому номеру колонки).
  4. Вкладка «Выбранные поля»: добавим ресурс Параметр.

Важный нюанс: как отметил автор в сообщении 7, чтобы данные выводились корректно в пересечении строк и колонок, само поле Параметр обязательно должно быть определено на вкладке «Ресурсы» (например, с функцией Максимум(Параметр)). Без этого система не поймет, какое именно значение отображать на пересечении группировок.

Способ 3: Создание порядкового номера колонки в запросе

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

Посмотрим на пример текста запроса:


ВЫБРАТЬ
    Т1.Знач,
    Т1.Параметр,
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Т2.Параметр) КАК НомерКолонки
ИЗ
    ИсходныеДанные КАК Т1
        ЛЕВОЕ СОЕДИНЕНИЕ ИсходныеДанные КАК Т2
        ПО Т1.Знач = Т2.Знач
            И Т1.Параметр >= Т2.Параметр
ГРУППИРОВАТЬ ПО
    Т1.Знач,
    Т1.Параметр

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

Способ 4: Программная модификация схемы при компоновке

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

Используем обработчик события ПриКомпоновкеРезультата:


Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // Получаем настройки пользователя
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // Здесь можно программно добавить группировки в Настройки.Структура
    // Например, найти элемент Таблица и программно добавить в него колонки
    
    // Выполняем компоновку
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(Результат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
КонецПроцедуры

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

Способ 5: Использование функций общих модулей

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

В выражении ресурса это будет выглядеть так:

МойОбщийМодуль.СформироватьСписокПараметров(Знач)

Важное условие: общий модуль должен иметь флаг «Вызов сервера» и функция должна быть экспортной. Однако помните, что такой подход может существенно замедлить формирование отчета при больших объемах данных, так как функция будет вызываться для каждой строки группировки.

Рекомендации по выбору метода

Проанализируем, какой метод лучше выбрать в зависимости от задачи:

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

← На главную