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