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

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

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

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

Проанализируем структуру выполнения кода платформы 1С:Предприятие. Модуль объекта документа (включая обработчики ПередЗаписью, ПриЗаписи и ОбработкаПроведения) исполняется строго на стороне сервера в рамках транзакции записи базы данных.

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

  1. Разделение контекстов «Клиент-Сервер»: Любые интерактивные элементы интерфейса и методы работы с формами (такие как ПолучитьФорму или ОткрытьФорму) не существуют на сервере. Попытка вызвать их из модуля объекта вызывает исключение недоступности контекста.
  2. Жизненный цикл экземпляров: Форма обработки является отдельным клиентским объектом сеанса. Метод ПолучитьФорму, даже если бы он вызывался на клиенте, создает совершенно новый экземпляр формы с реквизитами по умолчанию, а не обращается к уже открытому экрану с галочкой пользователя.
  3. Повторяемость проведения: Данные на форме обработки существуют только во время сеанса работы пользователя. При перепроведении документа, групповом перепроведении или выполнении регламентных заданий форма обработки не открывается вовсе, что сделало бы алгоритм проведения неработоспособным.

Способ 1: Передача флага через ДополнительныеСвойства объекта документа

Рассмотрим наиболее популярный способ передачи разовых параметров из обработки в модуль объекта без изменения структуры метаданных конфигурации. Коллекция ДополнительныеСвойства объекта ДокументОбъект представляет собой структуру, существующую в оперативной памяти сервера на время проведения и записи.

Разберем реализацию по шагам:

  1. В коде модуля формы обработки при записи или проведении документа заполняем дополнительное свойство:

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

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

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

Способ 2: Добавление реквизита в сам документ

Если поведение документа при повторном проведении должно строго сохраняться независимо от того, как и когда документ перепроводится, правильным решением является добавление постоянного реквизита в метаданные документа.

Рассмотрим порядок действий:

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

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

Способ 3: Использование регистра сведений (для типовых конфигураций на поддержке)

Если конфигурация находится на типовой поддержке без возможности редактирования реквизитов документа, можно создать независимый непериодический регистр сведений (например, ДополнительныеНастройкиДокументов).

  1. Создаем регистр сведений с измерением Документ (тип ДокументСсылка) и ресурсом ФлагОбработки (тип Булево).
  2. В обработке перед проведением делаем запись в регистр сведений:

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