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