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