При разработке отчетов на базе системы компоновки данных (СКД) разработчики нередко сталкиваются с ситуацией, когда параметр добавлен на вкладке «Параметры», но при попытке программно присвоить ему значение в процедуре ПриКомпоновкеРезультата возникает ошибка: «Параметр с указанным именем не найден». Особенно часто это проявляется в отчетах без основного набора данных, где используются вложенные схемы компоновки.
Разберем детально, почему компоновщик настроек не видит созданный параметр, как устранить проблему с кэшированием структуры и как гарантированно передавать параметры в подчиненные схемы.
Проанализируем основные факторы, из-за которых коллекция КомпоновщикНастроек.Настройки.ПараметрыДанных не содержит добавленного параметра:
ПользовательскиеНастройки, а прямое обращение к Настройки.ПараметрыДанных может приводить к ошибкам при компоновке.Если параметр был только что создан в конфигураторе, но в режиме «1С:Предприятие» возникает исключение, выполним следующие действия:
/ClearCache.
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
// Принудительно инициализируем компоновщик доступными настройками схемы
КомпоновщикНастроек.Инициализировать(
Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных)
);
КомпоновщикНастроек.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию);
ПараметрыДанных = КомпоновщикНастроек.Настройки.ПараметрыДанных;
ПараметрыДанных.УстановитьЗначениеПараметра("ЭтоСНГ", Ложь);
КонецПроцедуры
Метод УстановитьЗначениеПараметра() вызывает исключение, если параметра нет в коллекции настроек. Чтобы код работал стабильно и не вызывал аварийных завершений при несовпадении сохраненных пользовательских вариантов со схемой, используем метод НайтиЗначениеПараметра().
Посмотрим на пример безопасного заполнения параметра:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
ПараметрСКД = Новый ПараметрКомпоновкиДанных("ЭтоСНГ");
// Поиск и установка в основных настройках
ЭлементПараметра = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(ПараметрСКД);
Если ЭлементПараметра <> Неопределено Тогда
ЭлементПараметра.Значение = Ложь;
ЭлементПараметра.Использование = Истина;
КонецЕсли;
// Поиск и установка в пользовательских настройках (если выведен на форму)
Для Каждого Элемент Из КомпоновщикНастроек.ПользовательскиеНастройки.Элементы Цикл
Если ТипЗнч(Элемент) = Тип("ЗначениеПараметраНастроекКомпоновкиДанных")
И Элемент.Параметр = ПараметрСКД Тогда
Элемент.Значение = Ложь;
Элемент.Использование = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Рассмотрим правила связывания параметров основной и вложенной схемы:
Всегда. Это предотвращает автоматическое отключение параметра, если он не задействован напрямую в основном запросе.ОбъектНастройкиВладелец.ПараметрыДанных.ИмяПараметра.
Для Каждого ЭлементСтруктуры Из КомпоновщикНастроек.Настройки.Структура Цикл
Если ТипЗнч(ЭлементСтруктуры) = Тип("НастройкиВложенногоОбъектаКомпоновкиДанных") Тогда
ЭлементСтруктуры.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("ЭтоСНГ", Ложь);
КонецЕсли;
КонецЦикла;
Если значение параметра СКД зависит от параметров сеанса (например, текущий пользователь, организация по умолчанию или статус СНГ), нет необходимости писать код в модуле объекта. СКД поддерживает получение значений глобального контекста напрямую в схеме.
Для этого в конфигураторе на вкладке «Параметры» в колонке «Выражение» указываем:
ПараметрыСеанса.ИмяПараметраСеанса
Либо вызываем функцию неглобального общего модуля с серверным контекстом:
ОбщийМодульСервер.ПолучитьПризнакСНГ()
При таком подходе СКД сама вычисляет значение параметра в момент компоновки макета, исключая ошибки поиска элементов в настройках компоновщика.