Почему не сохранялись настройки СКД с новым полем
Как я уже писал ранее, сделал клиенту в УТ отчет, где подменил схему компоновки данных. Все работало хорошо, но не сохранялись настройки в варианте.
Проявлялось это так — если в настройках добавить поле «Остаток», то отчет формировался. Если сохранить вариант, потом переключиться на другой, потом вернуться на сохраненный, поле тоже показывалось.
Но если закрыть отчет и открыть сохраненный вариант, поля не было.
Я предполагал, что разбирательства будут долгими, так оно и оказалось. Работы были гарантийными, но мне было интересно, в чем проблема. Так можно было просто подменить макет через расширение макета, но хотелось докопаться до истины.
Вообще, был интересен вопрос — вариант сохраняется криво, без моего поля или же при восстановлении варианта происходит сбой.
Сейчас я понимаю, что надо было просто проверить, есть ли поле в настройках компоновщика при компоновке отчета из сохраненного варианта.
Но я пошел другим путем, не самым быстрым.
Я сделал замер производительности при сохранении варианта и нашел, где создается схема компоновки данных:
И вот тут я увидел, что в тексте запроса компоновки нет поля «Остаток», который я добавил (смотрите табло внизу):
Я отладил и нашел, где создается объект отчета:
В итоге я решил добавить событие, чтобы при создании отчета обновлялась компоновка данных.
В модуле ВариантыОтчетов:
&Вместо("ПодключитьОтчетОбъект") Функция дор_ПодключитьОтчетОбъект(СсылкаОтчета, ПолучатьМетаданные) Результат = ПродолжитьВызов(СсылкаОтчета, ПолучатьМетаданные); //Осипов - вызываем при создании, если возможно Попытка Результат.Объект.дор_ПриСозданииОтчета(); Исключение КонецПопытки; Возврат Результат; КонецФункции
В модуле отчета ВыручкаИСебестоимостьПродаж:
&Перед("ПередЗагрузкойНастроекВКомпоновщик") Процедура дор_ПередЗагрузкойНастроекВКомпоновщик(Контекст, КлючСхемы, КлючВарианта, НовыеНастройкиКД, НовыеПользовательскиеНастройкиКД) //Меняем на доработанную схему компановки дор_ПодменитьСхему(); КонецПроцедуры Процедура дор_ПодменитьСхему() СхемаКомпоновкиДанных = ПолучитьМакет("дор_ОсновнаяСхемаКомпоновкиДанных"); КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных)); //важно КонецПроцедуры Процедура дор_ПриСозданииОтчета() Экспорт дор_ПодменитьСхему(); КонецПроцедуры
После этого в компоновке появилось мое поле остаток:
Дальше я решил проверить, как загружаются настройки при открытии отчета, нашел вот эту функцию, где опять же создавался объект отчета, похоже со стандартной схемой компоновки (не измененной):
По стеку сложно было привязаться к каким либо событиям:
Поэтому я решил привязаться к событию ЗагрузитьНастройкиВКомпоновщик:
Код выглядел примерно так:
&НаСервере &Перед("ЗагрузитьНастройкиВКомпоновщик") Процедура дорЗагрузитьНастройкиВКомпоновщик(ПараметрыЗагрузки) //Перед вызываем ОтчетОбъект = РеквизитФормыВЗначение("Отчет"); Попытка ОтчетОбъект.дорПриСозданииОтчета(); Исключение КонецПопытки; //ЗначениеВРеквизитФормы(ОтчетОбъект, "Отчет"); ЗначениеВДанныеФормы(ОтчетОбъект, Отчет); КонецПроцедуры
Однако почему-то ЗначениеВРеквизитФормы выдавало ошибку, ругаясь на второй параметр. В общем, отладка показала, что ничего в запросе схемы компоновки не меняется, он остается без поля остаток.
Но тут я все же отладил загрузку варианта. Чтобы отлаживать не в фоновом режиме, я использовал запуск 1С с параметром РежимОтладки.
Я обнаружил, что настройка варианта загружается нормально, т.е. в списке полей настройки есть поле Остаток. Т.е. все предыдущие доработки были зря, потому что и без них вариант сохранялся и загружался нормально.
Настройки пропадают где-то при формировании отчета в коде самого отчета:
Дальнейшая проверка показала, где пропадает настройка:
Вот в этом коде настройки корректные:
КомпоновщикНастроек.Настройки.Выбор.Элементы
А вот в этом коде поля Остаток уже нет:
КомпоновщикНастроек.ПолучитьНастройки().Выбор.Элементы
Я добавил строчку для подмены настроек и отчет сформировался корректно:
Но мне не нравилось, что приходится менять код отчета. Поэтому я немножко поэкспериментировал и обнаружил, как можно привести настройки в адекватное состояние.
По сути, проблема сохранения варианта решается одной дополнительной строчкой кода в расширении, вот она:
&Перед("ПриКомпоновкеРезультата") Процедура дор_ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) КомпоновщикНастроек.ЗагрузитьНастройки(КомпоновщикНастроек.Настройки); КонецПроцедуры
Почему сбоят настройки, т.е. почему ПолучитьНастройки и Настройки одного и того же объекта выдают разные значения, я так и не понял. Я пробовал и метод ВосстановитьНастройки и добавлял инициализацию настроек в компоновщике настроек после подмены схемы компоновки, ничего не помогло. Видимо, это фича 1С.
Ошибкой было еще предположение, что где-то схема используется не измененная, поэтому настройки не сохраняются. Нужно было проверить настройки при компоновке отчета, тогда бы я увидел, что они уже там правильные, но сбрасываются из-за этой фичи.
Дело в том, что 1С всегда вызывает событие перед загрузкой настроек отчета, а там уже моё изменение схемы есть. Поэтому я по сути большую часть времени потратил на поиски фантомной ошибки, которой на самом деле не было.
UPD 2021-08-15: Обратились пользователи, решение не работало — поле остаток сохранялось, но нельзя было поменять период отчета.
Разборки показали, что проблема в пользовательских настройках, именно они при старте отчета не содержат поля остаток.
Я попробовал так, но не помогло:
Поле ДоступныеНастройки.ПользовательскиеНастройки.Элементы[3].Элементы не содержит поле Остаток:
Похоже, что пользовательские настройки отчета были модифицированы ранее.
Более детальный анализ показал, что настройки загружаются в событии формы перед загрузкой пользовательских настроек:
Поэтому нужно при создании формы отчета подменить схему компоновки.
Вот так заработало:
Но так не годится — это вмешательство в код.
Поэтому переношу код в расширение, таким образом, в расширении формы отчета достаточно такого кода (достаточно вызвать только при создании):
&НаСервере &Перед("ПриСозданииНаСервере") Процедура дор_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) //Перед вызываем ОтчетОбъект = РеквизитФормыВЗначение("Отчет"); Попытка ОтчетОбъект.дор_ПриСозданииОтчета(); Исключение КонецПопытки; ЗначениеВДанныеФормы(ОтчетОбъект, Отчет); КонецПроцедуры
Ну и в расширении модуля отчета по валовой прибыли необходимый код такой:
&Перед("ПередЗагрузкойНастроекВКомпоновщик") Процедура дор_ПередЗагрузкойНастроекВКомпоновщик(Контекст, КлючСхемы, КлючВарианта, НовыеНастройкиКД, НовыеПользовательскиеНастройкиКД) //Меняем на доработанную схему компановки дор_ПодменитьСхему(); КонецПроцедуры Процедура дор_ПодменитьСхему() Экспорт СхемаКомпоновкиДанных = ПолучитьМакет("дор_ОсновнаяСхемаКомпоновкиДанных"); КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных)); //важно КонецПроцедуры Процедура дор_ПриСозданииОтчета() Экспорт дор_ПодменитьСхему(); КонецПроцедуры
Перед загрузкой настроек в компоновщик тоже надо обрабатывать, иначе не срабатывает.
Время факт: 3 час. Среда: УТ 11.4.13.46
Свежие комментарии