Как сохранить параметры и отборы при смене варианта отчета в СКД

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

При работе с отчетами на базе Системы компоновки данных (СКД) разработчики часто сталкиваются с тем, что при переключении между предопределенными вариантами отчета все введенные пользователем параметры и отборы сбрасываются. Это происходит потому, что каждый вариант — это по сути отдельный набор настроек. Однако для удобства пользователя часто требуется, чтобы, установив период или организацию в одном варианте, эти значения сохранялись и при переходе к другому представлению тех же данных.

В этой статье мы подробно разберем, почему стандартное поведение системы именно такое, и как программно реализовать «умный» перенос настроек, используя возможности встроенного языка 1С.

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

Разберем внутреннюю механику работы компоновщика настроек. Объект КомпоновщикНастроек содержит несколько коллекций:

  1. Настройки (НастройкиКомпоновкиДанных) — это «каркас» текущего варианта.
  2. ПользовательскиеНастройки (ПользовательскиеНастройкиКомпоновкиДанных) — это значения, которые пользователь изменил на форме.
  3. ФиксированныеНастройки — настройки, которые нельзя изменить пользователю.

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

Способ 1. Программный перенос через соответствие имен

Самый надежный метод — это сохранить текущие значения в структуру или соответствие перед сменой варианта, а затем найти аналогичные элементы в новом варианте по их имени (для параметров) или пути к данным (для отборов).

Рассмотрим алгоритм реализации. Допустим, переключение происходит в форме отчета. Нам необходимо перехватить момент смены варианта. В управляемых формах это удобно делать в обработчике команды смены варианта или через событие ПриЗагрузкеВариантаНаФорме.

Сначала подготовим функцию для сбора текущих настроек в структуру:


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

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

Способ 2. Использование события ПриЗагрузкеВариантаНаФорме

Этот метод считается наиболее правильным при работе с управляемыми формами в современных конфигурациях. Мы используем тот факт, что в момент вызова этого события у нас есть доступ к коллекции настроек.

Разберем по шагам, как это реализовать:

  1. Перед тем как система применит новые настройки, мы запоминаем старые.
  2. После загрузки нового варианта мы выполняем сопоставление.

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

Посмотрим на пример кода, который можно адаптировать для формы:


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

КонецПроцедуры

Особенности работы с отборами

С отборами ситуация несколько сложнее, чем с параметрами. В отборах пользователь может создавать целые группы (И, ИЛИ, НЕ) или использовать сложные виды сравнения. Проанализируем простейший случай переноса плоского списка отборов.

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


НовыйОтбор = ПользовательскиеНастройки.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЗаполнитьЗначенияСвойств(НовыйОтбор, СтарыйОтбор, , "ИдентификаторПользовательскойНастройки");

Внимание: никогда не копируйте ИдентификаторПользовательскойНастройки напрямую между вариантами. Этот идентификатор должен оставаться уникальным для текущего контекста компоновщика, иначе связь между визуальным полем на форме и данными в объекте будет разорвана.

Типичные ошибки и способы их решения

Проанализируем распространенную ситуацию: код написан, значения в отладчике присваиваются, но на форме пользователь по-прежнему видит пустые поля. Почему это происходит?

  1. Приоритет пользовательских настроек. Как верно замечено в Сообщении 9, разработчики часто пытаются менять значения в КомпоновщикНастроек.Настройки.ПараметрыДанных. Но если эти параметры вынесены в пользовательские настройки, система просто проигнорирует ваши изменения, заменив их значениями из ПользовательскиеНастройки. Работать нужно именно с последними.
  2. Использование флага Использование. Если вы программно установили значение, но не установили Элемент.Использование = Истина, параметр не будет применен при компоновке.
  3. Обновление формы. После программного изменения настроек на сервере, не забудьте убедиться, что форма обновила свое состояние. Иногда требуется вызов ОбновитьОтображениеДанных() на клиенте.
  4. Несовпадение типов. Например, в одном варианте период задан как один параметр типа СтандартныйПериод, а в другом — двумя датами НачалоПериода и КонецПериода. В этом случае потребуется дополнительная логика конвертации данных.

Рекомендация по использованию БСП

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

Однако для нестандартных случаев ручной перенос через сопоставление имен в ПользовательскиеНастройки остается самым гибким и надежным инструментом в арсенале программиста 1С.

← На главную