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

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

В практике разработчика 1С часто возникает задача внедрить общую логику для множества различных справочников или документов. Например, нужно запустить обработчик ожидания при открытии формы, зафиксировать время закрытия или выполнить дополнительные проверки при записи. Делать это вручную для каждой формы трудозатратно и неудобно в плане поддержки. Разберем, как реализовать универсальный перехват событий ПриСозданииНаСервере, ПриЗаписи и ПриЗакрытии, используя возможности платформы 8.3 и Библиотеки стандартных подсистем (БСП).

Метод 1. Программная установка действия через расширение общего модуля

Если ваша конфигурация построена на БСП, мы можем внедрить код в процесс создания формы на самом раннем этапе. Большинство форм в современных конфигурациях интегрированы с подсистемой "Подключаемые команды". Проанализируем ситуацию: при создании формы вызывается общий модуль ПодключаемыеКоманды. Мы можем создать расширение для процедуры ПриСозданииНаСервере этого модуля.

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


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

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

Важный нюанс: метод УстановитьДействие полностью заменяет существующий обработчик. Этот прием часто востребован, когда необходима доработка динамических списков или перехват стандартных действий. Чтобы не нарушить логику типовой конфигурации, выясним причину, почему в данном случае используется процедура Подключаемый_ВыполнитьКомандуНаСервере. В формах, использующих БСП, эта процедура часто уже присутствует и предназначена для обработки различных команд. Платформа 1С позволяет назначать один и тот же обработчик разным событиям, даже если количество параметров не совпадает идеально — система просто передаст те параметры, которые предусмотрены для конкретного события.

Метод 2. Идентификация события внутри универсального обработчика

Когда мы перенаправили несколько событий (например, ПриЗаписи и ПриЗакрытии) в одну процедуру, нам нужно понять, откуда пришел вызов. Посмотрим на пример того, как можно косвенно определить источник вызова по составу параметров:


&НаКлиенте
Процедура Подключаемый_ВыполнитьКоманду(Команда)
    // Здесь мы можем проанализировать параметры или состояние формы
    // Если нам нужно отловить закрытие:
    ОписаниеОповещения = Новый ОписаниеОповещения("ПослеЗакрытияФормы", ЭтотОбъект);
    ЭтотОбъект.ПодключитьОбработчикОповещения(ОписаниеОповещения);
КонецПроцедуры

Для клиентских событий разберем по шагам использование метода ПодключитьОбработчикОповещения. Это позволяет "подписаться" на закрытие формы без прямого переназначения события ПриЗакрытии, что значительно безопаснее для стабильности системы.

Метод 3. Заимствование "пустых" форм в расширение (метод патчинга)

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

  1. Создаем расширение и заимствуем в него нужную форму справочника.
  2. Критически важно: не переносим в расширение элементы формы и реквизиты. Нам нужен только модуль.
  3. В модуле формы расширения используем аннотации &После или &Перед для стандартных обработчиков событий.

Проанализируем преимущества этого метода: при обновлении основной конфигурации, если состав реквизитов или элементов формы изменится, ваше расширение не вызовет конфликтов, так как оно "не знает" о внутреннем составе формы, а лишь дописывает логику в события. Платформа 1С 8.3.15+ позволяет заимствовать формы в "заблокированном" состоянии, что минимизирует риски при обновлении.

Метод 4. Использование подписок на события (уровень сервера)

Если ваша задача — выполнять действия именно при записи данных (а не визуальные изменения в интерфейсе), то лучшим решением будет использование механизма Подписки на события. Это наиболее "чистый" способ с точки зрения архитектуры 1С.

Разберем по шагам процесс настройки:

  1. В расширении создаем новый объект типа Подписка на событие.
  2. В качестве источника выбираем СправочникОбъект (или конкретные справочники).
  3. Выбираем событие ПриЗаписи или ПередЗаписью.
  4. Назначаем обработчик в общем модуле расширения.

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

Метод 5. Глобальный мониторинг через обработчик ожидания

В исключительных случаях, когда форма не интегрирована в БСП и вы не хотите заимствовать сотни объектов, рассмотрим вариант с мониторингом открытых окон. Это "костыльный", но иногда единственный способ отследить закрытие форм.

Мы можем запустить глобальный обработчик ожидания в модуле управляемого приложения:


&НаКлиенте
Процедура МониторингОкон() Экспорт
    ОкнаПриложения = ПолучитьОкна();
    Для Каждого Окно Из ОкнаПриложения Цикл
        // Сравниваем текущий список окон с сохраненным ранее в глобальной переменной
        // Если окно справочника "Номенклатура" исчезло — значит, форма была закрыта
    КонецЦикла;
КонецПроцедуры

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

Итоги и рекомендации

Для реализации универсальной подписки мы рекомендуем комбинированный подход:

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

← На главную