Как передать значение из формы документа в модуль объекта для проверки при проведении

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике разработки на платформе 1С:Предприятие часто возникает задача: передать какой-либо временный признак или значение из формы документа непосредственно в модуль объекта. Это необходимо, когда логика проведения (процедура ОбработкаПроведения) должна зависеть от действий пользователя в форме, но при этом само значение не нужно сохранять в базе данных как реквизит документа. Рассмотрим подробно, как это реализовать для разных типов форм, и разберем типичные ошибки новичков.

Проблема контекста и жизненного цикла объекта

Прежде чем переходить к коду, проанализируем ситуацию. Главная сложность заключается в том, что в системе 1С форма и объект базы данных существуют раздельно. В управляемом приложении на клиенте мы работаем с типом ДанныеФормыСтруктура, который является лишь отображением данных объекта. Когда мы нажимаем кнопку «Провести», платформа создает новый экземпляр ДокументОбъект на сервере, заполняет его данными из формы и запускает транзакцию записи. Если просто объявить переменную в модуле объекта, она будет инициализироваться заново при каждом создании экземпляра, и данные из формы в нее «сами собой» не попадут.

Способ 1: Использование коллекции ДополнительныеСвойства (Универсальный)

Это наиболее правильный и рекомендуемый методистами 1С способ. У каждого объекта (справочника, документа) есть свойство ДополнительныеСвойства, которое представляет собой структуру. Эта структура живет вместе с конкретным экземпляром объекта в памяти.

Разберем реализацию для управляемых форм, так как здесь передача данных требует двух этапов.

Шаг 1. Передача значения с клиента на сервер формы

В модуле формы в обработчике ПередЗаписью на клиенте мы можем добавить параметры в структуру ПараметрыЗаписи. Это позволит «пробросить» флаг через границу «клиент-сервер».


&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
    // Например, мы хотим передать признак, что пользователь подтвердил проведение с превышением лимита
    ПараметрыЗаписи.Вставить("ПроводитьБезПроверкиЛимитов", Истина);
КонецПроцедуры

Шаг 2. Перенос значения в объект

Теперь в обработчике ПередЗаписьюНаСервере нам доступен ТекущийОбъект — это именно тот экземпляр объекта, который будет записываться в базу. Мы перекладываем данные из параметров записи в его дополнительные свойства.


&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    Если ПараметрыЗаписи.Свойство("ПроводитьБезПроверкиЛимитов") Тогда
        ТекущийОбъект.ДополнительныеСвойства.Вставить("ПроводитьБезПроверкиЛимитов", ПараметрыЗаписи.ПроводитьБезПроверкиЛимитов);
    КонецЕсли;
КонецПроцедуры

Шаг 3. Использование в модуле объекта

Теперь в процедуре ОбработкаПроведения мы можем легко считать этот флаг:


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    ПроводитьБезПроверки = Ложь;
    Если ДополнительныеСвойства.Свойство("ПроводитьБезПроверкиЛимитов") Тогда
        ПроводитьБезПроверки = ДополнительныеСвойства.ПроводитьБезПроверкиЛимитов;
    КонецЕсли;
    
    Если Не ПроводитьБезПроверки Тогда
        // Здесь ваша логика проверки
    КонецЕсли;
КонецПроцедуры

Способ 2: Экспортные переменные модуля объекта

Этот способ чаще применяется в обычных (неуправляемых) формах. В модуле объекта можно объявить переменную с ключевым словом Экспорт. Она будет доступна через точку от объекта.

В модуле объекта:


Перем мМойФлаг Экспорт;

Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    Если мМойФлаг = Истина Тогда
        // Действие
    КонецЕсли;
КонецПроцедуры

В модуле обычной формы вы можете напрямую обратиться к переменной:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    ЭтотОбъект.мМойФлаг = Истина;
КонецПроцедуры

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

Особенности фонового проведения и БСП

Выясним причину, по которой данные могут теряться даже при использовании ДополнительныеСвойства. Если в вашей конфигурации (например, УТ 11, ERP, КА 2) используется фоновое проведение (когда проведение документа выполняется в отдельном фоновом задании для ускорения работы интерфейса), то коллекция ДополнительныеСвойства, заполненная в сеансе пользователя, не будет передана в фоновое задание.

Рассмотрим, как это работает:

  1. Пользователь нажимает «Провести».
  2. Документ просто записывается в базу.
  3. Платформа запускает фоновое задание, которое заново считывает документ из базы по ссылке.
  4. Поскольку в базе данных ваши временные флаги не хранятся, объект в фоновом задании будет «пустым».

Решение для фонового проведения: Если флаг критически важен, придется либо отказаться от фонового проведения для этого документа, либо записывать флаг в реальный (скрытый) реквизит документа, либо использовать вспомогательные регистры сведений, где в качестве ключа выступает ссылка на документ.

Типичные ошибки при реализации

Проанализируем основные промахи, которые совершают разработчики:

  1. Объявление переменной без слова Экспорт: В этом случае она будет видна только внутри модуля объекта и недоступна из формы.
  2. Попытка передачи через глобальные переменные: Использование глобальных переменных (в модуле приложения) — плохая практика. В многопользовательской среде значения будут перетираться разными пользователями, а в серверных вызовах они могут быть недоступны.
  3. Инициализация в ОбработкеЗаполнения: Как отмечалось в обсуждении на форуме, значения, установленные в ОбработкаЗаполнения, доступны только в момент создания нового объекта. При последующих открытиях формы и проведениях объект инициализируется заново.

Таким образом, для надежной работы в современной среде 1С:Предприятие 8.3 используйте механизм Дополнительных свойств в связке с серверными обработчиками формы. Это обеспечит чистоту кода и корректную передачу данных в рамках транзакции записи.

← На главную