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