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