Как правильно открыть альтернативную форму справочника при выборе или создании из документа

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

В процессе разработки в среде 1С:Предприятие 8 часто возникает классическая задача: при нажатии кнопки добавления (создания) или выбора в поле ввода документа необходимо открыть не основную форму элемента справочника, а другую, специально подготовленную вспомогательную форму. При попытке реализовать это поведение начинающие разработчики часто сталкиваются с неприятным эффектом, когда сначала открывается нужная (новая) форма, а сразу вслед за ней — стандартная форма по умолчанию.

В этой статье мы подробно разберем, почему возникает такая ошибка, проанализируем внутренние механизмы платформы 1С и рассмотрим два правильных архитектурных подхода к решению этой задачи: локальный (на клиенте) и глобальный (через модуль менеджера).

Выясняем причину: почему открываются две формы подряд?

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


&НаКлиенте
Процедура ТарифныйПланСоздание(Элемент, СтандартнаяОбработка)
    ОткрытьФорму("Справочник.ТарифныеПланы.Форма.ФормаТарифПриСоздании");
КонецПроцедуры

При таком коде платформа сначала послушно выполняет процедуру разработчика и открывает форму ФормаТарифПриСоздании. Однако сразу после завершения этой процедуры на экране появляется стандартная форма элемента. Почему это происходит?

Дело в параметре СтандартнаяОбработка. По умолчанию он всегда имеет значение Истина. Если в теле обработчика мы не изменим его значение на Ложь, платформа расценит это как сигнал к тому, что после выполнения кастомного кода разработчика необходимо запустить стандартный системный алгоритм — в данном случае, открыть основную форму элемента справочника, установленную по умолчанию.

Для того чтобы избежать двойного открытия, нам необходимо явно управлять поведением платформы. Ниже мы детально разберем два корректных сценария реализации.

---

Способ 1. Локальный метод (переопределение на клиенте в форме документа)

Этот способ является самым простым и предпочтительным, если вам нужно открывать альтернативную форму исключительно из одного конкретного документа (или конкретного поля ввода). В данном случае нам не нужно вносить изменения в модуль менеджера справочника.

Выполним настройку по шагам:

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

&НаКлиенте
Процедура ТарифныйПланСоздание(Элемент, СтандартнаяОбработка)
    // 1. Отменяем стандартное системное открытие формы
    СтандартнаяОбработка = Ложь; 
    
    // 2. Настраиваем структуру параметров (если необходимо передать данные в новую форму)
    ПараметрыОткрытия = Новый Структура;
    
    // 3. Открываем нашу специальную форму, указывая владельца
    ОткрытьФорму("Справочник.ТарифныеПланы.Форма.ФормаТарифПриСоздании", ПараметрыОткрытия, Элемент);
КонецПроцедуры

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

---

Способ 2. Глобальный метод (через модуль менеджера справочника)

Этот подход сложнее, но незаменим в тех случаях, когда логика выбора формы должна работать глобально по всей системе. Например, если вид открываемой формы зависит от роли текущего пользователя, параметров самого объекта или контекста, и эта логика должна применяться при вызове из любых документов, списков и отчетов.

Для реализации этого сценария используется предопределенный обработчик ОбработкаПолученияФормы в модуле менеджера прикладного объекта.

Рассмотрим по шагам, как правильно настроить это взаимодействие:

Шаг 1. Код в форме документа (на клиенте)

В обработчике события документа мы отменяем стандартное действие, но при этом запрашиваем открытие стандартной (общей) формы, передавая в параметрах специальный маркер (флаг):


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

Шаг 2. Код в модуле менеджера справочника

Теперь перейдем в модуль менеджера справочника ТарифныеПланы. Здесь мы перехватим запрос на получение формы и подменим её:


Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
    
    // Проверяем, что система пытается получить именно форму объекта (создания/редактирования)
    Если ВидФормы = "ФормаОбъекта" Тогда
        
        // Проверяем наличие нашего уникального ключа-маркера в переданных параметрах
        Если Параметры.Свойство("ОсобыйРежимОткрытия") Тогда
            
            // Подменяем путь к форме на нашу альтернативную форму
            ВыбраннаяФорма = "Справочник.ТарифныеПланы.Форма.ФормаТарифПриСоздании";
            
            // Указываем платформе, что мы сами определили форму и стандартная обработка больше не нужна
            СтандартнаяОбработка = Ложь;
            
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

---

Разбор критических ошибок из обсуждения на форуме

Давайте проанализируем ошибки, которые допустил автор темы в сообщении №7, пытаясь совместить оба метода. Понимание этих ошибок убережет вас от неверных решений в будущем.

Ошибка №1: Попытка проверить СтандартнаяОбработка на сервере в модуле менеджера

Автор написал в модуле менеджера:

Если СтандартнаяОбработка = Ложь Тогда ...

Это логическая ошибка. В процедуру ОбработкаПолученияФормы параметр СтандартнаяОбработка всегда приходит из платформы со значением Истина (True). Ваша задача как разработчика — не проверять его, а наоборот, присвоить ему значение Ложь внутри процедуры, если вы переопределили форму в переменной ВыбраннаяФорма.

Ошибка №2: Двойной вызов при явном указании пути к форме

Если вы на клиенте явно вызываете ОткрытьФорму с точным указанием пути к вашей специальной форме ("Справочник.ТарифныеПланы.Форма.ФормаТарифПриСоздании"), то платформа сразу открывает её напрямую. В этот момент задействовать еще и ОбработкаПолученияФормы в модуле менеджера бессмысленно и вредно — это приводит к путанице в параметрах и повторным вызовам генерации окон.

Резюме: какой способ выбрать?

Для принятия решения используйте простое правило:

← На главную