Как вывести таблицу значений в сводную кросс-таблицу с помощью Построителя отчета в 1С?

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

При разработке отчетов и обработок в 1С часто возникает задача преобразовать плоскую таблицу значений в кросс-таблицу (шахматку), где одно измерение располагается по горизонтали в шапке колонок, другое — по вертикали в строках, а на их пересечении выводятся числовые показатели. Для решения этой задачи традиционно используется объект ПостроительОтчета в связке с ОписаниеИсточникаДанных.

Однако на практике разработчики нередко сталкиваются с ситуацией, когда структура таблицы формируется, но ячейки с данными на пересечении измерений остаются пустыми либо при попытке задать итоги платформа выдает ошибку вида Неверные параметры "СУММА". Разберем по шагам, почему это происходит и как правильно настроить программный вывод.

Анализ проблемы: почему ячейки остаются пустыми

Проанализируем базовый алгоритм работы построителя отчета. Когда в качестве источника выступает ТаблицаЗначений, построитель не знает заранее, какие поля являются группировками (измерениями), а какие — вычисляемыми ресурсами.

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

Причина ошибки «Неверные параметры СУММА»

При попытке указать расчет итога строкой вида ИсточникДанных.Колонки.Количество.Итог = "СУММА(Количество)"; может возникнуть исключение при вызове метода Выполнить() или Вывести(). Выясним причину этой ошибки.

Платформа 1С требует, чтобы колонка таблицы значений, по которой рассчитывается агрегатная функция (СУММА, МИНИМУМ, МАКСИМУМ и др.), имела строгую типизацию. Если колонка была добавлена в таблицу значений без указания типа (например, ТЗ.Колонки.Добавить("Количество")), то ее тип считается неопределенным. Построитель отчета не может применить математическую функцию к нетипизированным данным или ячейкам со значениями Null, что и приводит к ошибке выполнения.

Пошаговое решение: правильная настройка Построителя отчета

Разберем рабочий пример формирования кросс-таблицы из таблицы значений.

  1. Типизация колонок исходной таблицы значений: при создании таблицы обязательно задаем числовой тип для ресурса.
  2. Инициализация описания источника данных: помечаем нужные колонки как измерения и задаем формулу итога для ресурса.
  3. Настройка структуры отчета: распределяем измерения по строкам и колонкам построителя.
  4. Вывод отчета: выполняем построитель и выводим результат в табличный документ.

Посмотрим на пример законченной процедуры:


Процедура ВывестиКроссТаблицу(ТЗ_Данные)
    
    // 1. Создаем построитель и связываем с описанием источника
    Построитель = Новый ПостроительОтчета;
    ИсточникДанных = Новый ОписаниеИсточникаДанных(ТЗ_Данные);
    
    // 2. Настраиваем измерения и ресурсы в описании источника
    ИсточникДанных.Колонки.Узел.Измерение = Истина;
    ИсточникДанных.Колонки.Родитель.Измерение = Истина;
    ИсточникДанных.Колонки.Количество.Итог = "СУММА(Количество)";
    
    Построитель.ИсточникДанных = ИсточникДанных;
    Построитель.МакетОформления = ПолучитьМакетОформления(СтандартноеОформление.Классика);
    
    // 3. Распределяем группировки по строкам и колонкам
    Построитель.ИзмеренияКолонки.Очистить();
    Построитель.ИзмеренияКолонки.Добавить("Узел");
    
    Построитель.ИзмеренияСтроки.Очистить();
    Построитель.ИзмеренияСтроки.Добавить("Родитель");
    
    // 4. Формируем и выводим отчет в табличный документ
    Построитель.ВыводитьОбщиеИтоги = Истина;
    Построитель.Выполнить();
    Построитель.Вывести();
    
КонецПроцедуры

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


ОписательЧисла = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2));
ТЗ_Результат.Колонки.Добавить("Количество", ОписательЧисла);

Альтернативные варианты построения кросс-таблиц

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

Использование Системы компоновки данных (СКД)

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

  1. В схеме компоновки создаем набор данных «Объект» с именем (например, ВнешняяТаблица).
  2. На вкладке «Ресурсы» указываем поле Количество с выражением Сумма(Количество).
  3. В настройках добавляем структуру Таблица: в строки помещаем группировку Родитель, в колонки — Узел.
  4. Если к группировке строки нужно вывести дополнительные реквизиты (например, код или артикул), добавляем их в ветку «Дополнительные поля» с расположением «В отдельных колонках».
  5. В коде передаем таблицу значений в процессор компоновки через структуру наборов данных:

ВнешниеНаборы = Новый Структура("ВнешняяТаблица", ТЗ_Результат);
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборы);

Передача таблицы значений во временную таблицу запроса

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

  1. Создаем менеджер временных таблиц: МенеджерВТ = Новый МенеджерВременныхТаблиц;.
  2. Передаем типизированную таблицу параметром в запрос: ПОМЕСТИТЬ ВТ_Данные ИЗ &ТЗ КАК ТЗ.
  3. Используем стандартные конструкции языка запросов (включая ИТОГИ ... ПО ...) для получения готовой многомерной выборки.

Ручной вывод через макет табличного документа

Если требуется нестандартное визуальное оформление, разворот можно выполнить программно:

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