Мы часто сталкиваемся с ситуацией, когда необходимо внести изменения в логику работы типовых объектов конфигурации 1С, например, при открытии какой-либо обработки. Одним из наиболее удобных и рекомендованных способов для этого является использование подписок на события в расширениях. Однако, как показывает практика и опыт наших коллег, в некоторых случаях, например, с типовой обработкой "СогласованиеПлатежей", подписка на событие ОбработкаПолученияФормы может просто не срабатывать. Давайте вместе разберем, почему так происходит, и какие есть эффективные решения этой проблемы.
Прежде всего, давайте проанализируем ситуацию, описанную автором вопроса. Он пытался перехватить открытие формы обработки "СогласованиеПлатежей" с помощью подписки на событие ОбработкаПолученияФормы, размещенной в расширении. При этом, для справочников и документов подписки работали корректно, а для этой обработки – нет. Интересный факт: при открытии той же обработки через меню "Функции для технического специалиста" отладчик срабатывал, но при открытии из раздела "Банк и касса" – нет.
Разберем подробнее, в чем здесь кроется проблема. Событие ОбработкаПолученияФормы, реализованное в модуле менеджера некоторых объектов, предназначено для переопределения стандартной управляемой формы, когда платформа сама определяет, какую форму открыть для объекта. Это очень удобно, когда нам нужно подменить типовую форму своей, расширенной, не вмешиваясь в основной код конфигурации.
Однако, здесь есть важный нюанс, который часто упускается из виду. Платформа 1С, начиная с версии 8.2.14, имеет особенность: "При явном указании открываемой формы событие не вызывается". Что это значит? Если в коде конфигурации (например, в модуле команды, формы или другого объекта) используется метод ОткрытьФорму() с полным, явным указанием имени формы, то событие ОбработкаПолученияФормы не будет инициировано.
Посмотрим на пример, как это может выглядеть в типовом коде:
ОткрытьФорму("Обработка.СогласованиеПлатежей.Форма.ФормаОбработки", ...);
В этом случае, платформа не "спрашивает" у события ОбработкаПолученияФормы, какую форму ей открыть, поскольку ей уже четко указали путь. Она просто открывает ту форму, имя которой передано в метод ОткрытьФорму(). Именно поэтому при открытии обработки из раздела "Банк и касса" подписка не срабатывает – скорее всего, там используется явное указание формы.
Когда же вы открываете обработку через "Функции для технического специалиста", платформа, вероятно, делает это "неявным" образом, позволяя событию ОбработкаПолученияФормы сработать, поскольку ей нужно самой определить, какая форма соответствует объекту.
Итак, если подписка на событие ОбработкаПолученияФормы не подходит из-за явного указания формы, мы не отчаиваемся. У нас есть другое, не менее мощное и гибкое решение – это перехват события ПриСозданииНаСервере самой формы обработки. Этот подход является рекомендованным и наиболее надежным для внесения изменений в логику работы существующих форм, особенно когда нам нужно выполнить какие-либо действия в момент создания формы на сервере.
Мы будем использовать расширения конфигурации. Этот механизм позволяет нам модифицировать типовую функциональность, не снимая конфигурацию с поддержки, что значительно упрощает дальнейшие обновления.
Заимствуем форму обработки в расширение.
Для начала нам необходимо "заимствовать" форму обработки, которую мы хотим модифицировать, в наше расширение. Это можно сделать через конфигуратор: откройте расширение, найдите нужную обработку (например, "СогласованиеПлатежей"), разверните ее, найдите форму (например, "ФормаОбработки") и добавьте ее в расширение.
Создаем обработчик события ПриСозданииНаСервере для заимствованной формы.
После того как форма будет заимствована, мы можем открыть ее в расширении и перейти к ее модулю. Здесь мы найдем событие ПриСозданииНаСервере. Мы можем добавить свой обработчик к этому событию, используя специальные аннотации расширений.
Рассмотрим подробнее доступные аннотации и их назначение:
Аннотация &Перед (Перед):
Эта аннотация указывает, что наш код в расширении будет выполнен до выполнения типового обработчика события ПриСозданииНаСервере. Это полезно, когда нам нужно подготовить какие-либо данные, изменить параметры формы или выполнить предварительные проверки до того, как сработает стандартная логика.
Посмотрим на пример кода:
&Перед("ПриСозданииНаСервере")
Процедура ПриСозданииНаСервереПеред(Отказ, СтандартнаяОбработка)
// Здесь мы можем выполнить свою логику до типового обработчика
Сообщить("Форма обработки 'СогласованиеПлатежей' открывается!");
// Например, изменить видимость какого-либо элемента
// Элементы.МояКнопка.Видимость = Ложь;
КонецПроцедуры
Аннотация &После (После):
Эта аннотация, наоборот, указывает, что наш код будет выполнен после выполнения типового обработчика события ПриСозданииНаСервере. Это идеальный вариант, если нам нужно доработать результат работы типового кода, изменить уже сформированные данные или выполнить какие-либо действия после полной инициализации формы.
Посмотрим на пример кода:
&После("ПриСозданииНаСервере")
Процедура ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Здесь мы можем выполнить свою логику после типового обработчика
Сообщить("Форма обработки 'СогласованиеПлатежей' полностью загружена.");
// Например, изменить заголовок формы
// ЭтаФорма.Заголовок = "Мое расширенное согласование платежей";
КонецПроцедуры
Аннотация &Вместо (Вместо):
Эта аннотация является самой мощной, но и самой "опасной". Она указывает, что наш код в расширении полностью заменит типовой обработчик события ПриСозданииНаСервере. То есть, типовой код выполняться не будет вовсе. Используйте эту аннотацию с большой осторожностью и только тогда, когда вы точно знаете, что типовой обработчик не нужен, или когда вы полностью воспроизводите его логику, добавляя свои изменения. В противном случае вы можете нарушить стандартную функциональность.
Проанализируем ситуацию: если несколько расширений пытаются перехватить одно и то же событие с использованием &Вместо, могут возникнуть конфликты, так как только один обработчик сможет полностью перехватить выполнение. Обычно срабатывает тот, который загружен последним.
Посмотрим на пример кода:
&Вместо("ПриСозданииНаСервере")
Процедура ПриСозданииНаСервереВместо(Отказ, СтандартнаяОбработка)
// Здесь мы полностью контролируем логику создания формы
Сообщить("Типовой обработчик ПриСозданииНаСервере заменен!");
// Если вам нужно вызвать типовой код, вы можете сделать это так:
// ВызватьТиповойОбработчик("ПриСозданииНаСервере", Отказ, СтандартнаяОбработка);
// Но обычно, если используем &Вместо, то пишем свою логику с нуля
КонецПроцедуры
Помимо перехвата событий, расширения также предоставляют нам возможность напрямую изменять элементы заимствованных форм: добавлять новые элементы управления, изменять их свойства (видимость, доступность, заголовок и т.д.), перемещать их и многое другое. Это делает расширения чрезвычайно мощным инструментом для адаптации интерфейса и функциональности без изменения основной конфигурации.
Мы рассмотрели два основных подхода к перехвату открытия форм в 1С. Важно понимать, когда какой из них применять:
ОбработкаПолученияФормы: Используем, когда нужно подменить стандартную форму объекта на свою, и открытие формы происходит неявно (без полного указания пути). Это наиболее "чистый" способ для переопределения стандартных форм.ПриСозданииНаСервере формы через расширение: Используем, когда форма открывается с явным указанием пути, или когда нам нужно выполнить какие-либо действия непосредственно в процессе создания самой формы на сервере. Это очень гибкий и надежный метод для модификации логики конкретной формы.Всегда отдавайте предпочтение расширениям. Этот механизм был разработан специально для того, чтобы вносить изменения в типовую конфигурацию, не снимая ее с поддержки. Это значительно упрощает процесс обновления вашей информационной базы в будущем, так как вам не придется каждый раз заново интегрировать свои доработки в обновленную конфигурацию.
Надеемся, что этот подробный разбор поможет вам успешно решать подобные задачи в вашей практике программирования на 1С!
← К списку