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