Как перенести параметры между вариантами отчета на форме БСП?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке отчетов на базе стандартных форм Библиотеки Стандартных Подсистем (БСП) часто возникает задача программного переключения вариантов отчета. Например, когда по нажатию пользовательской кнопки в командной панели требуется открыть другой вариант, сохранив при этом уже выбранные пользователем параметры: период, организацию или контрагента.

Типичная проблема, с которой сталкиваются разработчики: при переключении варианта через метод формы УстановитьТекущийВариант() значения параметров либо сбрасываются к значениям по умолчанию для нового варианта, либо подставляются сохраненные ранее значения, игнорируя то, что пользователь только что ввел в шапке отчета.

Разберем причины такого поведения платформы и детально рассмотрим несколько надежных способов правильного переноса параметров.

Почему параметры не переносятся или сбрасываются

Проанализируем архитектуру хранения настроек в системе компоновки данных (СКД). В компоновщике настроек присутствуют два ключевых объекта:

  1. Основные настройки (КомпоновщикНастроек.Настройки) — описывают структуру схемы, выбранные поля, группировки, отборы и параметры самого варианта.
  2. Пользовательские настройки (КомпоновщикНастроек.ПользовательскиеНастройки) — именно к этой коллекции привязаны интерактивные элементы управления на управляемой форме (быстрые отборы и параметры в шапке).

Когда мы пытаемся скопировать параметры напрямую через свойство КомпоновщикНастроек.Настройки, возникают сразу две проблемы:

  1. Присвоение по ссылке: переменная ПредыдущиеНастройки = ФормаОтчета.Отчет.КомпоновщикНастроек.Настройки не создает независимую копию. При вызове метода УстановитьТекущийВариант() объект настроек перечитывается, и обе переменные начинают ссылаться на одни и те же измененные данные.
  2. Приоритет пользовательских настроек: при компоновке отчета и отрисовке формы приоритет имеют элементы из коллекции ПользовательскиеНастройки. Если параметр выведен в пользовательские настройки (в шапку), то при изменении значения только в КомпоновщикНастроек.Настройки.ПараметрыДанных платформа перекроет его значением из ПользовательскиеНастройки нового варианта, и пользователь визуально не увидит изменений.

Способ 1. Получение полной копии настроек и перенос через пользовательские настройки

Рассмотрим правильный алгоритм переноса параметров с сохранением интерактивно введенных данных. Для получения настроек со всеми пользовательскими правками следует использовать метод ПолучитьНастройки(), а после переключения варианта синхронизировать значения как в основных настройках, так и в пользовательских.

Посмотрим на пример кода в общем модуле или модуле формы:


// 1. Получаем полную копию текущих настроек с учетом пользовательских правок
ПредыдущиеНастройки = ФормаОтчета.Отчет.КомпоновщикНастроек.ПолучитьНастройки();

// 2. Переключаем вариант отчета
ФормаОтчета.УстановитьТекущийВариант(КлючНовогоВарианта);

Компоновщик = ФормаОтчета.Отчет.КомпоновщикНастроек;

// 3. Переносим значения параметров в основные настройки
Для Каждого ЭлементПараметра Из ПредыдущиеНастройки.ПараметрыДанных.Элементы Цикл
    Если Не ЭлементПараметра.Использование Тогда
        Продолжить;
    КонецЕсли;
    
    ПараметрТекущий = Компоновщик.Настройки.ПараметрыДанных.Найти(ЭлементПараметра.Параметр);
    Если ПараметрТекущий <> Неопределено Тогда
        ПараметрТекущий.Значение = ЭлементПараметра.Значение;
        ПараметрТекущий.Использование = Истина;
    КонецЕсли;
КонецЦикла;

// 4. Обязательно обновляем значения в пользовательских настройках для отображения в шапке
Для Каждого ЭлементПользовательских Из Компоновщик.ПользовательскиеНастройки.Элементы Цикл
    Если ТипЗнч(ЭлементПользовательских) = Тип("ЗначениеПараметраНастроекКомпоновкиДанных") Тогда
        СохраненныйПараметр = ПредыдущиеНастройки.ПараметрыДанных.Найти(ЭлементПользовательских.Параметр);
        Если СохраненныйПараметр <> Неопределено И СохраненныйПараметр.Использование Тогда
            ЭлементПользовательских.Значение = СохраненныйПараметр.Значение;
            ЭлементПользовательских.Использование = Истина;
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

// 5. Формируем отчет с новыми параметрами
ФормаОтчета.СкомпоноватьРезультат();

Обратите внимание на важный нюанс: идентификаторы пользовательских настроек (ИдентификаторПользовательскойНастройки) у одного и того же параметра в разных вариантах различаются. Поэтому сопоставлять элементы необходимо исключительно по имени параметра (Параметр).

Способ 2. Использование типовых процедур БСП

Если разработка ведется в типовой или доработанной конфигурации с интегрированной БСП, ручной обход коллекций можно заменить вызовом штатных методов. В БСП предусмотрен общий модуль КомпоновкаДанныхКлиентСервер, в котором реализована процедура УстановитьПараметр().

Разберем по шагам, как это работает. Если передать в качестве первого аргумента объект КомпоновщикНастроек, процедура сама выполнит поиск и в Настройки.ПараметрыДанных, и внутри коллекции ПользовательскиеНастройки, корректно отобразив значение в поле ввода формы.


// 1. Фиксируем актуальные параметры в структуру перед переключением
ПредыдущиеНастройки = ФормаОтчета.Отчет.КомпоновщикНастроек.ПолучитьНастройки();
СохраненныеПараметры = Новый Структура;

Для Каждого Элемент Из ПредыдущиеНастройки.ПараметрыДанных.Элементы Цикл
    Если Элемент.Использование Тогда
        СохраненныеПараметры.Вставить(Строка(Элемент.Параметр), Элемент.Значение);
    КонецЕсли;
КонецЦикла;

// 2. Меняем вариант отчета
ФормаОтчета.УстановитьТекущийВариант(КлючНовогоВарианта);

// 3. Устанавливаем параметры через БСП
Компоновщик = ФормаОтчета.Отчет.КомпоновщикНастроек;
Для Каждого КлючИЗначение Из СохраненныеПараметры Цикл
    КомпоновкаДанныхКлиентСервер.УстановитьПараметр(
        Компоновщик, 
        КлючИЗначение.Ключ, 
        КлючИЗначение.Значение
    );
КонецЦикла;

ФормаОтчета.СкомпоноватьРезультат();

Тонкости и ограничения при синхронизации параметров

Выясним возможные подводные камни, которые необходимо учитывать:

  1. Совместимость типов: убедитесь, что переносимый параметр в обоих вариантах имеет одинаковый тип. Например, если в одном варианте отчета параметр Период ожидает значение типа СтандартныйПериод, а в другом разделен на две даты типа Дата, прямое присвоение вызовет ошибку компоновки.
  2. Доступность на форме: если параметр не выведен в быстрые пользовательские настройки целевого варианта, метод БСП установит его только в базовые настройки, что не приведет к ошибкам и корректно отработает при формировании.
← На главную