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