Разработка и Конфигурация · 11 мин
Как найти открытую форму 1С программно
Разбираем, как программно найти открытую форму в 1С: поиск по ключу уникальности, обход окон, глобальный контекст. Примеры кода, типичные ошибки и FAQ.
При разработке на платформе 1С нередко возникает задача: прежде чем открывать форму документа или справочника, проверить — а не открыта ли она уже у пользователя. Если такая форма существует, логичнее активировать её, а не плодить дубликаты окон. Платформа предоставляет для этого несколько механизмов, и выбор конкретного зависит от режима работы (обычное или управляемое приложение) и от того, что именно нужно найти.
Ключевые инструменты — это метод ОткрытьЗначение() с автоматическим поиском, функция ОткрытьФорму() с параметром уникальности, а также перебор открытых окон через ПолучитьОкна() в обычном приложении. В управляемом приложении прямого перебора всех форм нет, и поиск строится вокруг ключа уникальности формы.
Важно понимать: платформа не даёт универсальной функции вида «найти форму по имени». Вместо этого используется идеология «открыть, а если уже открыто — активировать». Это сделано намеренно, чтобы избежать гонок состояний и дублирования окон. Ниже разберём все рабочие подходы с примерами кода.
Как устроен поиск форм в управляемом приложении
В тонком и веб-клиенте каждая открытая форма имеет ключ уникальности. Если при вызове ОткрытьФорму() передать ключ, совпадающий с ключом уже открытой формы, платформа не создаст новый экземпляр, а активирует существующий и вернёт ссылку на него. Именно это поведение используется как основной способ «найти» форму.
Ключ уникальности можно задать самостоятельно — строкой, ссылкой на объект или любым другим сериализуемым значением. Если ключ не задан, платформа формирует его автоматически: например, для формы элемента справочника ключом фактически служит ссылка на элемент, поэтому дважды открыть одну и ту же карточку стандартным способом не получится.
Поиск формы через ОткрытьФорму() с ключом уникальности
Самый надёжный и рекомендуемый приём: при открытии формы всегда передавать осмысленный ключ уникальности. Тогда для «поиска» достаточно повторно вызвать ОткрытьФорму() с тем же ключом и проверить результат — вернётся существующая форма или создастся новая.
// Открываем форму с собственным ключом уникальности
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Ключ", ТекущаяСсылка);
Форма = ОткрытьФорму("Справочник.Номенклатура.Форма.ФормаЭлемента",
ПараметрыФормы, , ТекущаяСсылка.УникальныйИдентификатор());
// Если форма с таким ключом уже была открыта,
// платформа активирует её и вернёт существующий экземпляр
Чтобы отличить «нашли существующую» от «создали новую», можно передать в параметрах флаг и проверить его в обработчике ПриСозданииНаСервере формы, либо сравнить состояние формы после вызова. На практике чаще всего различать эти случаи не требуется — важен сам факт, что дубликат окна не появится.
Ограничения подхода
Способ работает, только если вы контролируете код открытия формы и заранее назначаете ключи. Если форма открыта платформой или чужим кодом с автоматическим ключом, угадать его невозможно. Поэтому в расширениях и доработках принято централизовать открытие форм через общий модуль, где ключи назначаются единообразно.
Активация уже открытой формы объекта через ОткрытьЗначение()
Для объектных данных (документов, элементов справочников) есть ещё более простой вариант — глобальный метод ОткрытьЗначение(). Он открывает стандартную форму объекта, а если такая форма уже открыта в сеансе — активирует её вместо создания дубликата.
// Если карточка документа уже открыта — она активируется,
// если нет — откроется новая
ОткрытьЗначение(ДокументСсылка);
Этот метод удобен в обработчиках нажатия на ссылку, в отчётах и в любых местах, где нужно «показать объект пользователю». Минус — вы не управляете параметрами открытия и не получаете ссылку на форму как объект для дальнейшей работы.
Перебор открытых окон в обычном приложении
В обычном приложении (толстый клиент, режим обычных форм) доступен прямой перебор окон главного окна через метод ПолучитьОкна(). Это позволяет найти форму по заголовку, типу или содержимому.
Окна = ПолучитьОкна();
Для Каждого Окно Из Окна Цикл
Если Окно = Неопределено Или Окно.ПолучитьСодержимое() = Неопределено Тогда
Продолжить;
КонецЕсли;
Содержимое = Окно.ПолучитьСодержимое();
Если ТипЗнч(Содержимое) = Тип("Форма")
И Найти(Окно.Заголовок, "Номенклатура") > 0 Тогда
Окно.Активизировать();
Прервать;
КонецЕсли;
КонецЦикла;
У формы в обычном приложении также есть свойство КлючУникальности, и работает метод ОткрытьФорму() с похожей логикой. Дополнительно можно хранить ссылки на открытые формы в структуре или соответствии в модуле, если нужен точный контроль.
Поиск формы среди открытых через обработчики и уведомления
Когда нужно не просто активировать форму, а передать ей данные или проверить её состояние, используют механизм оповещений. Форма при открытии подписывается на оповещение через Оповестить() и ОбработкаОповещения(), а инициатор рассылает событие — все открытые формы, которые его обрабатывают, получат сообщение.
// В форме-приёмнике
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "ОбновитьСписокЗаказов" Тогда
Элементы.Список.Обновить();
КонецЕсли;
КонецПроцедуры
// В форме-инициаторе
Оповестить("ОбновитьСписокЗаказов", Неопределено, ЭтотОбъект);
Такой подход заменяет прямой поиск: вместо того чтобы «найти форму и дёрнуть её метод», вы сообщаете всем заинтересованным формам о событии. Это устойчивее к ошибкам — не нужно хранить ссылки, нет риска обратиться к уже закрытой форме.
Хранение ссылок на формы вручную
Если требуется именно прямой доступ к открытой форме (например, вызвать её экспортный метод), ссылку на форму можно сохранить при открытии в переменной модуля или параметре сеанса на клиенте. Перед обращением обязательно проверяйте, что форма ещё открыта — через Форма.Открыта():
Если Не СохраненнаяФорма = Неопределено И СохраненнаяФорма.Открыта() Тогда
СохраненнаяФорма.Активизировать();
Иначе
СохраненнаяФорма = ОткрытьФорму("Обработка.Монитор.Форма.ФормаМонитора");
КонецЕсли;
- 1Определите, что будет ключом уникальности: ссылка на объект, строка-идентификатор или GUID
- 2Передайте ключ в ОткрытьФорму() четвёртым параметром при первом открытии
- 3Для «поиска» повторно вызовите ОткрытьФорму() с тем же ключом — вернётся существующая форма или создастся новая
- 4Если нужно передать данные в уже открытую форму — используйте Оповестить() с уникальным именем события
- 5Проверьте результат: повторный вызов не должен создавать второе окно с тем же содержимым
Типичные ошибки при поиске открытых форм
Самая частая ошибка — попытка найти форму по её заголовку или имени в управляемом приложении. Такого API нет, и обходные пути через анализ окон ОС нестабильны и не переносимы между клиентами. Правильный путь — проектировать открытие форм с ключами уникальности с самого начала.
Вторая ошибка — обращение к сохранённой ссылке на форму без проверки Открыта(). Если пользователь закрыл окно, вызов методов формы приведёт к исключению. Третья — использование одинаковых ключей для логически разных форм: например, если всем формам элемента назначить ключ «Элемент», вторая карточка никогда не откроется — будет активироваться первая.
Проверка результата и выбор подхода
Признак корректной работы механизма: при повторном выполнении кода открытия количество окон не растёт, а уже открытая форма выходит на передний план. Проверить это просто — выполните открытие дважды подряд и посмотрите на панель окон. Если появилось два одинаковых окна, значит ключи уникальности не совпадают или не заданы.
Как проверить результат
Существующее окно активируется, новое не создаётся
Открывается второе окно с тем же содержимым — ключи не совпадают
Вызов Открыта() возвращает Истина, методы формы выполняются
Исключение при вызове — форма закрыта, ссылка неактуальна
ОбработкаОповещения срабатывает во всех открытых формах-подписчиках
Событие не доходит — проверьте точное совпадение имени события и источника
Сравнение способов поиска формы
Основной способ в управляемом приложении. Требует контроля над кодом открытия; не найдёт форму, открытую без ключа
Простейший вариант для объектных ссылок. Не даёт доступа к форме как объекту и не позволяет передать параметры
Только обычное приложение. Прямой перебор окон, но не работает в тонком и веб-клиенте
Не поиск, а рассылка события всем открытым формам. Подходит для обновления данных, но не для активации конкретного окна
Выбор зависит от задачи: для активации карточки объекта достаточно ОткрытьЗначение(), для независимых форм (обработок, мониторов) — собственный ключ уникальности, для обмена данными между формами — оповещения. Комбинировать подходы нормально: например, ключ уникальности для предотвращения дублей плюс оповещение для обновления содержимого.
Что важно запомнить
Отдельной функции поиска открытой формы в 1С нет. В управляемом приложении «поиск» — это повторный вызов ОткрытьФорму() с тем же ключом уникальности: форма либо активируется, либо создаётся. В обычном приложении доступен перебор через ПолучитьОкна(). Для передачи данных между открытыми формами используйте оповещения, а при хранении ссылок на формы всегда проверяйте Открыта().
Частые вопросы
Есть ли в 1С функция «НайтиОткрытуюФорму»?
Нет, такой встроенной функции платформа не предоставляет. Роль поиска выполняет механизм ключей уникальности: повторный вызов ОткрытьФорму() с тем же ключом возвращает уже открытый экземпляр. В обычном приложении дополнительно доступен перебор окон через ПолучитьОкна().
Как найти форму, открытую без ключа уникальности?
В управляемом приложении напрямую — никак. Платформа сама назначает такой форме внутренний ключ, узнать его извне нельзя. Практическое решение — перенести все места открытия этой формы в общий модуль и назначать ключ централизованно, после чего поиск станет возможен.
Как проверить, открыта ли форма, ссылка на которую сохранена в переменной?
Вызовите метод формы Открыта() — он вернёт Истина, если окно ещё существует. Обращаться к другим свойствам и методам формы без этой проверки нельзя: если пользователь закрыл окно, произойдёт исключение.
Почему ОткрытьФорму() с ключом всё равно создаёт второе окно?
Чаще всего ключи фактически различаются: например, в одном месте передаётся ссылка, а в другом — её уникальный идентификатор или строковое представление. Проверьте, что тип и значение ключа совпадают во всех точках открытия. Также убедитесь, что форма открывается в том же сеансе и окне-владельце.
Можно ли найти открытую форму другого пользователя?
Нет. Открытые формы существуют только в контексте клиентского сеанса, и ни один механизм платформы не даёт доступа к формам чужого сеанса. Для взаимодействия между пользователями используются другие средства — например, регистрация событий в базе или система взаимодействий.
Как передать данные в уже открытую форму, не закрывая её?
Используйте Оповестить() с уникальным именем события, а в целевой форме реализуйте ОбработкаОповещения с проверкой этого имени. Если ссылка на форму сохранена, можно напрямую вызвать её экспортный клиентский метод, предварительно проверив Открыта().