Как получить уже открытую управляемую форму в обычном приложении 1С?

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

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

Почему форма открывается повторно: механизм работы ключа уникальности

Для того чтобы понять, почему вызов ОткрытьФорму("ОбщаяФорма.МояФорма") не возвращает ссылку на уже открытое окно, выясним причину и последовательность действий платформы при поиске экземпляров форм в памяти клиента.

Поиск уже открытой формы выполняется клиентским приложением до создания контекста формы и до выполнения любых серверных или клиентских обработчиков (таких как ПриСозданииНаСервере или ПриОткрытии). Платформа идентифицирует уникальность формы по комбинации нескольких параметров:

  1. Тип (имя) формы: например, ОбщаяФорма.Настройки.
  2. Значение параметра «Уникальность»: четвертый параметр глобального метода ОткрытьФорму.
  3. Владелец формы: форма или элемент управления, переданный вторым параметром.
  4. Значения ключевых параметров: параметры формы, для которых в конфигураторе взведен флаг «Ключевой параметр».

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

Способ 1. Единая точка программного открытия формы

Разберем основной и самый надежный способ обеспечения уникальности окна: открытие формы из всех точек системы (включая интерфейсные команды) через единую процедуру с фиксированным ключом уникальности.

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


Процедура ОткрытьФормуНастроек() Экспорт
    
    ПараметрыФормы = Новый Структура;
    КлючУникальности = "ОбщаяФормаНастройкиФиксированныйКлюч";
    
    // Платформа выполнит поиск открытой формы с указанным ключом.
    // Если форма уже открыта, метод активизирует её и вернет существующий объект УправляемаяФорма.
    ФормаНастроек = ОткрытьФорму("ОбщаяФорма.Настройки", ПараметрыФормы, , КлючУникальности);
    
КонецПроцедуры

В этом случае как первое открытие из пользовательского интерфейса, так и последующие программные вызовы будут использовать один и тот же ключ КлючУникальности, гарантируя работу с единственным экземпляром окна.

Способ 2. Использование ключевых параметров формы

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

  1. Откроем нужную управляемую форму в конфигураторе и перейдем на вкладку Параметры.
  2. Добавим новый параметр, например, ИдентификаторФормы с типом Строка.
  3. В свойствах добавленного параметра установим флаг Ключевой.
  4. При открытии формы передадим значение этого параметра в структуру:

ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ИдентификаторФормы", "ОдиночныйЭкземплярНастроек");

Форма = ОткрытьФорму("ОбщаяФорма.Настройки", ПараметрыФормы);

Так как параметр помечен как ключевой, платформа автоматически сформирует внутренний ключ уникальности на основании переданного значения и предотвратит открытие дублирующих окон.

Способ 3. Передача данных через механизм оповещений (рекомендуемый подход)

Часто получение объекта открытой формы требуется только для того, чтобы передать в нее обновленные данные, полученные из внешнего сервиса или другого модуля. В управляемом интерфейсе прямое манипулирование контекстом открытой формы снаружи считается плохой практикой из-за строгой изоляции клиент-серверного контекста. Разберем, как решить задачу через механизм оповещений.

Шаг 1. В модуле обычного приложения или общем модуле после получения данных отправляем системное оповещение:


// Отправка события всем открытым клиентским окнам
СтруктураДанных = Новый Структура("Статус, Данные", Истина, ПолученныеДанные);
Оповестить("ОбновлениеДанныхВнешнегоРесурса", СтруктураДанных, "МодульОбычногоПриложения");

Шаг 2. В модуле управляемой формы объявляем обработчик события оповещения:


&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
    
    Если ИмяСобытия = "ОбновлениеДанныхВнешнегоРесурса" Тогда
        // Обрабатываем полученные данные непосредственно в контексте формы
        ЗаполнитьДанныеФормы(Параметр.Данные);
    КонецЕсли;
    
КонецПроцедуры

Преимущество данного способа заключается в полной независимости компонентов: коду отправки данных не требуется знать, открыта ли форма в данный момент, какой у нее ключ уникальности и как именно устроена её внутренняя структура элементов.

Ограничения при работе с управляемыми формами в обычном приложении

Проанализируем важные системные ограничения платформы, о которых следует помнить:

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