Почему при открытии управляемой формы 1С очищается реквизит, заполненный в ПриСозданииНаСервере?

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

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

Анализ проблемы: переданные параметры и жизненный цикл формы

Рассмотрим типовой сценарий, в котором проявляется данное поведение. Из одной формы (например, записи регистра сведений) выполняется программный вызов управляемой формы обработки:


&НаКлиенте 
Процедура ВыполнитьВыгрузкуДанных(Команда) 
    ПараметрыОткрытия = Новый Структура; 
    ПараметрыОткрытия.Вставить("мФайлВыгрузки", Запись.ФайлВыгрузкиДанных); 
    ОткрытьФорму("Обработка.ВыгрузкаДанных.Форма.УправляемаяФорма", ПараметрыОткрытия); 
КонецПроцедуры

В модуле открываемой формы в процедуре ПриСозданииНаСервере значение параметра считывается и помещается в реквизит формы или объекта обработки:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Если Параметры.Свойство("мФайлВыгрузки") Тогда    
        ИмяФайлаДанных = Параметры.мФайлВыгрузки;
    КонецЕсли;
КонецПроцедуры

При пошаговой отладке видно, что на последней строке процедуры ПриСозданииНаСервере переменная ИмяФайлаДанных заполнена. Но как только управление передается в клиентскую процедуру ПриОткрытии, реквизит оказывается пустым, при этом в коде нет явных команд очистки. Чтобы понять природу этой ошибки, проанализируем две особенности работы платформы 1С:Предприятие 8.3.

  1. Удаление неключевых параметров формы. Платформа очищает все переданные параметры из коллекции Параметры сразу после завершения обработчика ПриСозданииНаСервере, если у них в свойствах формы не установлен признак Ключевой. Поэтому обратиться к неключевому параметру напрямую в клиентском событии ПриОткрытии нельзя.
  2. Автоматическая загрузка сохраненных настроек пользователя. Это главная причина затирания реквизита. Если для формы или конкретного реквизита включен механизм сохранения данных в настройках, платформа применяет сохраненные ранее значения строго в промежутке между серверным созданием формы и ее клиентским открытием. Если ранее пользователь закрыл форму с пустым полем, платформа сохранила это пустое значение и при следующем открытии перезаписала инициализированный реквизит.

Посмотрим на строгую последовательность событий жизненного цикла формы при открытии:

  1. Срабатывает ПриСозданииНаСервере (здесь реквизит заполняется значением из переданных параметров).
  2. Срабатывает серверное событие ПередЗагрузкойДанныхИзНастроекНаСервере.
  3. Платформа автоматически применяет сохраненные настройки (именно в этот невидимый для точек останова отладчика момент реквизит перезаписывается сохраненным пользовательским значением).
  4. Срабатывает серверное событие ПриЗагрузкеДанныхИзНастроекНаСервере.
  5. Срабатывает клиентское событие ПриОткрытии (здесь разработчик обнаруживает уже стертое значение).

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

Если для конкретного поля формы нет необходимости сохранять пользовательский ввод между сеансами, самым простым и надежным решением будет снятие флага сохранения. Разберем, как это сделать:

  1. В конфигураторе перейдем к управляемой форме обработки.
  2. Откроем свойства формы и обратим внимание на свойства СохранениеДанныхВНастройках и АвтоматическоеСохранениеДанныхВНастройках.
  3. Если сохранение включено для конкретных реквизитов, найдем реквизит ИмяФайлаДанных и в его свойствах снимем флажок Сохранение.
  4. Если в свойствах формы для настройки СохранениеДанныхВНастройках выбрано значение ИспользоватьСписок, проверим перечень сохраняемых реквизитов и снимем отметку с проблемного поля.

После отключения признака платформа перестанет вмешиваться в значение реквизита, и переданный в ПриСозданииНаСервере параметр корректно сохранится к моменту выполнения ПриОткрытии.

Способ 2. Управление загрузкой через событие ПередЗагрузкойДанныхИзНастроекНаСервере

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

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


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

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

Способ 3. Переопределение значения в ПриЗагрузкеДанныхИзНастроекНаСервере

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

Посмотрим на пример кода при использовании ключевого параметра:


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

Способ 4. Очистка сохраненных пользовательских настроек

Если логика формы настроена правильно, но у конкретного пользователя платформа подставляет пустое значение из ранее поврежденного или пустого кэша настроек, выясним причину сбросом настроек формы. Очистить данные можно двумя способами:

  1. В пользовательском режиме: перейти в форму обработки, открыть меню команд формы (или «Главное меню» → «Настройки») и выполнить команду Очистить настройки....
  2. Программно: удалить записанные параметры формы из системного хранилища:
    
    ХранилищеСистемныхНастроек.Удалить("Обработка.ВыгрузкаДанных.Форма.УправляемаяФорма", "", "");
    

Способ 5. Инициализация через параметры стандартного заполнения

Если реквизит, в который передаются данные, принадлежит не самой форме, а объекту обработки (Объект.ИмяФайлаДанных), надежным механизмом передачи является использование предопределенного параметра ЗначенияЗаполнения. Рассмотрим этот подход:


&НаКлиенте 
Процедура ВыполнитьВыгрузкуДанных(Команда) 
    СтруктураЗаполнения = Новый Структура;
    СтруктураЗаполнения.Вставить("ИмяФайлаДанных", Запись.ФайлВыгрузкиДанных);
    
    ПараметрыОткрытия = Новый Структура; 
    ПараметрыОткрытия.Вставить("ЗначенияЗаполнения", СтруктураЗаполнения); 
    
    ОткрытьФорму("Обработка.ВыгрузкаДанных.Форма.УправляемаяФорма", ПараметрыОткрытия); 
КонецПроцедуры

В этом случае платформа автоматически выполняет стандартную процедуру ОбработкаЗаполнения в модуле объекта обработки при инициализации данных формы, корректно передавая значения в реквизиты объекта без риска их случайной потери при ручной обработке событий формы.

← На главную