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

· 9 мин

Содержание

Чтобы программно активировать поле ввода в 1С, присвойте форме свойство ТекущийЭлемент: ЭтаФорма.ТекущийЭлемент = Элементы.Количество; — курсор сразу перейдёт в это поле. Это и есть программная активация: фокус ставится кодом, а не щелчком мыши.

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

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

Ставим фокус: свойство ТекущийЭлемент

Активное поле в управляемой форме — это значение свойства ТекущийЭлемент. Чтобы перевести курсор в поле, присвойте этому свойству нужный элемент из коллекции Элементы:

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

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

📌 Что важно помнить:

  • 🎯 ТекущийЭлемент — свойство формы, а не элемента. Пишется один раз: ЭтаФорма.ТекущийЭлемент = ....
  • 🧩 Справа от знака равенства — ссылка на элемент: Элементы.ИмяПоля.
  • 👁 Поле должно быть видимым и доступным. На невидимый или отключённый элемент фокус не встанет, и ошибки не будет — просто ничего не произойдёт.

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

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

Элементы.ГруппаСтраницы.ТекущаяСтраница = Элементы.СтраницаДопустимо;
ЭтаФорма.ТекущийЭлемент = Элементы.Комментарий;

Иначе курсор уйдёт на скрытую вкладку, и пользователь его не увидит.

Где в коде включать активацию поля

Главная ошибка — поставить фокус не в том обработчике. Форма сначала создаётся на сервере, и только потом показывается на клиенте. До показа фокусу вставать некуда.

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

ПриОткрытии — клиент, форма уже на экране. Это правильное место для начального фокуса:

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    Если Не ЗначениеЗаполнено(Объект.Контрагент) Тогда
        ЭтаФорма.ТекущийЭлемент = Элементы.Контрагент;
    КонецЕсли;
КонецПроцедуры

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

&НаКлиенте
Процедура ВидОперацииПриИзменении(Элемент)
    Если Объект.ВидОперации = "Возврат" Тогда
        ЭтаФорма.ТекущийЭлемент = Элементы.ДокументОснование;
    КонецЕсли;
КонецПроцедуры

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

Управляем доступностью, видимостью и режимом «только просмотр»

«Активировать» часто значит не «поставить курсор», а «включить поле, чтобы в него можно было писать». За это отвечают три разных свойства, и путать их не стоит.

СвойствоЧто делаетВидно значениеМожно скопировать
Доступность = ЛожьПоле серое, в него нельзя встатьДаНет
ТолькоПросмотр = ИстинаПоле обычное, но ввод запрещёнДаДа
Видимость = ЛожьПоле исчезает с формыНетНет

Включить и отключить поле:

Элементы.Скидка.Доступность = Истина;   // поле активно, можно вводить
Элементы.Скидка.Доступность = Ложь;     // поле серое, недоступно

Спрятать и показать:

Элементы.ПричинаВозврата.Видимость = (Объект.ВидОперации = "Возврат");

Разница между Доступность и ТолькоПросмотр важна на практике. Если нужно, чтобы пользователь видел и мог выделить/скопировать значение, но не правил его — ставьте ТолькоПросмотр, а не Доступность. Отключённое через Доступность = Ложь поле нельзя даже выделить мышью, и это раздражает, когда из него хотят скопировать номер или сумму.

Доступность всей формы разом задаёт свойство формы ТолькоПросмотр:

ЭтаФорма.ТолькоПросмотр = Истина;   // вся форма открыта на чтение

Удобно для просмотра проведённых документов без риска случайной правки.

Делаем поле обязательным и подсвечиваем незаполненное

Активация часто идёт в паре с проверкой: подсветить поле и сразу перевести в него курсор, если его забыли заполнить.

Автоматическую подсветку даёт свойство реквизита «Проверка заполнения» (значение «Выдавать ошибку») в конфигураторе. Платформа сама подчеркнёт пустое поле красным при записи и вызове метода ПроверитьЗаполнение().

Для своей логики используйте объект СообщениеПользователю — он и подсвечивает поле, и ставит на него курсор по щелчку на тексте ошибки:

&НаКлиентеНаСервереБезКонтекста
Процедура СообщитьОбОшибкеПоля(Текст, ИмяПоля)
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = Текст;
    Сообщение.Поле  = ИмяПоля;
    Сообщение.Сообщить();
КонецПроцедуры

Вызов, например, перед записью:

Если Не ЗначениеЗаполнено(Объект.Количество) Тогда
    СообщитьОбОшибкеПоля("Заполните количество", "Объект.Количество");
    Отказ = Истина;
КонецЕсли;

В свойстве Поле указывается путь к данным: для реквизита объекта — "Объект.Количество", для реквизита формы — просто его имя. Для строки табличной части путь включает индекс строки: "Объект.Товары[0].Цена".

Когда сообщение формируется на сервере (например, в ОбработкаПроверкиЗаполнения или перед записью), и проверяется реквизит объекта, вызовите Сообщение.УстановитьДанные(ЭтотОбъект); — иначе платформа не привяжет подсветку к полю на форме.

