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

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

1С: как получить открытые формы программно

Как в 1С получить список открытых форм и окон: методы ПолучитьОкна, АктивноеОкно, поиск формы по владельцу и ключу уникальности, примеры кода и типичные ошибки.

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

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

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

Как работает ПолучитьОкна() в обычном приложении

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

Типовой перебор выглядит так:

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

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

Сообщить(Окно.ПолучитьЗаголовок());

Для Каждого Форма Из Окно.Содержимое Цикл

Сообщить(Форма.ИмяФормы);

КонецЦикла;

КонецЦикла;

Через свойство Содержимое можно добраться до самой формы и, например, проверить, какой объект она редактирует, или вызвать её экспортные процедуры. Это удобно для поиска уже открытой формы конкретного документа.

Ограничение: метод не работает в управляемом приложении и на веб-клиенте. Если конфигурация переведена на управляемые формы, вызов ПолучитьОкна() приведёт к ошибке компиляции или выполнения.

bsl
Окна = ПолучитьОкна();
Для Каждого Окно Из Окна Цикл
    Для Каждого Форма Из Окно.Содержимое Цикл
        Сообщить(Форма.ИмяФормы);
    КонецЦикла;
КонецЦикла;

АктивноеОкно() и АктивнаяФорма()

Если нужна не вся коллекция, а только текущее окно, используйте АктивноеОкно(). Метод возвращает объект окна, которое сейчас активно, либо Неопределено, если активного окна нет. Через него можно получить форму: АктивноеОкно().Содержимое[0].

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

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

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

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

Первый — ключ уникальности. При вызове ОткрытьФорму() передайте параметр Уникальность — произвольное значение (строка, ссылка, УникальныйИдентификатор). Если форма с таким ключом уже открыта, платформа не создаст новую, а активирует существующую. Фактически это и есть «поиск открытой формы», встроенный в платформу.

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

ПараметрыФормы, , СсылкаНаЭлемент); // четвёртый параметр — Уникальность

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

Третий — метод ПолучитьФорму() с указанием ключа уникальности. Если форма с таким ключом уже существует, ПолучитьФорму() вернёт именно её, а не создаст новую:

Форма = ПолучитьФорму("Обработка.МояОбработка.Форма.ФормаНастроек",

, , "КлючНастроек");

Если Не Форма.Открыта() Тогда

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

Иначе

Форма.Активизировать();

КонецЕсли;

Поиск формы конкретного объекта

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

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

ОткрытьФорму("Обработка.ЗагрузкаДанных.Форма.ФормаЗагрузки",

, , "ЕдинственныйЭкземпляр");

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

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

Оповещения как альтернатива поиску форм

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

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

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

Сравнение подходов

ПолучитьОкна() + перебор

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

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

Управляемое приложение. Платформа сама находит и активирует форму, дубликатов нет

ПолучитьФорму() с ключом

Возвращает существующую форму, позволяет вызвать её методы до открытия

Оповестить() / ОповеститьОбИзменении()

Когда нужно не найти форму, а передать данные всем заинтересованным формам

Типичные ошибки и ограничения

Первая ошибка — попытка использовать ПолучитьОкна() в управляемом приложении. Код не скомпилируется: метод недоступен в этом режиме. Проверяйте директивы компиляции и режим работы конфигурации.

Вторая — сравнение форм по заголовку. Заголовок может меняться пользователем, локализацией и состоянием объекта. Надёжные признаки: ИмяФормы, ключ уникальности, ссылка на объект.

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

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

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

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

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

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

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

Повторное открытие формы
Норма

Активируется уже открытый экземпляр

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

Открывается вторая копия формы

Закрытие и повторное открытие
Норма

Форма открывается заново без ошибок

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

Ошибка обращения к закрытой форме

Режим клиента
Норма

Код работает в целевом режиме (обычный/управляемый)

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

Ошибка компиляции из-за недоступного метода

Итог

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

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

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

Можно ли в управляемом приложении получить список всех открытых форм?

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

Почему ПолучитьОкна() выдаёт ошибку «Метод объекта не обнаружен»?

Метод доступен только в обычном приложении (толстый клиент). Если конфигурация запускается в режиме управляемого приложения или код выполняется на тонком клиенте, вызов невозможен. Проверьте свойство конфигурации «Режим использования модальности» и «Основной режим запуска», а также директивы компиляции в модуле.

Как открыть форму, только если она ещё не открыта, а иначе активировать?

Передайте в ОткрытьФорму() четвёртым параметром значение Уникальность — например, ссылку на объект или фиксированную строку. Платформа сама проверит наличие формы с таким ключом: если она открыта, активирует её; если нет — создаст новую. Дополнительный код поиска не требуется.

Чем отличается ПолучитьФорму() от ОткрытьФорму()?

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

Как закрыть все открытые формы обработки при завершении работы?

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