Как зафиксировать фокус и активизировать ячейку табличного поля в 1С на обычных формах?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Торговля и дистрибуция
← На главную

При разработке интерфейсов на обычных формах 1С (например, в конфигурации «Управление торговлей 10.3») часто возникает задача валидации пользовательского ввода непосредственно в табличной части или табличном поле. Типичный сценарий: пользователь вводит значение в ячейку (например, адрес электронной почты), система проверяет его на корректность и, если найдена ошибка, должна предупредить пользователя и оставить курсор в этой же ячейке в режиме редактирования для исправления.

Однако при попытке реализовать такую логику в событии ПриИзменении разработчики сталкиваются с тем, что курсор все равно переходит в следующую колонку строки. Разберем причины такого поведения платформы и рассмотрим надежные способы решения задачи.

Почему не работает установка ТекущаяКолонка в событии ПриИзменении?

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

По этой причине прямое присвоение ЭлементыФормы.ТабличноеПоле.ТекущаяКолонка = НужнаяКолонка; внутри процедуры ПриИзменении просто перезаписывается последующим системным переходом платформы. Дополнительно ситуацию осложняет модальное окно Предупреждение(): оно перехватывает системный фокус, сбивая внутреннее состояние ввода ячейки.

Способ 1. Отложенный возврат фокуса через обработчик ожидания

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

Рассмотрим пошаговую реализацию этого алгоритма:

  1. В модуле формы объявим переменные для хранения позиции ошибочной ячейки.
  2. В событии ПриИзменении выполним проверку и подключим однократный обработчик ожидания.
  3. В вызываемой процедуре переведем фокус на табличное поле, установим текущую колонку и вызовем метод ИзменитьСтроку().

Посмотрим на пример программного кода модуля формы:


Перем мОшибочнаяСтрока;
Перем мОшибочнаяКолонка;

Процедура таблЭлектрПочтаКолонкаЭлектрПочтаПриИзменении(Элемент)
    
    ТекСтрока = ЭлементыФормы.таблЭлектрПочта.ТекущиеДанные;
    Если ТекСтрока = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    ТекЗначение = СокрЛП(ТекСтрока.КолонкаЭлектрПочта);
    
    Если Найти(ТекЗначение, " ") > 0 Тогда
        Сообщить("Адрес электронной почты не может содержать пробелы!", СтатусСообщения.Важное);
        
        // Сохраняем координаты ячейки
        мОшибочнаяСтрока = ТекСтрока;
        мОшибочнаяКолонка = ЭлементыФормы.таблЭлектрПочта.Колонки.КолонкаЭлектрПочта;
        
        // Подключаем однократный обработчик с минимальной задержкой
        ПодключитьОбработчикОжидания("ВернутьФокусВЯчейку", 0.1, Истина);
    КонецЕсли;

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

Процедура ВернутьФокусВЯчейку() Экспорт
    
    // Активизируем табличное поле на форме
    ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.таблЭлектрПочта;
    
    // Устанавливаем строку и колонку
    Если мОшибочнаяСтрока <> Неопределено Тогда
        ЭлементыФормы.таблЭлектрПочта.ТекущаяСтрока = мОшибочнаяСтрока;
    КонецЕсли;
    
    Если мОшибочнаяКолонка <> Неопределено Тогда
        ЭлементыФормы.таблЭлектрПочта.ТекущаяКолонка = мОшибочнаяКолонка;
    КонецЕсли;
    
    // Переводим ячейку в режим редактирования
    ЭлементыФормы.таблЭлектрПочта.ИзменитьСтроку();
    
    мОшибочнаяСтрока = Неопределено;
    мОшибочнаяКолонка = Неопределено;

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

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

Способ 2. Контроль корректности в событии ПередОкончаниемРедактирования

В платформе 1С штатным механизмом запрета перехода при невалидных данных является событие табличного поля ПередОкончаниемРедактирования. Оно срабатывает, когда пользователь пытается завершить редактирование всей строки (нажимает Enter в последней колонке, кликает на другую строку или вне таблицы).

Разберем, как применить этот механизм для контроля конкретной колонки:


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

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

В этом случае пользователь сможет перемещаться между колонками внутри одной строки, но программа гарантированно не позволит сохранить строку или перейти к другой записи, пока ошибка в поле почты не будет устранена.

Способ 3. Настройка режима редактирования колонки

Чтобы при установке ТекущаяКолонка ячейка сразу переходила в активный ввод без необходимости повторного двойного клика мышью, настроим свойство колонки РежимРедактирования:

  1. В палитре свойств нужной колонки табличного поля найдем свойство РежимРедактирования (или EditMode).
  2. Установим значение Вход при вводе (РежимРедактированияКолонки.ВходПриВводе) или Непосредственно (РежимРедактированияКолонки.Непосредственно).

Такая настройка гарантирует быстрое открытие редактора поля ввода при попадании на колонку программно или с клавиатуры.

← На главную