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