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