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

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

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

Почему стандартный поиск через ПолучитьФорму() не работает как ожидается

Рассмотрим частую ошибку, с которой сталкиваются разработчики при попытке вручную отследить состояние формы:


Форма = ПолучитьФорму("ОбщаяФорма.Форма");
Форма.РежимОткрытияОкна = РежимОткрытияОкнаФормы.БлокироватьОкноВладельца;

Если Форма.Открыта() Тогда
    Форма.Активизировать();
Иначе 
    Форма.Открыть();
КонецЕсли;

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

Основной способ: использование метода ОткрытьФорму с ключом уникальности

Платформа 1С:Предприятие по умолчанию умеет находить и активизировать уже открытые формы. Для ссылочных объектов (элементов справочников, документов) ключом уникальности служит сама ссылка на объект. Однако при программном открытии общих форм, форм обработок или отчетов необходимо явно управлять параметром уникальности.

Синтаксис метода выглядит следующим образом:

ОткрытьФорму(ИмяФормы, Параметры, Владелец, Уникальность, Окно, НавигационнаяСсылка, ОписаниеОповещенияОЗакрытии, РежимОткрытияОкна)

Разберем значения параметра Уникальность:

  1. Ложь или не указан — платформа использует стандартный алгоритм поиска (для записанных объектов — по их ссылке).
  2. Истина — принудительно создается и открывается новое независимое окно, даже если аналогичная форма уже существует.
  3. Произвольное значение (строка, ссылка, УникальныйИдентификатор) — платформа выполняет поиск открытой формы с точно таким же значением ключа уникальности. Если форма найдена, она активизируется, а новый экземпляр не создается.

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


// Открываем форму с фиксированным строковым ключом уникальности
КлючФормы = "МояУникальнаяОбщаяФорма";
ОткрытьФорму("ОбщаяФорма.Форма", , , КлючФормы);

Если вызвать этот код повторно, платформа не станет создавать дубликат, а переведет фокус на ранее открытое окно.

Важные нюансы: параметр Владелец и работа с новыми объектами

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

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

Обработка повторного открытия в коде самой формы

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

Обратите внимание на различия между типами форм:

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

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


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

Альтернативный вариант: поиск формы через коллекцию окон

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


ОкнаКлиента = ПолучитьОкна();

Для Каждого Окно Из ОкнаКлиента Цикл
    Контент = Окно.ПолучитьСодержимое();
    Если ТипЗнч(Контент) = Тип("УправляемаяФорма") Тогда
        Если Контент.ИмяФормы = "ОбщаяФорма.Форма" Тогда
            Окно.Активизировать();
            Прервать;
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

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

← На главную