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