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