Как установить фокус и активировать поле ввода в 1С кодом
Содержание
Чтобы программно активировать поле ввода в 1С, присвойте форме свойство ТекущийЭлемент: ЭтаФорма.ТекущийЭлемент = Элементы.Количество; — курсор сразу перейдёт в это поле. Это и есть программная активация: фокус ставится кодом, а не щелчком мыши.
Отдельного метода SetFocus, как в вебе, в платформе нет. Фокусом в управляемой форме 8.3 управляет одно свойство формы — ТекущийЭлемент указывает, какой элемент активен. Доступ к самому полю (включить, отключить, спрятать) — это уже другие свойства: Доступность, Видимость, ТолькоПросмотр.
Ниже разберём все случаи: как поставить фокус при открытии и в обработчиках, как управлять доступностью поля, как подсветить ошибку и перевести курсор на незаполненный реквизит, как активировать нужную ячейку в табличной части. Весь код — для управляемых форм 8.3; про обычные формы — оговорка в конце.
Ставим фокус: свойство ТекущийЭлемент
Активное поле в управляемой форме — это значение свойства ТекущийЭлемент. Чтобы перевести курсор в поле, присвойте этому свойству нужный элемент из коллекции Элементы:
ЭтаФорма.ТекущийЭлемент = Элементы.Количество;
Количество здесь — имя элемента формы, а не имя реквизита. Имена видно в дереве формы слева в конфигураторе, в ветке «Элементы». Они часто совпадают с реквизитом, но не обязаны: элемент можно переименовать, и в коде нужно именно имя элемента.
📌 Что важно помнить:
- 🎯
ТекущийЭлемент— свойство формы, а не элемента. Пишется один раз:ЭтаФорма.ТекущийЭлемент = .... - 🧩 Справа от знака равенства — ссылка на элемент:
Элементы.ИмяПоля. - 👁 Поле должно быть видимым и доступным. На невидимый или отключённый элемент фокус не встанет, и ошибки не будет — просто ничего не произойдёт.
Свойство работает и на чтение. Чтобы узнать, какое поле сейчас активно, обратитесь к тому же ЭтаФорма.ТекущийЭлемент — вернётся ссылка на текущий элемент формы. Это пригодится, когда поведение команды зависит от того, где стоит курсор: например, кнопка панели применяется к той колонке таблицы, в которой находится пользователь.
Если поле лежит в группе-странице (на закладке), сначала переключите закладку, а затем ставьте фокус. Активная страница группы задаётся так:
Элементы.ГруппаСтраницы.ТекущаяСтраница = Элементы.СтраницаДопустимо;
ЭтаФорма.ТекущийЭлемент = Элементы.Комментарий;
Иначе курсор уйдёт на скрытую вкладку, и пользователь его не увидит.
Где в коде включать активацию поля
Главная ошибка — поставить фокус не в том обработчике. Форма сначала создаётся на сервере, и только потом показывается на клиенте. До показа фокусу вставать некуда.
ПриСозданииНаСервере — сервер, форма ещё не отображена. Здесь настраивают доступность и видимость, заполняют начальные значения. Ставить ТекущийЭлемент тут можно, но не всегда срабатывает — поле ещё не нарисовано.
ПриОткрытии — клиент, форма уже на экране. Это правильное место для начального фокуса:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Если Не ЗначениеЗаполнено(Объект.Контрагент) Тогда
ЭтаФорма.ТекущийЭлемент = Элементы.Контрагент;
КонецЕсли;
КонецПроцедуры
Событие поля (ПриИзменении, Нажатие, Очистка) — тоже клиент. Фокус тут ставится без оговорок, форма уже активна:
&НаКлиенте
Процедура ВидОперацииПриИзменении(Элемент)
Если Объект.ВидОперации = "Возврат" Тогда
ЭтаФорма.ТекущийЭлемент = Элементы.ДокументОснование;
КонецЕсли;
КонецПроцедуры
Правило простое: всё, что связано с фокусом, делайте на клиенте и после открытия формы. На сервере задавайте доступность и видимость — их платформа применит при отрисовке.
Управляем доступностью, видимостью и режимом «только просмотр»
«Активировать» часто значит не «поставить курсор», а «включить поле, чтобы в него можно было писать». За это отвечают три разных свойства, и путать их не стоит.
| Свойство | Что делает | Видно значение | Можно скопировать |
|---|---|---|---|
Доступность = Ложь | Поле серое, в него нельзя встать | Да | Нет |
ТолькоПросмотр = Истина | Поле обычное, но ввод запрещён | Да | Да |
Видимость = Ложь | Поле исчезает с формы | Нет | Нет |
Включить и отключить поле:
Элементы.Скидка.Доступность = Истина; // поле активно, можно вводить
Элементы.Скидка.Доступность = Ложь; // поле серое, недоступно
Спрятать и показать:
Элементы.ПричинаВозврата.Видимость = (Объект.ВидОперации = "Возврат");
Разница между Доступность и ТолькоПросмотр важна на практике. Если нужно, чтобы пользователь видел и мог выделить/скопировать значение, но не правил его — ставьте ТолькоПросмотр, а не Доступность. Отключённое через Доступность = Ложь поле нельзя даже выделить мышью, и это раздражает, когда из него хотят скопировать номер или сумму.
Доступность всей формы разом задаёт свойство формы ТолькоПросмотр:
ЭтаФорма.ТолькоПросмотр = Истина; // вся форма открыта на чтение
Удобно для просмотра проведённых документов без риска случайной правки.
Делаем поле обязательным и подсвечиваем незаполненное
Активация часто идёт в паре с проверкой: подсветить поле и сразу перевести в него курсор, если его забыли заполнить.
Автоматическую подсветку даёт свойство реквизита «Проверка заполнения» (значение «Выдавать ошибку») в конфигураторе. Платформа сама подчеркнёт пустое поле красным при записи и вызове метода ПроверитьЗаполнение().
Для своей логики используйте объект СообщениеПользователю — он и подсвечивает поле, и ставит на него курсор по щелчку на тексте ошибки:
&НаКлиентеНаСервереБезКонтекста
Процедура СообщитьОбОшибкеПоля(Текст, ИмяПоля)
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = Текст;
Сообщение.Поле = ИмяПоля;
Сообщение.Сообщить();
КонецПроцедуры
Вызов, например, перед записью:
Если Не ЗначениеЗаполнено(Объект.Количество) Тогда
СообщитьОбОшибкеПоля("Заполните количество", "Объект.Количество");
Отказ = Истина;
КонецЕсли;
В свойстве Поле указывается путь к данным: для реквизита объекта — "Объект.Количество", для реквизита формы — просто его имя. Для строки табличной части путь включает индекс строки: "Объект.Товары[0].Цена".
Когда сообщение формируется на сервере (например, в ОбработкаПроверкиЗаполнения или перед записью), и проверяется реквизит объекта, вызовите Сообщение.УстановитьДанные(ЭтотОбъект); — иначе платформа не привяжет подсветку к полю на форме.
Единое место для проверок у документа или справочника — обработчик ОбработкаПроверкиЗаполнения в модуле объекта. Он выполняется на сервере при записи и при вызове ПроверитьЗаполнение():
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если Объект.Скидка > 0 И Не ЗначениеЗаполнено(Объект.ОснованиеСкидки) Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Укажите основание скидки";
Сообщение.Поле = "ОснованиеСкидки";
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Плюс такого подхода — проверка срабатывает и при интерактивной записи, и при программной. Поле подсветится красным автоматически, а по щелчку на тексте ошибки курсор перейдёт в него.
Если хочется именно поставить курсор в проблемное поле сразу (а не ждать щелчка по ошибке), добавьте на клиенте, например в обработчике команды записи:
ЭтаФорма.ТекущийЭлемент = Элементы.Количество;
На клиенте запустить проверку всех обязательных реквизитов можно одной строкой: Если Не ПроверитьЗаполнение() Тогда Возврат; КонецЕсли;. Метод вернёт Ложь и сам подсветит все незаполненные поля, у которых в конфигураторе включена проверка заполнения.
Активируем ячейку и настраиваем навигацию по сложной форме
С таблицей свойства ТекущийЭлемент уже мало — нужно указать и строку, и колонку. Делается это в два-три шага.
- 📍 Задайте текущую строку по её идентификатору:
Элементы.Товары.ТекущаяСтрока = ИдентификаторСтроки;
- 🎯 Переведите фокус на колонку. Колонки таблицы — это тоже элементы формы с именами вида
<ИмяТаблицы><ИмяКолонки>:
ЭтаФорма.ТекущийЭлемент = Элементы.ТоварыЦена;
Типичный сценарий — добавить строку и сразу встать в неё, чтобы пользователь продолжил ввод:
&НаКлиенте
Процедура ДобавитьСтрокуИАктивировать()
НоваяСтрока = Объект.Товары.Добавить();
Элементы.Товары.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();
ЭтаФорма.ТекущийЭлемент = Элементы.ТоварыНоменклатура;
КонецПроцедуры
Чтобы узнать идентификатор уже существующей строки, пройдите по коллекции и у нужного элемента вызовите .ПолучитьИдентификатор(). Текущие данные активной строки доступны через Элементы.Товары.ТекущиеДанные — удобно читать и менять значения прямо в обработчике.
Если таблица лежит на скрытой закладке, сначала покажите закладку (см. первый раздел), иначе активная ячейка окажется за кадром.
На сложных формах с десятком полей важно, как курсор переходит по Enter и Tab. За это отвечает свойство элемента «Пропускать при вводе» (ПропускатьПриВводе): если у поля стоит Истина, при переходе по Enter оно пропускается. Так убирают из маршрута ввода служебные и расчётные поля:
Элементы.ИтогоСуммой.ПропускатьПриВводе = Истина;
Порядок обхода задаётся не кодом, а деревом формы: Enter переходит к следующему видимому и доступному элементу по порядку. Хотите нестандартный маршрут — отключайте лишние поля из обхода ПропускатьПриВводе и располагайте элементы в нужной последовательности. Для табличной части это особенно удобно: пользователь заполняет только значимые колонки и не застревает на вычисляемых.
Почему фокус не ставится: разбор типичных проблем
Код написан, а курсор не переходит. Почти всегда причина — в одном из нескольких мест. Прогоните свой случай по диагностике.
Видимость = Ложь или Доступность = Ложь фокус не встаёт молча. Сначала сделайте поле видимым и доступным, потом ставьте ТекущийЭлемент.ТекущийЭлемент в клиентский обработчик ПриОткрытии или в событие элемента — форма должна быть уже отображена.Элементы.ИмяПоля указано имя реквизита, а не имя элемента формы, либо имя с опечаткой. Сверьте имя в дереве формы, ветка «Элементы».ТекущуюСтраницу группы, затем ставьте фокус.ТекущаяСтрока. Добавьте ЭтаФорма.ТекущийЭлемент = Элементы.<Таблица><Колонка>;, чтобы встать в конкретную колонку.Ещё две ловушки, которые легко пропустить:
- 🔁 Если фокус ставится в
ПриИзмененииполя, а потом платформа сама уводит курсор дальше (например, из-за свойства «Пропускать при вводе» у соседнего элемента) — проверьте настройкуПропускатьПриВводеу соседних элементов. - 🧷 Присвоение
ТекущийЭлементв цикле или несколько раз подряд бессмысленно: сработает только последнее. Ставьте фокус один раз, в конце логики.
Когда программную активацию лучше не делать
Фокус кодом — инструмент, а не самоцель. Несколько случаев, когда от него стоит воздержаться.
- 🚫 Насильно возвращать курсор в поле. Если на каждое неверное значение код снова и снова ставит фокус в одно поле, пользователь не может уйти с формы. Подсветите ошибку сообщением и дайте человеку решить самому.
- 🚫 Ставить фокус при каждой перерисовке. В обработчиках, которые срабатывают часто (
ПриИзменениимножества полей), повторная установкаТекущийЭлементсбивает ввод. Ставьте фокус по конкретному условию, а не на всякий случай. - 🚫 Отключать поле вместо скрытия, когда оно не нужно совсем. Если реквизит неприменим в этом сценарии, прячьте его через
Видимость, а не оставляйте серым — так форма чище.
Короткий ориентир: автоматический фокус оправдан при открытии (встать в первое незаполненное поле), после добавления строки в таблицу и при переключении режима операции. Во всех остальных случаях навигацию лучше отдать пользователю — он сам щёлкнет туда, куда нужно.
Отдельно про производительность: все эти свойства (Доступность, Видимость, ТолькоПросмотр, ТекущийЭлемент) работают с интерфейсом формы, их присвоение почти не нагружает систему. Выносить их на сервер ради скорости не нужно — наоборот, фокус ставится только на клиенте.
Обычные формы 8.1–8.2: коротко про отличие
Всё выше — про управляемые формы. В обычных (толстых) формах старых конфигураций обращение к элементам идёт через коллекцию ЭлементыФормы, а не Элементы, и набор свойств другой. Если вы ведёте разработку на управляемом приложении 8.3 (а это сейчас стандарт), ориентируйтесь на Элементы и ТекущийЭлемент. Переносить синтаксис обычных форм на управляемые нельзя — имена свойств и коллекций не совпадают.
Частые вопросы
Чем `ТекущийЭлемент` отличается от `АктивизироватьПоле`?
АктивизироватьПоле в управляемой форме нет. Активным полем управляет свойство формы ТекущийЭлемент — присваиваете ему ссылку на элемент, и фокус переходит туда.Можно ли поставить фокус сразу при создании документа?
ПриОткрытии, а не в ПриСозданииНаСервере. На сервере форма ещё не отображена, и фокус может не встать.Как сделать поле доступным только при определённом условии?
Элементы.Поле.Доступность выражение с условием — например, в обработчике ПриИзменении ведущего реквизита или один раз в ПриСозданииНаСервере для начального состояния.Почему после `Доступность = Ложь` из поля нельзя скопировать текст?
ТолькоПросмотр = Истина вместо Доступность = Ложь.Как встать в конкретную ячейку таблицы, а не просто выделить строку?
ТекущаяСтрока таблицы по идентификатору строки, затем присвойте ЭтаФорма.ТекущийЭлемент элемент нужной колонки (Элементы.ТаблицаКолонка).