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