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