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