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

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

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

Основной способ: используем коллекцию `ДополнительныеСвойства`

Для обмена служебными данными между формой и модулем объекта в рамках одной транзакции (записи или проведения) платформа 1С предоставляет специальный механизм — коллекцию ДополнительныеСвойства. Эта коллекция представляет собой структуру, которая временно "прикрепляется" к объекту документа, существует только во время одного серверного вызова и не сохраняется в базе данных. Это идеальный инструмент для нашей задачи.

Разберем процесс по шагам.

  1. Шаг 1. Добавление переменной в коллекцию из формы документа.
    Чтобы передать данные, нам нужно поместить их в коллекцию ДополнительныеСвойства перед тем, как платформа начнет запись или проведение документа. Наиболее подходящее место для этого — серверный обработчик события формы ПередЗаписьюНаСервере.

    В этом обработчике нам доступен параметр ТекущийОбъект — это и есть объект документа, с которым мы работаем. Именно у него есть нужная нам коллекция.

    Посмотрим на пример: предположим, у нас на форме есть реквизит ОсобыйРежимПроведения (тип Булево), и его значение нужно передать в модуль объекта.

    Код в модуле формы документа:

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

    Важный момент: для добавления используется метод Вставить(). Присваивать значение напрямую (ДополнительныеСвойства = ...) нельзя, так как сама коллекция доступна только для чтения.

  2. Шаг 2. Получение и использование переменной в модуле объекта.
    Теперь, когда данные переданы, мы можем получить их в любом обработчике модуля объекта, который вызывается в той же транзакции, например, в ОбработкаПроведения.

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

    Поэтому обязательно нужно проверять наличие свойства перед его использованием. Лучший способ для этого — метод Свойство().

    Проанализируем пример кода в модуле объекта документа:

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

    Такой подход делает код надежным и универсальным. Он будет корректно работать как при интерактивном проведении из формы, так и при программном вызове, не вызывая ошибок и выполняя нужную логику в каждой ситуации.

Подведем итоги и закрепим лучшие практики

Рассмотренный механизм является стандартным и рекомендованным способом решения подобных задач. Давайте еще раз сформулируем ключевые моменты:

Использование этого подхода позволяет создавать гибкую и предсказуемую логику, разделяя интерактивное поведение, зависящее от пользователя в форме, и базовый алгоритм проведения, заложенный в модуле объекта.

← На главную