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