Почему не сохранялись настройки СКД с новым полем

Как я уже писал ранее, сделал клиенту в УТ отчет, где подменил схему компоновки данных. Все работало хорошо, но не сохранялись настройки в варианте.

Проявлялось это так — если в настройках добавить поле «Остаток», то отчет формировался. Если сохранить вариант, потом переключиться на другой, потом вернуться на сохраненный, поле тоже показывалось.

Но если закрыть отчет и открыть сохраненный вариант, поля не было.

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

Вообще, был интересен вопрос — вариант сохраняется криво, без моего поля или же при восстановлении варианта происходит сбой.

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

Но я пошел другим путем, не самым быстрым.

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

И вот тут я увидел, что в тексте запроса компоновки нет поля «Остаток», который я добавил (смотрите табло внизу):

Я отладил и нашел, где создается объект отчета:

В итоге я решил добавить событие, чтобы при создании отчета обновлялась компоновка данных.

В модуле ВариантыОтчетов:

&Вместо("ПодключитьОтчетОбъект")
Функция дор_ПодключитьОтчетОбъект(СсылкаОтчета, ПолучатьМетаданные)
    Результат = ПродолжитьВызов(СсылкаОтчета, ПолучатьМетаданные);
    //Осипов - вызываем при создании, если возможно
    Попытка
        Результат.Объект.дор_ПриСозданииОтчета();
    Исключение
    КонецПопытки;
    Возврат Результат;
КонецФункции

В модуле отчета ВыручкаИСебестоимостьПродаж:

&Перед("ПередЗагрузкойНастроекВКомпоновщик")
Процедура дор_ПередЗагрузкойНастроекВКомпоновщик(Контекст, КлючСхемы, КлючВарианта, НовыеНастройкиКД, НовыеПользовательскиеНастройкиКД)
    //Меняем на доработанную схему компановки
    дор_ПодменитьСхему();
КонецПроцедуры

Процедура дор_ПодменитьСхему()
    СхемаКомпоновкиДанных = ПолучитьМакет("дор_ОсновнаяСхемаКомпоновкиДанных");
    КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных)); //важно
КонецПроцедуры

Процедура дор_ПриСозданииОтчета() Экспорт
    дор_ПодменитьСхему();
КонецПроцедуры

После этого в компоновке появилось мое поле остаток:

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

По стеку сложно было привязаться к каким либо событиям:

Поэтому я решил привязаться к событию ЗагрузитьНастройкиВКомпоновщик:

Код выглядел примерно так:

&НаСервере
 &Перед("ЗагрузитьНастройкиВКомпоновщик")
 Процедура дорЗагрузитьНастройкиВКомпоновщик(ПараметрыЗагрузки)     //Перед вызываем     ОтчетОбъект = РеквизитФормыВЗначение("Отчет");     Попытка         ОтчетОбъект.дорПриСозданииОтчета();
     Исключение
     КонецПопытки;
      //ЗначениеВРеквизитФормы(ОтчетОбъект, "Отчет");
      ЗначениеВДанныеФормы(ОтчетОбъект, Отчет);
 КонецПроцедуры

Однако почему-то ЗначениеВРеквизитФормы выдавало ошибку, ругаясь на второй параметр. В общем, отладка показала, что ничего в запросе схемы компоновки не меняется, он остается без поля остаток.

Но тут я все же отладил загрузку варианта. Чтобы отлаживать не в фоновом режиме, я использовал запуск 1С с параметром РежимОтладки.

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

Настройки пропадают где-то при формировании отчета в коде самого отчета:

Дальнейшая проверка показала, где пропадает настройка:

Вот в этом коде настройки корректные:

КомпоновщикНастроек.Настройки.Выбор.Элементы

А вот в этом коде поля Остаток уже нет:

КомпоновщикНастроек.ПолучитьНастройки().Выбор.Элементы

Я добавил строчку для подмены настроек и отчет сформировался корректно:

Но мне не нравилось, что приходится менять код отчета. Поэтому я немножко поэкспериментировал и обнаружил, как можно привести настройки в адекватное состояние.

По сути, проблема сохранения варианта решается одной дополнительной строчкой кода в расширении, вот она:

&Перед("ПриКомпоновкеРезультата")
 Процедура дор_ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
     КомпоновщикНастроек.ЗагрузитьНастройки(КомпоновщикНастроек.Настройки); 
 КонецПроцедуры

Почему сбоят настройки, т.е. почему ПолучитьНастройки и Настройки одного и того же объекта выдают разные значения, я так и не понял. Я пробовал и метод ВосстановитьНастройки и добавлял инициализацию настроек в компоновщике настроек после подмены схемы компоновки, ничего не помогло. Видимо, это фича 1С.

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

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

UPD 2021-08-15: Обратились пользователи, решение не работало — поле остаток сохранялось, но нельзя было поменять период отчета.

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

Я попробовал так, но не помогло:

Поле ДоступныеНастройки.ПользовательскиеНастройки.Элементы[3].Элементы не содержит поле Остаток:

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

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

Поэтому нужно при создании формы отчета подменить схему компоновки.

Вот так заработало:

Но так не годится — это вмешательство в код.

Поэтому переношу код в расширение, таким образом, в расширении формы отчета достаточно такого кода (достаточно вызвать только при создании):

&НаСервере
&Перед("ПриСозданииНаСервере")
Процедура дор_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	//Перед вызываем
	ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
	Попытка
		ОтчетОбъект.дор_ПриСозданииОтчета();
	Исключение
	КонецПопытки;
	ЗначениеВДанныеФормы(ОтчетОбъект, Отчет);
КонецПроцедуры

Ну и в расширении модуля отчета по валовой прибыли необходимый код такой:

&Перед("ПередЗагрузкойНастроекВКомпоновщик")
Процедура дор_ПередЗагрузкойНастроекВКомпоновщик(Контекст, КлючСхемы, КлючВарианта, НовыеНастройкиКД, НовыеПользовательскиеНастройкиКД)
	//Меняем на доработанную схему компановки
	дор_ПодменитьСхему();
КонецПроцедуры

Процедура дор_ПодменитьСхему() Экспорт
	СхемаКомпоновкиДанных = ПолучитьМакет("дор_ОсновнаяСхемаКомпоновкиДанных");
	КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных)); //важно
КонецПроцедуры

Процедура дор_ПриСозданииОтчета() Экспорт
	дор_ПодменитьСхему();
КонецПроцедуры

Перед загрузкой настроек в компоновщик тоже надо обрабатывать, иначе не срабатывает.

Время факт: 3 час. Среда: УТ 11.4.13.46

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Читайте также:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *