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

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

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

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

Почему динамический реквизит формы не сохраняет значение в базе данных?

Разберем фундаментальные принципы работы управляемых форм в 1С:

  1. Жизненный цикл формы: Реквизиты формы, созданные в конфигураторе или программно с помощью РеквизитФормы, существуют исключительно в оперативной памяти клиентского приложения и сервера на время жизни контекста текущей формы. Как только форма закрывается, все ее динамические реквизиты и элементы уничтожаются. При следующем открытии форма инициализируется заново.
  2. Разница между реквизитом формы и реквизитом объекта: Метод ИзменитьРеквизиты() добавляет свойства только в контекст формы. Нельзя «на лету» расширить состав полей прикладного объекта базы данных (структуры Объект), если соответствующий реквизит отсутствует в метаданных конфигурации или расширения.
  3. Свойство «СохраняемыеДанные»: Установка флага СохраняемыеДанные = Истина в объекте РеквизитФормы не выполняет запись значения в базу данных. Это свойство лишь информирует платформу о том, что при изменении поля пользователем форма переходит в состояние модифицированности (Модифицированность = Истина), и при попытке закрыть форму без сохранения платформа запросит подтверждение.

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

Способ 1. Добавление реквизита через расширение конфигурации

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

  1. Создаем или открываем расширение конфигурации.
  2. Добавляем в расширение целевой объект (например, справочник Контрагенты или документ).
  3. Добавляем новый реквизит в структуру объекта в расширении (например, МаксимальнаяСуммаПоставки с типом Число).
  4. Добавляем в расширение форму объекта и размещаем на ней созданный реквизит.

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

Способ 2. Хранение значений в независимом регистре сведений

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

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

В обработчике ПриСозданииНаСервере создаем реквизит и элемент формы:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Создаем массив добавляемых реквизитов формы
    МассивРеквизитов = Новый Массив;
    МассивРеквизитов.Добавить(Новый РеквизитФормы("МаксимальнаяСуммаПоставки", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)), , "Максимальная сумма поставки", Истина));
    
    ИзменитьРеквизиты(МассивРеквизитов);
    
    // Добавляем элемент управления на форму
    НовыйЭлемент = Элементы.Добавить("ПолеМаксимальнаяСуммаПоставки", Тип("ПолеФормы"), Элементы.ОсновныеСведения);
    НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
    НовыйЭлемент.ПутьКДанным = "МаксимальнаяСуммаПоставки";
    
КонецПроцедуры

Чтение сохраненного значения выполняем в обработчике ПриЧтенииНаСервере. В отличие от создания формы, этот обработчик гарантированно вызывается не только при открытии, но и при перечитывании данных объекта:


&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
    
    Если ЗначениеЗаполнено(ТекущийОбъект.Ссылка) Тогда
        Отбор = Новый Структура("Контрагент", ТекущийОбъект.Ссылка);
        ЗначенияРесурсов = РегистрыСведений.ЛимитыПоставок.ПолучитьПоследнее(, Отбор);
        МаксимальнаяСуммаПоставки = ЗначенияРесурсов.Сумма;
    КонецЕсли;
    
КонецПроцедуры

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


&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
    
    МенеджерЗаписи = РегистрыСведений.ЛимитыПоставок.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.Контрагент = ТекущийОбъект.Ссылка;
    МенеджерЗаписи.Сумма = МаксимальнаяСуммаПоставки;
    МенеджерЗаписи.Записать(Истина);
    
КонецПроцедуры

Способ 3. Использование системного хранилища настроек

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

Посмотрим на пример чтения и сохранения данных:


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

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

Способ 4. Механизм дополнительных реквизитов и сведений (БСП)

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

  1. В режиме «1С:Предприятие» переходим в раздел Администрирование → Общие настройки → Дополнительные реквизиты и сведения.
  2. Находим нужный справочник (например, Контрагенты) и добавляем дополнительный реквизит нужного типа (число, строка, ссылка).
  3. Поле автоматически появится на форме объекта и будет штатно сохраняться в табличной части ДополнительныеРеквизиты без изменения конфигурации и без написания программного кода.

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

← На главную