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

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

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

Причина №1: Автоматическое сохранение данных в настройках

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

Когда открывается форма, события происходят в строго определенной последовательности:

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

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


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

Причина №2: Путаница между реквизитом формы и реквизитом объекта

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

Если в коде вы пишете:

Объект.Контрагент = Параметры.Контрагент;

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

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


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

Причина №3: Ключевые параметры формы

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

Посмотрим, какие преимущества это дает:

Рекомендация: Использование структуры «ЗначенияЗаполнения»

Если ваша задача — открыть форму нового объекта (документа или элемента справочника) и заполнить его данными по умолчанию, правильнее использовать стандартный механизм платформы ЗначенияЗаполнения. Вместо передачи произвольного параметра, передайте структуру с ключом ЗначенияЗаполнения.

Пример вызова из другой формы:


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

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

В этом случае в модуле объекта (или обработки) сработает процедура ОбработкаЗаполнения, и данные попадут в реквизиты Объект.Контрагент автоматически, еще до того, как начнет работать логика формы. Это считается наиболее «чистым» и правильным архитектурным подходом в 1С.

Итоги

Если программное заполнение не срабатывает, выполните следующие шаги:

  1. Проверьте свойство «Сохранять данные в настройках» у реквизитов и формы. Если оно включено — используйте ПередЗагрузкойДанныхИзНастроекНаСервере, чтобы отменить перезапись.
  2. Убедитесь, что ПутьКДанным у элемента формы на 100% совпадает с тем реквизитом, который вы заполняете в коде.
  3. Попробуйте использовать стандартный механизм ЗначенияЗаполнения для передачи данных в новые объекты.

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

← На главную