Как программно заполнить пользовательские параметры СКД и избежать их исчезновения при открытии формы?

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

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

Анализируем причину проблемы: порядок вызова событий

Основная причина «исчезновения» параметров кроется в механизме работы управляемых форм 1С. Разберем по шагам, что происходит на сервере, когда мы открываем форму отчета:

  1. ПриСозданииНаСервере: Здесь разработчик обычно пишет код для установки параметров. Мы обращаемся к КомпоновщикНастроек, меняем значения, и кажется, что всё готово.
  2. ПередЗагрузкойПользовательскихНастроекНаСервере: Это системный этап. Платформа готовится применить к отчету те настройки, с которыми пользователь работал в прошлый раз (они хранятся в системном хранилище настроек).
  3. ПриЗагрузкеПользовательскихНастроекНаСервере: На этом этапе сохраненные настройки фактически «накладываются» на компоновщик.

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

Решение 1: Использование обработчика ПередЗагрузкойПользовательскихНастроекНаСервере

Рассмотрим самый надежный вариант. Чтобы программно установленные параметры не сбрасывались, их установку следует выполнять (или дублировать) в событии ПередЗагрузкойПользовательскихНастроекНаСервере. Посмотрим на пример кода, который позволяет перехватить управление:


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

В этом примере мы анализируем входящие параметры формы и, если находим нужный, принудительно записываем его в Настройки, которые система как раз собирается применить. Таким образом, наши данные оказываются «финальными».

Решение 2: Передача структуры «Отбор» через параметры открытия формы

Проанализируем более простой и изящный способ, который предоставляет расширение управляемой формы отчета. При вызове метода ОткрытьФорму мы можем передать специальную структуру. Система автоматически попытается сопоставить ключи этой структуры с параметрами или полями отбора СКД.

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


// В модуле формы документа или обработки
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("Номенклатура", ТекущаяНоменклатура);
ПараметрыОтбора.Вставить("Организация", Объект.Организация);

ПараметрыФормы = Новый Структура("Отбор", ПараметрыОтбора);

ОткрытьФорму("Отчет.Продажи.ФормаОбъекта", ПараметрыФормы);

Важный нюанс этого метода: 1С автоматически ищет в СКД параметр с именем «Номенклатура». Если такой параметр существует и доступен, система установит ему значение. Если параметра нет, но есть доступное поле компоновки с таким именем, будет добавлен элемент отбора. Это «типовой» и рекомендуемый путь для простых случаев.

Решение 3: Работа через Пользовательские настройки (важные правила)

Выясним распространенную ошибку начинающих разработчиков. Часто код пишется так:

Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Склад", Склад);

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

Разберем правильный подход к поиску элемента в пользовательских настройках:


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

Важно: Никогда не обращайтесь к элементам по индексу (например, Элементы[1]). Если завтра вы добавите новый параметр в схему или измените их порядок, ваш код сломается или начнет работать некорректно. Использование ИдентификаторПользовательскойНастройки — единственный безопасный способ синхронизации.

Особенности работы с периодами (тип СтандартныйПериод)

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

Если вы попытаетесь программно установить только ДатаНачала в основных настройках, пользовательская настройка «Период» может перекрыть ваше значение при загрузке. Рассмотрим, как правильно работать с таким типом данных:


// Пример установки периода
НовыйПериод = Новый СтандартныйПериод;
НовыйПериод.ДатаНачала = НачалоМесяца(ТекущаяДата());
НовыйПериод.ДатаОкончания = КонецМесяца(ТекущаяДата());

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

Фиксированные настройки как альтернатива

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

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

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

← На главную