Как открыть другую форму при вводе на основании в 1С?

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

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

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

Типичные ошибки: почему нельзя менять форму в событиях ПриОткрытии или ПриСозданииНаСервере?

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

Обычно это выглядит так: в модуле формы создаваемого документа в процедуре ПриСозданииНаСервере или ПриОткрытии пишется код, который проверяет наличие документа-основания. Если основание заполнено, разработчик вызывает программное открытие альтернативной формы (например, формы заказ-наряда), а для текущей формы устанавливает параметр Отказ = Истина.

При таком подходе мы неизбежно сталкиваемся со следующими критическими проблемами:

  1. Потеря контекста заполнения: При повторном программном открытии новой формы метод ОбработкаЗаполнения в модуле объекта запускается второй раз. Однако параметры заполнения (включая ссылку на документ-основание) в метод ДанныеЗаполнения уже не передаются автоматически так, как это делает платформа при стандартном вводе на основании. В итоге форма открывается пустой.
  2. Лишняя нагрузка на сервер: Платформа выполняет двойную работу. Сначала она инициализирует первый объект, подготавливает его стандартную форму, выполняет заполнение, а затем все это уничтожает из-за флага Отказ и начинает процесс заново для другой формы.
  3. Сложности поддержки кода: Такой код выглядит запутанным, его тяжело отлаживать, а при обновлении типовой конфигурации высока вероятность затереть эти изменения.

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

Чтобы понять, где именно нужно перехватывать управление, рассмотрим точную последовательность событий, которые отрабатывают на платформе 1С 8.3 при интерактивном вводе на основании:

  1. ОбработкаПолученияФормы (Модуль менеджера документа): Это самое первое событие. На данном этапе самого объекта документа в оперативной памяти еще не существует. Платформа только пытается определить, *какой именно шаблон формы* (интерфейсный файл) ей нужно будет построить и инициализировать.
  2. Инициализация объекта: Создается новый пустой экземпляр документа в памяти.
  3. ОбработкаЗаполнения (Модуль объекта документа): Отрабатывает стандартный алгоритм переноса данных из документа-основания в реквизиты нового документа.
  4. ПриСозданииНаСервере (Модуль выбранной формы): Инициализируется форма, которая была определена на шаге 1.

Как видим, идеальной точкой интеграции является именно шаг 1 — процедура ОбработкаПолученияФормы в модуле менеджера. Переопределив форму на этом этапе, мы заставим платформу изначально строить нужный нам интерфейс, а заполнение объекта (шаг 3) пройдет в штатном режиме без сбоев и повторных вызовов.

Реализуем подмену формы через ОбработкаПолученияФормы

Давайте разберем по шагам, как написать обработчик в модуле менеджера документа (в нашем примере это будет документ ЗаказПокупателя, для которого при вводе на основании нужно открыть форму ФормаЗаказНаряда).

Откроем модуль менеджера документа и создадим процедуру ОбработкаПолученияФормы. Нам необходимо проанализировать входящую структуру Параметры:

Проанализируем пример кода:


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

В данном примере, если вид операции в документе-основании соответствует заказу на ремонт, платформа проигнорирует стандартную форму и сразу перейдет к инициализации формы ФормаЗаказНаряда. При этом метод ОбработкаЗаполнения отработает корректно и ровно один раз.

Безопасная разработка: реализуем решение через расширение конфигурации

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

Выполним следующие шаги для настройки расширения:

  1. Создадим новое расширение конфигурации (или откроем существующее) и снимем галочку «Активно», если ведем разработку, либо оставим ее для тестирования.
  2. Добавим интересующий нас документ (например, ЗаказПокупателя) в расширение. Для этого достаточно кликнуть по нему правой кнопкой мыши в дереве метаданных основной конфигурации и выбрать «Добавить в расширение».
  3. Перейдем в модуль менеджера документа в расширении.
  4. Создадим обработчик события с аннотацией &После или &Вместо. Использование аннотации &После является наиболее безопасным, так как оно не нарушает работу других расширений или типового кода.

Посмотрим на пример реализации метода в расширении с аннотацией &После:


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

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

Важные нюансы и подводные камни

При работе с обработчиком ОбработкаПолученияФормы необходимо учитывать несколько критически важных особенностей платформы:

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

← На главную