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