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

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

Как в 1С передать фокус форме и элементу формы

Как в 1С передать фокус форме или элементу: методы Активизировать, ТекущийЭлемент, особенности тонкого и веб-клиента, типичные ошибки и примеры кода.

Управление фокусом ввода — частая задача при доработке форм в 1С:Предприятии. Типичные сценарии: после открытия формы курсор должен стоять в поле поиска, после добавления строки в табличную часть — в колонке «Количество», а после ошибки проверки заполнения — в поле с некорректным значением. Всё это решается встроенными средствами платформы без внешних компонент.

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

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

Как активировать форму из другой формы

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

&НаКлиенте

Процедура ОткрытьОбработку(Команда)

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

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

Если Окно.Заголовок = "Моя обработка" Тогда

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

Возврат;

КонецЕсли;

КонецЦикла;

ОткрытьФорму("ВнешняяОбработка.МояОбработка.Форма");

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

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

Как установить фокус на элемент формы через ТекущийЭлемент

Свойство ТекущийЭлемент управляемой формы определяет, какой элемент в данный момент активен. Присвоив ему ссылку на элемент формы, вы передаёте фокус этому элементу. Классический сценарий — установка курсора в поле поиска при открытии формы списка.

&НаКлиенте

Процедура ПриОткрытии(Отказ)

ЭтаФорма.ТекущийЭлемент = Элементы.СтрокаПоиска;

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

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

Установка фокуса срабатывает не мгновенно: платформа применяет его после завершения текущего обработчика. Поэтому если в одной процедуре вы несколько раз присваиваете ТекущийЭлемент, фокус получит последний присвоенный элемент.

Порядок действий
  1. 1
    Убедитесь, что код выполняется в директиве &НаКлиенте
  2. 2
    Проверьте имя элемента в конфигураторе (свойство Имя)
  3. 3
    Присвойте ЭтаФорма.ТекущийЭлемент = Элементы.ИмяЭлемента
  4. 4
    Для поля ввода при необходимости вызовите НачатьВыборИзСписка или измените текст
  5. 5
    Откройте форму и проверьте, что курсор стоит в нужном поле

Как передать фокус в таблицу формы и на конкретную строку

Активация строки табличной части

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

&НаКлиенте

Процедура ПерейтиКСтроке(Команда)

ЭтаФорма.ТекущийЭлемент = Элементы.Товары;

Элементы.Товары.ТекущаяСтрока = НужнаяСтрокаИдентификатор;

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

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

Фокус на конкретную колонку при добавлении строки

Частая задача: после добавления строки в табличную часть курсор должен встать в колонку «Количество» или «Цена», минуя «Номенклатуру». Для этого в обработчике ПриНачалеРедактирования или ОбработкаВыбора таблицы устанавливается ТекущийЭлемент таблицы:

&НаКлиенте

Процедура ТоварыПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)

Если НоваяСтрока Тогда

Элементы.Товары.ТекущийЭлемент = Элементы.ТоварыКоличество;

КонецЕсли;

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

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

Типичные ошибки
01
Присваивание ТекущийЭлемент в серверной процедуре — код молча не работает
02
Использование имени реквизита данных вместо имени элемента формы — фокус не перемещается
03
Установка ТекущаяСтрока без установки ТекущийЭлемент таблицы — строка выделяется, но фокус остаётся в другом месте
04
Попытка установить фокус на невидимый или недоступный элемент — платформа игнорирует команду

Особенности работы в разных клиентах

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

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

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

Сравнение вариантов

Активизировать() формы/окна

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

ЭтаФорма.ТекущийЭлемент

Основной способ поставить курсор в поле ввода или на кнопку. Работает только на клиенте

ТекущаяСтрока + ТекущийЭлемент таблицы

Для таблиц: активирует строку и колонку. Требует правильного идентификатора строки

Проверка результата и отладка

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

&НаКлиенте

Процедура ПроверитьФокус(Команда)

Если ЭтаФорма.ТекущийЭлемент <> Неопределено Тогда

Сообщить("Активный элемент: " + ЭтаФорма.ТекущийЭлемент.Имя);

Иначе

Сообщить("Активного элемента нет");

КонецЕсли;

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

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

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

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

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

Поле подсвечено, можно сразу вводить текст

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

Фокус на первом элементе по порядку обхода — проверьте контекст (&НаКлиенте) и имя элемента

Активная строка таблицы
Норма

Нужная строка выделена и видима на экране

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

Строка не выделяется — неверный идентификатор или строка отфильтрована

Чтение ТекущийЭлемент после установки
Норма

Возвращает нужный элемент

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

Возвращает другой элемент — после вашего кода срабатывает ещё один обработчик

Ограничения и когда фокус передать нельзя

Нельзя установить фокус на элемент со свойством Доступность = Ложь или Видимость = Ложь — платформа проигнорирует команду. Если элемент становится доступным условно, сначала включите доступность, затем передавайте фокус.

Нельзя передать фокус в ещё не открытую форму: ТекущийЭлемент в обработчике ПриСозданииНаСервере не сработает, потому что элементы формы на клиенте ещё не созданы. Используйте ПриОткрытии на клиенте.

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

Практический пример: форма подбора с фокусом в поиске

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

&НаКлиенте

Процедура ПриОткрытии(Отказ)

ЭтаФорма.ТекущийЭлемент = Элементы.СтрокаПоиска;

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

&НаКлиенте

Процедура ДобавитьТовар(Команда)

// логика добавления товара

ЭтаФорма.ТекущийЭлемент = Элементы.СтрокаПоиска;

Элементы.СтрокаПоиска.ВыделенныйТекст = Элементы.СтрокаПоиска.ВыделенныйТекст;

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

Для поля ввода дополнительно полезно выделять введённый текст, чтобы следующее сканирование штрихкода автоматически заменяло предыдущее значение. Это делается через свойство ВыделенныйТекст или установку границ выделения.

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

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

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

Часто задаваемые вопросы

Почему присвоение ТекущийЭлемент не даёт эффекта?

Чаще всего код выполняется на сервере (&НаСервере или общий модуль без клиентского контекста), либо указано имя реквизита данных вместо имени элемента формы. Также проверьте, что элемент видим и доступен — фокус на скрытый элемент платформа не установит.

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

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

Как поставить фокус на кнопку, а не на поле ввода?

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

Как вернуть фокус в поле после закрытия диалога выбора?

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

Работает ли Активизировать() для окон в веб-клиенте?

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

Как узнать, какой элемент сейчас в фокусе?

Прочитайте свойство ЭтаФорма.ТекущийЭлемент на клиенте — оно вернёт активный элемент формы или Неопределено. У полученного элемента можно прочитать свойство Имя для диагностики.