Как передать значения переменных в обработчик подписки на событие в 1С

Программист 1С v8.3 (Обычные формы) Управленческий учет Промышленность, строительство и АПК
← На главную

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

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

Это стандартный и наиболее рекомендуемый механизм платформы. Каждый объект (ДокументОбъект, СправочникОбъект и др.) обладает свойством ДополнительныеСвойства, которое представляет собой структуру. Эта структура «живет» ровно столько, сколько существует сам экземпляр объекта в памяти сервера.

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


// В модуле объекта в процедуре ОбработкаПроведения
ДополнительныеСвойства.Вставить("СтруктураШапкиДокумента", СтруктураШапкиДокумента);
ДополнительныеСвойства.Вставить("ТаблицаПоПродукции", ТаблицаПоПродукции);

Теперь выясним, как получить эти данные в обработчике подписки на событие. В параметрах подписки первым аргументом всегда выступает Источник — это и есть наш экземпляр объекта.


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

КонецПроцедуры

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

Способ 2: Объявление экспортных переменных в модуле объекта

Если по каким-то причинам использование структуры ДополнительныеСвойства неудобно, мы можем объявить переменные в самом верху модуля объекта с ключевым словом Экспорт. Это сделает их доступными для чтения извне через точку от объекта Источник.

Разберем реализацию этого метода. В модуле объекта пишем:


Перем мДанныеДляПодписки Экспорт;

Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    // Выполняем расчеты
    мДанныеДляПодписки = "НужноеЗначение";
КонецПроцедуры

В подписке на событие мы сможем обратиться к этой переменной напрямую: Значение = Источник.мДанныеДляПодписки;. Однако помните, что экспортные переменные модуля объекта считаются менее «чистым» стилем программирования по сравнению с ДополнительныеСвойства.

Способ 3: Использование расширений (для современных версий платформы)

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

Мы можем создать расширение для процедуры ОбработкаПроведения и заполнить ДополнительныеСвойства там:


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

При использовании метода &Перед данные попадут в объект еще до начала основного кода проведения и будут доступны на протяжении всего процесса.

Способ 4: Анализ коллекции Движения (без изменения кода объекта)

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

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

Способ 5: Менеджер временных таблиц (для передачи больших объемов данных)

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

  1. В модуле объекта создаем Новый МенеджерВременныхТаблиц.
  2. Помещаем туда таблицу через запрос.
  3. Передаем ссылку на сам менеджер в ДополнительныеСвойства.
  4. В подписке подключаем этот менеджер к новому запросу и быстро считываем данные.

Рекомендации по безопасности и производительности

При работе с передачей данных между событиями важно соблюдать следующие правила:

Рассмотренные методы позволяют гибко управлять потоками данных в системе «1С:Предприятие 8», обеспечивая чистоту кода и минимизируя вмешательство в типовые механизмы конфигураций.

← На главную