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