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

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

Как установить курсор в 1С программно

Как программно установить курсор в 1С: метод Активизировать, ТекущаяСтрока таблицы формы, позиционирование в динамическом списке и табличном документе. Примеры кода.

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

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

Ниже разобраны рабочие способы позиционирования для основных сценариев: табличные части, динамические списки, поля ввода и табличные документы, а также типичные ошибки, из-за которых курсор «не встаёт» куда нужно.

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

В управляемом приложении нет прямого доступа к экранным координатам и «каретке». Форма — это декларативное описание, а фокусом управляет платформа. Разработчику доступны два рычага: свойство ТекущийЭлемент объекта УправляемаяФорма и свойство ТекущаяСтрока у элементов типа «Таблица формы».

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

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

Перевод фокуса на элемент формы

Чтобы установить курсор в конкретное поле ввода — например, после открытия формы сразу перевести фокус на поле «Контрагент», — используется присваивание свойству ТекущийЭлемент:

&НаКлиенте

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

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

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

Альтернатива — метод Активизировать() у элемента формы. Он доступен на клиенте и делает то же самое: Элементы.Контрагент.Активизировать();. В обычных формах это основной способ.

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

Установка курсора на строку табличной части

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

&НаКлиенте

Процедура СпозиционироватьсяНаСтроке(Команда)

Строки = Объект.Товары.НайтиСтроки(Новый Структура("Номенклатура", ИскомаяНоменклатура));

Если Строки.Количество() > 0 Тогда

Элементы.Товары.ТекущаяСтрока = Строки[0].ПолучитьИдентификатор();

Элементы.Товары.Активизировать();

КонецЕсли;

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

Обратите внимание: передаётся не индекс строки (0, 1, 2...), а именно идентификатор — внутреннее число, которое платформа назначает строке коллекции. Индекс и идентификатор совпадают не всегда, особенно после удаления строк, поэтому использование индекса — распространённая ошибка.

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

Порядок действий
  1. 1
    Найдите нужную строку методом НайтиСтроки() или перебором коллекции
  2. 2
    Получите её идентификатор: Строка.ПолучитьИдентификатор()
  3. 3
    Присвойте идентификатор свойству Элементы.ИмяТаблицы.ТекущаяСтрока
  4. 4
    Вызовите Элементы.ИмяТаблицы.Активизировать(), чтобы таблица получила фокус
  5. 5
    Проверьте визуально: строка подсвечена и видима в области прокрутки

Позиционирование в динамическом списке и форме выбора

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

&НаКлиенте

Процедура ОткрытьСписокСПозицией(Команда)

ПараметрыФормы = Новый Структура;

ПараметрыФормы.Вставить("ТекущаяСтрока", ТекущаяНоменклатура);

ОткрытьФорму("Справочник.Номенклатура.ФормаСписка", ПараметрыФормы);

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

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

&НаКлиенте

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

Если ЗначениеЗаполнено(НужнаяСсылка) Тогда

Элементы.Список.ТекущаяСтрока = НужнаяСсылка;

КонецЕсли;

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

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

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

Курсор в поле ввода и табличном документе

Выделение текста в поле ввода

Для полей ввода можно не только установить фокус, но и выделить часть текста. Это делается через метод УстановитьГраницыВыделения() элемента формы:

Элементы.Комментарий.Активизировать();

Элементы.Комментарий.УстановитьГраницыВыделения(1, 10);

Метод принимает позиции начала и конца выделения (нумерация с единицы). Если позиции совпадают, устанавливается просто текстовый курсор в указанное место. Учтите, что метод доступен только на клиенте и работает для полей, редактирующих строковые данные.

Табличный документ

При выводе отчётов в табличный документ курсор устанавливается через свойство ТекущаяОбласть элемента формы «Поле табличного документа»:

Элементы.Результат.ТекущаяОбласть = Результат.Область("R10C3");

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

bsl
Найденная = Результат.НайтиТекст("Итого", , , Истина);
Если Найденная <> Неопределено Тогда
	Элементы.Результат.ТекущаяОбласть = Найденная;
КонецЕсли;

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

Главный признак корректной установки курсора — строка визуально подсвечена и находится в видимой области таблицы, а ожидаемое поле имеет фокус ввода. Если позиционирование «молча» не сработало, проверяйте по порядку: тип переданного значения, наличие строки в данных, состояние отборов и момент вызова кода.

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

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

Тип значения для ТекущаяСтрока
Норма

Идентификатор (число) для данных формы, ссылка для динамического списка

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

Индекс строки или ссылка в таблице данных формы

Наличие строки в данных
Норма

Строка присутствует при текущих отборах

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

Отбор или отбор компоновки исключает запись

Момент вызова
Норма

Код выполняется на клиенте после создания формы

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

Установка фокуса в серверной процедуре

Видимость элемента
Норма

Элемент видим, доступен, страница активна

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

Элемент на скрытой странице или недоступен

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

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

Ограничения и особенности платформы

Управление курсором целиком клиентская операция. Любая логика позиционирования должна выполняться в директивах &НаКлиенте или &НаКлиентеНаСервереБезКонтекста не подойдут — серверный код не имеет доступа к элементам формы как к объектам интерфейса.

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

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

Итог

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

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

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

Как установить курсор на последнюю строку табличной части?

Найдите последний элемент коллекции: Строка = Объект.Товары[Объект.Товары.Количество() - 1];, затем присвойте Элементы.Товары.ТекущаяСтрока = Строка.ПолучитьИдентификатор();. Предварительно проверьте, что коллекция не пуста, иначе обращение по индексу вызовет ошибку.

Почему ТекущаяСтрока присваивается, но строка не выделяется?

Наиболее вероятные причины: в динамическом списке действует отбор, исключающий запись; строка находится в свёрнутой группе иерархического списка; таблица формы не имеет фокуса. Снимите отборы, разверните узел методом Развернуть() и вызовите Активизировать() у таблицы.

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

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

Как спозиционировать курсор в списке документов на конкретном документе?

Передайте в форму списка параметр ТекущаяСтрока со ссылкой на документ: ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаСписка", Новый Структура("ТекущаяСтрока", СсылкаНаДокумент));. Стандартная форма списка обработает параметр автоматически.

Работает ли УстановитьГраницыВыделения в многострочных полях?

Да, метод работает и для многострочных полей ввода, позиции отсчитываются от начала всего текста с учётом символов переноса строк. Учтите, что точное поведение с переводами строк может различаться между клиентами, поэтому сложные сценарии стоит проверять в целевом окружении.

Чем отличается Активизировать() от присваивания ТекущийЭлемент?

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