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