Почему не срабатывает ОбработкаПолученияФормы при программном открытии и как подменить форму в 1С?

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

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

Выясним причину: механика работы события ОбработкаПолученияФормы

Для понимания проблемы обратимся к синтаксису и механизму работы процедуры ОбработкаПолученияФормы в модуле менеджера объекта:


Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
    // Переопределение формы
    СтандартнаяОбработка = Ложь;
    ВыбраннаяФорма = "ИмяМоейФормы";
КонецПроцедуры

Проанализируем логику платформы 1С:Предприятие 8.3:

  1. Запрос стандартной формы: Данное событие менеджера и соответствующая подписка на событие срабатывают исключительно тогда, когда система пытается получить стандартную форму объекта. Это происходит при интерактивном открытии пользователем (из командного интерфейса, панели разделов) либо при программном вызове с обобщенным именем вида ОткрытьФорму("Обработка.КлиентБанк.Форма").
  2. Прямой вызов конкретной формы: В типовых конфигурациях вызовы из связанных рабочих мест часто реализованы через указание конкретного имени формы, например ОткрытьФорму("Обработка.КлиентБанк.Форма.Форма") или ОткрытьФорму("Обработка.КлиентБанк.Форма.ОсновнаяФорма"). Когда платформе передан явный путь к конкретной форме, этап сопоставления стандартной формы полностью пропускается. Платформа считает выбор формы завершенным, поэтому событие ОбработкаПолученияФормы не вызывается вообще.
  3. Отсутствие глобального перехватчика: В платформе 1С не существует механизма глобального клиентского перехвата вызовов метода ОткрытьФорму, а подписки на события работают на стороне сервера для строго определенного набора событий метаданных.

Рассмотрим, почему распространенная идея прерывания в процедуре формы не работает.

Почему не подходит установка Отказ = Истина в ПриСозданииНаСервере

Иногда разработчики предлагают в процедуре ПриСозданииНаСервере оригинальной формы написать Отказ = Истина, надеясь следом вызвать свою форму. Разберем, к чему это приведет:

  1. Установка флага Отказ = Истина на сервере приводит к генерации исключения на клиенте при выполнении метода ОткрытьФорму, в результате чего пользователь получает системную ошибку об отказе в создании формы.
  2. Открыть новую форму непосредственно из серверного контекста ПриСозданииНаСервере технически невозможно, так как метод ОткрытьФорму является строго клиентским методом.

Теперь рассмотрим рабочие и надежные варианты решения этой задачи без снятия конфигурации с поддержки.

Решение 1. Переопределение вызова команды в расширении конфигурации

Если конфигурация находится на типовой поддержке, наиболее правильный и поддерживаемый путь — перехватить процедуру вызова в той форме, откуда производится открытие (в нашем примере — журнал «Банковские выписки»).

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

  1. Добавляем в конфигурацию расширение (или используем существующее).
  2. Заимствуем в расширение вызывающую форму журнала.
  3. Находим клиентскую процедуру (обработчик команды или кнопки), в которой вызывается метод ОткрытьФорму для целевой обработки.
  4. Переопределяем данный метод с помощью аннотации &Вместо.

Посмотрим на пример переопределения процедуры в расширении:


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

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

Решение 2. Модификация оригинальной формы обработки через расширение

Зачастую отдельную форму-дублер создавать не обязательно, если требуется лишь дополнить интерфейс или изменить поведение типовой формы. В современной платформе 1С расширения позволяют изменять форму напрямую.

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

  1. Заимствуем в расширение не только журнал, но и саму оригинальную форму обработки (ту, которую жестко вызывает типовой код).
  2. В расширении добавляем на заимствованную форму необходимые реквизиты, элементы управления и команды.
  3. С помощью директив &Перед, &После или &Вместо переопределяем события формы (ПриСозданииНаСервере, ПриОткрытии) и логику работы кнопок.

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

← На главную