Как реализовать открытие неосновной формы объекта в обычном приложении 1С

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

При разработке в среде обычного приложения (толстый клиент) программисты часто сталкиваются с необходимостью динамической подмены стандартной формы объекта на специализированную. Типичный пример: для обычных элементов справочника должна открываться основная форма, а для определенных групп или предопределенных элементов — уникальная форма с расширенным функционалом. Рассмотрим подробно, как правильно реализовать этот механизм, избежав типичных ошибок с «пустыми» формами.

Анализ проблемы: почему форма открывается пустой

Разберем ситуацию, с которой столкнулся автор вопроса. При попытке вызвать форму через ОткрытьФорму или простым вызовом ПолучитьФорму("ИмяФормы"), система открывает окно, но данные в нем отсутствуют — форма выглядит так, будто создается новый элемент. Выясним причину этого поведения.

В управляемых формах мы привыкли передавать структуру Параметры с ключом Ключ. В обычном приложении логика иная. Если методу ПолучитьФорму не указать, для какого именно объекта (ссылки) мы хотим получить визуальное представление, платформа создаст новый экземпляр объекта в памяти. Чтобы форма «увидела» данные существующего элемента, необходимо явно передать Ссылку или Объект во второй параметр метода.

Решение №1: Перехват события ПередОткрытием в модуле формы

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


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

В данном примере использование Отказ = Истина предотвращает вывод стандартного окна, а метод ПолучитьФорму с указанием ссылки гарантирует, что ФормаГруппыСпец будет инициализирована данными нужного нам элемента.

Решение №2: Вызов формы из списка (Профессиональный подход)

Рассмотрим более оптимизированный вариант. Использование события ПередОткрытием внутри самой формы имеет небольшой недостаток: стандартная форма всё равно начинает инициализироваться (выполняются процедуры ПриСозданииНаСервере в современных версиях или внутренние механизмы подготовки в старых), что тратит ресурсы. Проанализируем ситуацию: лучше вообще не доводить дело до инициализации «ненужной» формы.

Для этого мы можем перехватить событие ПередНачаломИзменения в форме списка справочника. Рассмотрим пример кода для модуля формы списка:


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

Этот подход исключает «мерцание» экрана и считается более «чистым» с точки зрения архитектуры обычного приложения.

Тонкости передачи параметров в обычных формах

В отличие от управляемого приложения, где параметры передаются в момент открытия через специальную структуру, в обычном приложении мы работаем с объектом формы напрямую. Посмотрим, как передать дополнительные данные в открываемую форму:

  1. Через свойства формы: Если в форме ФормаГруппыСпец объявлена переменная в разделе Перем с ключевым словом Экспорт, мы можем обратиться к ней после получения формы.
  2. Напрямую через реквизиты: Мы можем менять свойства формы до её отображения пользователю.

Разберем практический пример передачи параметра:


Форма = Справочники.Номенклатура.ПолучитьФорму("ФормаГруппыСпец", Ссылка);

// Пример 1: Установка стандартного свойства
Форма.ТолькоПросмотр = Истина;

// Пример 2: Передача произвольного значения в экспортную переменную формы
Форма.МойДополнительныйПараметр = "Значение для анализа";

Форма.Открыть();

Использование метода ОткрытьМодально

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


Если Предопределенный Тогда
    Отказ = Истина;
    Форма = Справочники.Номенклатура.ПолучитьФорму("ФормаГруппыСпец", Ссылка);
    Форма.ОткрытьМодально();
КонецЕсли;

Сравнение ПолучитьФорму и ОткрытьФорму

Проанализируем разницу между этими методами в контексте обычного приложения. Метод ОткрытьФорму является более высокоуровневым и часто используется для открытия общих форм или форм отчетов, где не требуется жесткая привязка к конкретному экземпляру данных объекта через контекст. Однако при работе со справочниками и документами в толстом клиенте рекомендуется использовать цепочку [Менеджер].ПолучитьФорму(...). Это дает разработчику полный контроль над объектом формы до момента его появления на экране.

Важные выводы:

Следуя этим правилам, вы сможете гибко управлять интерфейсом обычного приложения 1С, предоставляя пользователям именно те формы, которые необходимы в конкретной бизнес-ситуации.

← На главную