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