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