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