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