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