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