Единое место для проверок у документа или справочника — обработчик ОбработкаПроверкиЗаполнения в модуле объекта. Он выполняется на сервере при записи и при вызове ПроверитьЗаполнение():

Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
    Если Объект.Скидка > 0 И Не ЗначениеЗаполнено(Объект.ОснованиеСкидки) Тогда
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Укажите основание скидки";
        Сообщение.Поле  = "ОснованиеСкидки";
        Сообщение.УстановитьДанные(ЭтотОбъект);
        Сообщение.Сообщить();
        Отказ = Истина;
    КонецЕсли;
КонецПроцедуры

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

Если хочется именно поставить курсор в проблемное поле сразу (а не ждать щелчка по ошибке), добавьте на клиенте, например в обработчике команды записи:

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

На клиенте запустить проверку всех обязательных реквизитов можно одной строкой: Если Не ПроверитьЗаполнение() Тогда Возврат; КонецЕсли;. Метод вернёт Ложь и сам подсветит все незаполненные поля, у которых в конфигураторе включена проверка заполнения.

Активируем ячейку и настраиваем навигацию по сложной форме

С таблицей свойства ТекущийЭлемент уже мало — нужно указать и строку, и колонку. Делается это в два-три шага.

  1. 📍 Задайте текущую строку по её идентификатору:
Элементы.Товары.ТекущаяСтрока = ИдентификаторСтроки;
  1. 🎯 Переведите фокус на колонку. Колонки таблицы — это тоже элементы формы с именами вида <ИмяТаблицы><ИмяКолонки>:
ЭтаФорма.ТекущийЭлемент = Элементы.ТоварыЦена;

Типичный сценарий — добавить строку и сразу встать в неё, чтобы пользователь продолжил ввод:

&НаКлиенте
Процедура ДобавитьСтрокуИАктивировать()
    НоваяСтрока = Объект.Товары.Добавить();
    Элементы.Товары.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();
    ЭтаФорма.ТекущийЭлемент = Элементы.ТоварыНоменклатура;
КонецПроцедуры

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

Если таблица лежит на скрытой закладке, сначала покажите закладку (см. первый раздел), иначе активная ячейка окажется за кадром.

На сложных формах с десятком полей важно, как курсор переходит по Enter и Tab. За это отвечает свойство элемента «Пропускать при вводе» (ПропускатьПриВводе): если у поля стоит Истина, при переходе по Enter оно пропускается. Так убирают из маршрута ввода служебные и расчётные поля:

Элементы.ИтогоСуммой.ПропускатьПриВводе = Истина;

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

Почему фокус не ставится: разбор типичных проблем

Код написан, а курсор не переходит. Почти всегда причина — в одном из нескольких мест. Прогоните свой случай по диагностике.

Диагностика: выберите симптом

Ещё две ловушки, которые легко пропустить:

  • 🔁 Если фокус ставится в ПриИзменении поля, а потом платформа сама уводит курсор дальше (например, из-за свойства «Пропускать при вводе» у соседнего элемента) — проверьте настройку ПропускатьПриВводе у соседних элементов.
  • 🧷 Присвоение ТекущийЭлемент в цикле или несколько раз подряд бессмысленно: сработает только последнее. Ставьте фокус один раз, в конце логики.

Когда программную активацию лучше не делать

Фокус кодом — инструмент, а не самоцель. Несколько случаев, когда от него стоит воздержаться.

  • 🚫 Насильно возвращать курсор в поле. Если на каждое неверное значение код снова и снова ставит фокус в одно поле, пользователь не может уйти с формы. Подсветите ошибку сообщением и дайте человеку решить самому.
  • 🚫 Ставить фокус при каждой перерисовке. В обработчиках, которые срабатывают часто (ПриИзменении множества полей), повторная установка ТекущийЭлемент сбивает ввод. Ставьте фокус по конкретному условию, а не на всякий случай.
  • 🚫 Отключать поле вместо скрытия, когда оно не нужно совсем. Если реквизит неприменим в этом сценарии, прячьте его через Видимость, а не оставляйте серым — так форма чище.

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

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

Обычные формы 8.1–8.2: коротко про отличие

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

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

Чем `ТекущийЭлемент` отличается от `АктивизироватьПоле`?
Отдельного метода АктивизироватьПоле в управляемой форме нет. Активным полем управляет свойство формы ТекущийЭлемент — присваиваете ему ссылку на элемент, и фокус переходит туда.
Можно ли поставить фокус сразу при создании документа?
Да, но делайте это в клиентском обработчике ПриОткрытии, а не в ПриСозданииНаСервере. На сервере форма ещё не отображена, и фокус может не встать.
Как сделать поле доступным только при определённом условии?
Присваивайте Элементы.Поле.Доступность выражение с условием — например, в обработчике ПриИзменении ведущего реквизита или один раз в ПриСозданииНаСервере для начального состояния.
Почему после `Доступность = Ложь` из поля нельзя скопировать текст?
Отключённое поле блокирует и выделение. Если значение должно оставаться копируемым, используйте ТолькоПросмотр = Истина вместо Доступность = Ложь.
Как встать в конкретную ячейку таблицы, а не просто выделить строку?
Сначала задайте ТекущаяСтрока таблицы по идентификатору строки, затем присвойте ЭтаФорма.ТекущийЭлемент элемент нужной колонки (Элементы.ТаблицаКолонка).