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