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

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

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

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

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

Рассмотрим по шагам, как настроить этот обработчик в модуле менеджера документа:

  1. Откроем модуль менеджера нужного документа (например, Документ.ЗаказПоставщику).
  2. Создадим процедуру ОбработкаПолученияФормы со стандартным набором параметров: ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка.
  3. Проанализируем параметры вызова. Если открывается существующий документ, его ссылка передается в свойстве Параметры.Ключ. Если создается новый документ, вид операции извлекается из Параметры.ЗначенияЗаполнения.
  4. При совпадении условий установим СтандартнаяОбработка = Ложь и передадим имя нужной формы в переменную ВыбраннаяФорма.

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


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

КонецПроцедуры

Важный нюанс производительности: ни в коем случае не вызывайте метод Параметры.Ключ.ПолучитьОбъект() внутри процедуры получения формы. Это приведет к считыванию всех данных объекта из базы данных еще до открытия интерфейса, что существенно замедлит работу конфигурации. Используйте легкие запросы к базе данных или функции чтения отдельных реквизитов.

Способ 2. Создание промежуточной формы выбора вида операции

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

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

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


&НаКлиенте
Процедура КомандаСоздатьУслуги(Команда)
	
	ПараметрыФормы = Новый Структура;
	ЗначенияЗаполнения = Новый Структура("ВидОперации", ПредопределенноеЗначение("Перечисление.ВидыОперацийЗаказаПоставщику.Услуги"));
	ПараметрыФормы.Вставить("ЗначенияЗаполнения", ЗначенияЗаполнения);
	
	ОткрытьФорму("Документ.ЗаказПоставщику.Форма.ФормаДокументаУслуги", ПараметрыФормы, ЭтотОбъект);
	
КонецПроцедуры

Способ 3. Организация интерфейса через группы страниц («Слои») в единой форме

Если дублирование логики между двумя независимыми формами нежелательно, но визуально интерфейс должен выглядеть совершенно по-разному, можно применить подход с панелями страниц:

  1. На основной форме документа создаем элемент управления типа Страницы.
  2. Устанавливаем свойство ОтображениеЗакладок = ОтображениеЗакладок.Нет, чтобы пользователь не мог переключать вкладки вручную.
  3. Создаем отдельные страницы под каждый вид операции и размещаем на них необходимые реквизиты, таблицы и поля.
  4. В обработчике формы ПриСозданииНаСервере или при изменении реквизита операции программно переключаем активную вкладку:

&НаСервере
Процедура УстановитьВидимостьСтраницПоВидуОперации()
	
	Если Объект.ВидОперации = Перечисления.ВидыОперацийЗаказаПоставщику.Услуги Тогда
		Элементы.ГруппаСтраницы.ТекущаяСтраница = Элементы.СтраницаУслуги;
	Иначе
		Элементы.ГруппаСтраницы.ТекущаяСтраница = Элементы.СтраницаТовары;
	КонецЕсли;
	
КонецПроцедуры

Архитектурные рекомендации: выбор между одной и несколькими формами

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

  1. Раздельные формы: идеально подходят, когда бизнес-логика, состав реквизитов и поведение табличных частей не пересекаются. Код получается чистым и не перегружен бесконечными проверками условий. Однако при добавлении общих реквизитов их придется вручную выносить на каждую созданную форму. Для минимизации дублирования кода выносите общие алгоритмы расчетов и проверок в модуль менеджера или модуль объекта.
  2. Единая форма (через страницы или видимость): позволяет централизованно сопровождать общие элементы и алгоритмы формы, но может привести к громоздкому модулю формы с множеством условий в обработчиках событий.
← На главную