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