Как убрать итоги по группировкам при выводе Построителя отчета в 1С для корректного экспорта в Excel?

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

При работе с legacy-кодом или адаптации старых отчетов под управляемые формы программисты часто сталкиваются с необходимостью использовать ПостроительОтчета. Несмотря на то, что современным стандартом разработки является Система компоновки данных (СКД), в некоторых конфигурациях до сих пор успешно функционируют механизмы на базе построителя, которые приходится поддерживать и дорабатывать в тонком клиенте.

Типичная проблема возникает при попытке выгрузить кросс-таблицу или сложный многоуровневый отчет в формат Microsoft Excel. Платформа 1С при формировании отчета через ПостроительОтчета принудительно выводит промежуточные итоги по группировкам строк. При выгрузке такого документа в Excel формулы и сторонние макросы начинают задваивать или застраивать итоговые суммы, что делает дальнейший автоматизированный анализ данных невозможным. Выясним, почему возникает эта проблема, и разберем несколько способов ее решения.

Почему Построитель отчета выводит итоги по группировкам?

В объекте ПостроительОтчета за вывод итогов отвечает свойство РазмещениеИтоговВСтроках. Данное свойство принимает значения из системного перечисления ТипРазмещенияИтогов. К сожалению, архитектура этого объекта не предполагает варианта «Не выводить вообще». Платформа предлагает лишь настроить их положение:

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

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

---

Решение 1: Фильтрация строк по цвету фона (метод автора темы)

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

Разберем по шагам логику этого решения:

  1. Определяем количество уровней группировок в табличном документе с помощью метода КоличествоУровнейГруппировокСтрок().
  2. Если уровней больше одного, убираем группировку строк методом Разгруппировать(), чтобы пользователю не выводились «плюсики» сворачивания.
  3. Запускаем цикл обхода строк снизу вверх или сверху вниз.
  4. Для каждой строки анализируем цвет ячейки во второй колонке. Если цвет фона строго равен белому (RGB 255, 255, 255), мы пропускаем строку. Если цвет отличается — удаляем строку целиком сдвигом вверх.

Посмотрим на пример реализации данного алгоритма:


КолвоУровней = ЭтаФорма.Результат.КоличествоУровнейГруппировокСтрок();
Если КолвоУровней > 1 Тогда
    Таб = ЭтаФорма.Результат;
    Строк = Таб.ВысотаТаблицы;
    
    // Снимаем группировку со всего документа
    Таб.Область("R1:R" + Формат(Строк, "ЧРГ=; ЧГ=0")).Разгруппировать();
    
    ИндексСтроки = 2; // Предполагаем, что строка 1 — это шапка
    Пока ИндексСтроки <= Таб.ВысотаТаблицы Цикл
        ЯчейкаПроверки = Таб.Область(ИндексСтроки, 2, ИндексСтроки, 2);
        Цвет = ЯчейкаПроверки.ЦветФона;
        
        // Проверяем, является ли цвет белым
        Если (Цвет.Зеленый = 255) И (Цвет.Красный = 255) И (Цвет.Синий = 255) Тогда
            ИндексСтроки = ИндексСтроки + 1;
        Иначе
            // Удаляем строку группировки/итога
            ОбластьУдаления = Таб.Область("R" + Формат(ИндексСтроки, "ЧРГ=; ЧГ=0"));
            Таб.УдалитьОбласть(ОбластьУдаления, ТипСмещенияТабличногоДокумента.ПоВертикали);
        КонецЕсли;
    КонецЦикла;
КонецЕсли;

Преимущества метода: Простота реализации без необходимости глубоко влезать в структуру запросов построителя.

Критические недостатки:

---

Решение 2: Определение итогов через проверку расшифровки (Надежный программный метод)

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

Рассмотрим, как можно надежно выявить и очистить строки итогов на основе анализа типа данных расшифровки:


Таб = ЭтаФорма.Результат;
ИндексСтроки = Таб.ВысотаТаблицы;

// Обходим таблицу снизу вверх, чтобы корректно удалять строки без сдвига индексов
Пока ИндексСтроки > 1 Цикл
    Ячейка = Таб.Область(ИндексСтроки, 1); // Проверяем первую колонку группировки
    Расшифровка = Ячейка.ПараметрРасшифровки;
    
    // Строки группировок и итогов часто содержат структуру или массив в расшифровке
    Если ТипЗнч(Расшифровка) = Тип("Структура") Тогда
        ОбластьУдаления = Таб.Область("R" + Формат(ИндексСтроки, "ЧРГ=; ЧГ=0"));
        Таб.УдалитьОбласть(ОбластьУдаления, ТипСмещенияТабличногоДокумента.ПоВертикали);
    КонецЕсли;
    
    ИндексСтроки = ИндексСтроки - 1;
КонецЦикла;

Этот способ гораздо стабильнее, так как он не зависит от визуального отображения, стилей или настроек монитора пользователя.

---

Решение 3: Оптимизация удаления строк через сборку нового документа (Высокая скорость работы)

Если ваш отчет содержит тысячи строк, последовательное удаление областей со сдвигом парализует работу пользователя. Оптимизируем этот процесс. Вместо удаления «плохих» строк из готового документа, мы создадим новый пустой ТабличныйДокумент и скопируем в него только «хорошие» (детальные) строки.

Разберем пример быстрой сборки плоской таблицы:


ИсходныйТаб = ЭтаФорма.Результат;
НовыйТаб = Новый ТабличныйДокумент;

// Копируем параметры страницы и шапку (допустим, первые 3 строки)
НовыйТаб.Вывести(ИсходныйТаб.Область("R1:R3"));

Для НомерСтроки = 4 По ИсходныйТаб.ВысотаТаблицы Цикл
    Ячейка = ИсходныйТаб.Область(НомерСтроки, 1);
    
    // Проверяем, является ли строка детальной (например, по типу значения расшифровки)
    Если ТипЗнч(Ячейка.ПараметрРасшифровки) <> Тип("Структура") Тогда
        // Выводим только детальные строки
        НовыйТаб.Вывести(ИсходныйТаб.Область("R" + Формат(НомерСтроки, "ЧРГ=; ЧГ=0")));
    КонецЕсли;
КонецЦикла;

// Заменяем результат на очищенный документ
ЭтаФорма.Результат = НовыйТаб;

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

---

Решение 4: Нативный обход проблемы через дополнительные поля построителя

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

Вместо этого мы можем использовать механизм дополнительных полей:

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

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

← На главную