Как программно свернуть группировки строк в отчете 1С СКД и избежать ошибок?

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

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

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

Выясняем причины ошибок при программном выводе

Когда мы отключаем стандартную обработку в событии ПриКомпоновкеРезультата с помощью свойства СтандартнаяОбработка = Ложь, вся ответственность за формирование отчета ложится на наши плечи. Платформа больше не выполняет автоматическую подготовку макета, инициализацию процессоров и вычисление параметров "под капотом". Это приводит к двум главным проблемам, с которыми столкнулся автор темы:

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

Давайте последовательно разберем, как решить эти проблемы программным путем.

Решение 1. Правильный программный вывод в модуле объекта

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

Разберем по шагам реализацию в процедуре ПриКомпоновкеРезультата:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // 1. Отключаем стандартный вывод платформы
    СтандартнаяОбработка = Ложь;
    
    // 2. Явно устанавливаем параметры, которые вызывали ошибку синтаксиса
    // Извлекаем текущие настройки компоновщика (с учетом пользовательских изменений)
    ТекущиеНастройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // Заполняем параметр напрямую из кода, обходя вычисление выражения в СКД
    ЗначениеКонстанты = Константы.ИмяНужнойКонстанты.Получить();
    ПараметрКонстанты = ТекущиеНастройки.ПараметрыДанных.Найти("ИмяПараметраВСКД");
    Если ПараметрКонстанты <> Неопределено Тогда
        ПараметрКонстанты.Значение = ЗначениеКонстанты;
        ПараметрКонстанты.Использование = Истина;
    КонецЕсли;
    
    // 3. Создаем макет компоновки данных
    КомпоновщикМакет = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакет.Выполнить(СхемаКомпоновкиДанных, ТекущиеНастройки, ДанныеРасшифровки);
    
    // 4. Инициализируем процессор компоновки и РАЗРЕШАЕМ внешние функции
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    
    // Третий параметр метода Инициализировать отвечает за возможность использования внешних функций
    // Передаем Истина, чтобы функции общих модулей в вычисляемых полях отработали без ошибок
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
    
    // 5. Выводим результат в табличный документ
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
    // 6. Сворачиваем группировки строк до нужного уровня (например, до 1-го уровня)
    ДокументРезультат.ПоказатьУровеньГруппировокСтрок(1);
    
КонецПроцедуры

Важное примечание: Обратите внимание на использование метода КомпоновщикНастроек.ПолучитьНастройки() вместо прямого обращения к свойству КомпоновщикНастроек.Настройки. Метод ПолучитьНастройки() собирает воедино как фиксированные настройки отчета, так и все пользовательские изменения (отборы, сортировки, условное оформление), сделанные на форме перед формированием.

Решение 2. Сворачивание группировок на уровне формы (Рекомендуемый способ)

Переопределение стандартной обработки в модуле объекта имеет один существенный минус: отчет перестает формироваться в фоновом режиме. На управляемых формах тяжелые отчеты формируются асинхронно, чтобы не "вешать" интерфейс пользователя. Как только мы пишем СтандартнаяОбработка = Ложь, формирование становится синхронным, и пользователь видит зависший экран до окончания процесса.

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

Для этого выполним следующие действия:

  1. В модуле управляемой формы отчета найдем или создадим обработчик события ПриОткрытии или используем предопределенные события формы. Если в вашей конфигурации используется Библиотека Стандартных Подсистем (БСП), у формы отчета есть событие ПослеЗаполненияПанелиБыстрыхНастроек или специализированные переопределяемые модули.
  2. Если вы используете собственную кнопку "Сформировать" на форме, код будет выглядеть максимально просто:

&НаКлиенте
Процедура СформироватьОтчет(Команда)
    
    // Очищаем предыдущий результат
    Результат.Очистить();
    
    // Вызываем стандартный метод формирования отчета на форме
    СкомпоноватьРезультат();
    
    // Сворачиваем группировки до 1 уровня на клиенте
    Результат.ПоказатьУровеньГруппировокСтрок(1);
    
КонецПроцедуры

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

Полезный лайфхак: Надежная свертка группировок "снизу вверх"

Иногда при вызове метода ПоказатьУровеньГруппировокСтрок(1) на сложных иерархических отчетах дочерние группировки внутри свернутых родительских остаются раскрытыми. Из-за этого при ручном раскрытии плюсика пользователю сразу вываливается вся "простыня" вложенных данных.

Чтобы гарантировать красивую и последовательную свертку всех уровней, опытные разработчики используют обход уровней группировок в цикле снизу вверх. Рассмотрим этот алгоритм:


// Получаем максимальное количество уровней группировок в сформированном документе
МаксимальныйУровень = ДокументРезультат.КоличествоУровнейГруппировокСтрок();

// Последовательно сворачиваем уровни, начиная с самых глубоких
Для ТекущийУровень = 1 По МаксимальныйУровень - 1 Цикл
    ДокументРезультат.ПоказатьУровеньГруппировокСтрок(МаксимальныйУровень - ТекущийУровень);
КонецЦикла;

// В самом конце устанавливаем желаемый уровень отображения
ДокументРезультат.ПоказатьУровеньГруппировокСтрок(1);

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

← На главную