К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как найти открытую форму 1С программно

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

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

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

Важно понимать: платформа не даёт универсальной функции вида «найти форму по имени». Вместо этого используется идеология «открыть, а если уже открыто — активировать». Это сделано намеренно, чтобы избежать гонок состояний и дублирования окон. Ниже разберём все рабочие подходы с примерами кода.

Как устроен поиск форм в управляемом приложении

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

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

Поиск формы через ОткрытьФорму() с ключом уникальности

Самый надёжный и рекомендуемый приём: при открытии формы всегда передавать осмысленный ключ уникальности. Тогда для «поиска» достаточно повторно вызвать ОткрытьФорму() с тем же ключом и проверить результат — вернётся существующая форма или создастся новая.

// Открываем форму с собственным ключом уникальности

ПараметрыФормы = Новый Структура;

ПараметрыФормы.Вставить("Ключ", ТекущаяСсылка);

Форма = ОткрытьФорму("Справочник.Номенклатура.Форма.ФормаЭлемента",

ПараметрыФормы, , ТекущаяСсылка.УникальныйИдентификатор());

// Если форма с таким ключом уже была открыта,

// платформа активирует её и вернёт существующий экземпляр

Чтобы отличить «нашли существующую» от «создали новую», можно передать в параметрах флаг и проверить его в обработчике ПриСозданииНаСервере формы, либо сравнить состояние формы после вызова. На практике чаще всего различать эти случаи не требуется — важен сам факт, что дубликат окна не появится.

Ограничения подхода

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

Активация уже открытой формы объекта через ОткрытьЗначение()

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

// Если карточка документа уже открыта — она активируется,

// если нет — откроется новая

ОткрытьЗначение(ДокументСсылка);

Этот метод удобен в обработчиках нажатия на ссылку, в отчётах и в любых местах, где нужно «показать объект пользователю». Минус — вы не управляете параметрами открытия и не получаете ссылку на форму как объект для дальнейшей работы.

Перебор открытых окон в обычном приложении

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

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

Для Каждого Окно Из Окна Цикл

Если Окно = Неопределено Или Окно.ПолучитьСодержимое() = Неопределено Тогда

Продолжить;

КонецЕсли;

Содержимое = Окно.ПолучитьСодержимое();

Если ТипЗнч(Содержимое) = Тип("Форма")

И Найти(Окно.Заголовок, "Номенклатура") > 0 Тогда

Окно.Активизировать();

Прервать;

КонецЕсли;

КонецЦикла;

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

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

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

// В форме-приёмнике

&НаКлиенте

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)

Если ИмяСобытия = "ОбновитьСписокЗаказов" Тогда

Элементы.Список.Обновить();

КонецЕсли;

КонецПроцедуры

// В форме-инициаторе

Оповестить("ОбновитьСписокЗаказов", Неопределено, ЭтотОбъект);

Такой подход заменяет прямой поиск: вместо того чтобы «найти форму и дёрнуть её метод», вы сообщаете всем заинтересованным формам о событии. Это устойчивее к ошибкам — не нужно хранить ссылки, нет риска обратиться к уже закрытой форме.

Хранение ссылок на формы вручную

Если требуется именно прямой доступ к открытой форме (например, вызвать её экспортный метод), ссылку на форму можно сохранить при открытии в переменной модуля или параметре сеанса на клиенте. Перед обращением обязательно проверяйте, что форма ещё открыта — через Форма.Открыта():

Если Не СохраненнаяФорма = Неопределено И СохраненнаяФорма.Открыта() Тогда

СохраненнаяФорма.Активизировать();

Иначе

СохраненнаяФорма = ОткрытьФорму("Обработка.Монитор.Форма.ФормаМонитора");

КонецЕсли;

Порядок действий для управляемого приложения
  1. 1
    Определите, что будет ключом уникальности: ссылка на объект, строка-идентификатор или GUID
  2. 2
    Передайте ключ в ОткрытьФорму() четвёртым параметром при первом открытии
  3. 3
    Для «поиска» повторно вызовите ОткрытьФорму() с тем же ключом — вернётся существующая форма или создастся новая
  4. 4
    Если нужно передать данные в уже открытую форму — используйте Оповестить() с уникальным именем события
  5. 5
    Проверьте результат: повторный вызов не должен создавать второе окно с тем же содержимым

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

Самая частая ошибка — попытка найти форму по её заголовку или имени в управляемом приложении. Такого API нет, и обходные пути через анализ окон ОС нестабильны и не переносимы между клиентами. Правильный путь — проектировать открытие форм с ключами уникальности с самого начала.

Вторая ошибка — обращение к сохранённой ссылке на форму без проверки Открыта(). Если пользователь закрыл окно, вызов методов формы приведёт к исключению. Третья — использование одинаковых ключей для логически разных форм: например, если всем формам элемента назначить ключ «Элемент», вторая карточка никогда не откроется — будет активироваться первая.

Типичные ошибки
01
Перенос кода с ПолучитьОкна() в управляемое приложение — метод там недоступен, код падает с ошибкой
02
Обращение к сохранённой форме без проверки Открыта() — исключение, если пользователь закрыл окно
03
Одинаковый ключ уникальности для разных объектов — вторая форма не открывается, активируется первая
04
Разные ключи для одной и той же формы в разных местах кода — дубликаты окон, которых вы пытались избежать
05
Поиск формы по заголовку окна — заголовок может меняться и локализоваться, поиск ненадёжен

Проверка результата и выбор подхода

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

Контрольные точки

Как проверить результат

Повторный вызов ОткрытьФорму() с тем же ключом
Норма

Существующее окно активируется, новое не создаётся

Тревожный признак

Открывается второе окно с тем же содержимым — ключи не совпадают

Обращение к сохранённой ссылке на форму
Норма

Вызов Открыта() возвращает Истина, методы формы выполняются

Тревожный признак

Исключение при вызове — форма закрыта, ссылка неактуальна

Оповещение между формами
Норма

ОбработкаОповещения срабатывает во всех открытых формах-подписчиках

Тревожный признак

Событие не доходит — проверьте точное совпадение имени события и источника

Сравнение способов поиска формы

ОткрытьФорму() с ключом уникальности

Основной способ в управляемом приложении. Требует контроля над кодом открытия; не найдёт форму, открытую без ключа

ОткрытьЗначение()

Простейший вариант для объектных ссылок. Не даёт доступа к форме как объекту и не позволяет передать параметры

ПолучитьОкна()

Только обычное приложение. Прямой перебор окон, но не работает в тонком и веб-клиенте

Оповестить() / ОбработкаОповещения

Не поиск, а рассылка события всем открытым формам. Подходит для обновления данных, но не для активации конкретного окна

Выбор зависит от задачи: для активации карточки объекта достаточно ОткрытьЗначение(), для независимых форм (обработок, мониторов) — собственный ключ уникальности, для обмена данными между формами — оповещения. Комбинировать подходы нормально: например, ключ уникальности для предотвращения дублей плюс оповещение для обновления содержимого.

Итог

Что важно запомнить

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

Частые вопросы

Есть ли в 1С функция «НайтиОткрытуюФорму»?

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

Как найти форму, открытую без ключа уникальности?

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

Как проверить, открыта ли форма, ссылка на которую сохранена в переменной?

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

Почему ОткрытьФорму() с ключом всё равно создаёт второе окно?

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

Можно ли найти открытую форму другого пользователя?

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

Как передать данные в уже открытую форму, не закрывая её?

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