Как программно переназначить форму записи регистра сведений в 1С 8.3

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

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

Проблема переназначения формы в управляемом режиме

Многие разработчики, привыкшие к обычному приложению, пытаются использовать старую схему в модуле формы: в обработчике ПриОткрытии установить параметр Отказ = Истина и вызвать ОткрытьФорму для новой формы. Однако в управляемом приложении такой подход часто приводит к тому, что не открывается ни одна форма. Проблема заключается в иерархии окон и параметрах блокировки. Если новая форма открывается с владельцем, который тут же закрывается или «отменяется» через Отказ, система может автоматически закрыть и дочернее окно.

Рассмотрим два основных способа решения этой задачи: «правильный» (через модуль менеджера) и «быстрый» (через модуль самой формы).

Способ 1. Использование события ОбработкаПолученияФормы (Рекомендуемый)

Наиболее архитектурно верный способ в 1С 8.3 — это использование обработчика ОбработкаПолученияФормы в модуле менеджера регистра сведений. Этот метод позволяет системе определить нужную форму еще до того, как она начнет создаваться в памяти, что экономит ресурсы и исключает «мигание» интерфейса.

Разберем реализацию этого метода по шагам:

  1. Откроем модуль менеджера нужного регистра сведений.
  2. Найдем или создадим процедуру ОбработкаПолученияФормы.
  3. Пропишем логику выбора формы.

Пример кода в модуле менеджера:


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

Важный нюанс: данный обработчик срабатывает только при неявном вызове формы (например, из динамического списка или при использовании функции ОткрытьФорму("РегистрСведений.Имя.ФормаЗаписи")). Если в коде явно указано полное имя формы (например, ОткрытьФорму("РегистрСведений.Имя.Форма.ФормаЗаписи_Дополнительная")), этот обработчик будет проигнорирован.

Способ 2. Переназначение в обработчике ПриОткрытии

Если по каким-то причинам вы не можете использовать модуль менеджера, существует вариант реализации логики внутри самой формы. Рассмотрим, почему у многих этот способ не работает и как это исправить.

Проблема кроется в параметре Владелец. Если у вашей дополнительной формы установлено свойство РежимОткрытияОкна = Блокировать окно владельца, то при открытии ее из основной формы «владельцем» автоматически становится текущая форма. Если вы тут же ставите Отказ = Истина, основная форма уничтожается, закрывая за собой и новую форму.

Проанализируем правильный код для модуля формы:


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

Сравнение методов и рекомендации

Выясним, какой метод лучше использовать в конкретных ситуациях:

Проанализируем ситуацию с навигационными ссылками. Если пользователь переходит по ссылке вида e1cib/data/..., система сначала обращается к менеджеру объекта. Если там прописано переназначение, пользователь сразу увидит нужный интерфейс. Если же логика в ПриОткрытии, сначала на мгновение может мелькнуть стандартная форма, прежде чем откроется дополнительная, что создает визуальный дискомфорт.

Дополнительный совет: Функциональные опции

Если выбор формы записи зависит не от данных конкретной строки, а от общей настройки программы (например, «Использовать упрощенную форму регистрации»), рассмотрите использование Функциональных опций. В свойствах регистра сведений можно указать разные основные формы для разных функциональных опций. В этом случае платформа сама, без единой строки кода, будет подставлять нужную форму в зависимости от того, включена опция или нет.

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

← На главную