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

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

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

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

Анализ проблемы: особенности событий в 1С 8.1

Давайте разберем, почему простая попытка использовать событие ПриИзменении не приводит к желаемому результату "мгновенного" перехода. В платформе 1С (особенно в версии 8.1 на обычных формах) событие ПриИзменении генерируется только тогда, когда система понимает, что ввод в поле завершен. Это происходит в двух случаях:

  1. Пользователь нажал клавишу Enter.
  2. Пользователь переключил фокус на другой элемент (нажал Tab или кликнул мышкой).

Таким образом, если мы напишем код перехода внутри ПриИзменении, он сработает уже ПОСЛЕ того, как пользователь вручную покинул поле, что делает автоматизацию бессмысленной. Событие ОкончаниеВводаТекста также не подходит для посимвольного отслеживания, так как оно срабатывает при завершении редактирования строки.

Решение №1: Использование маски ввода (Рекомендуемый подход)

Проанализируем ситуацию: зачем нам плодить 10 или 12 отдельных полей ввода, если можно использовать одно, но правильно настроенное? Это самый надежный и "чистый" с точки зрения кода способ. Вместо создания массива полей, мы используем одно ПолеВвода с типом данных Строка и настроенной маской.

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

Рассмотрим по шагам настройку маски для ИНН:

  1. Выделите ПолеВвода на форме и откройте его свойства.
  2. Установите тип данных — Строка. Не используйте тип Число для ИНН, иначе вы потеряете ведущие нули.
  3. Найдите свойство Маска.
  4. Для ИНН юридического лица введите: 9999999999 (10 девяток).
  5. Для ИНН физического лица введите: 999999999999 (12 девяток).

Символ 9 в маске означает, что в данной позиции разрешен ввод только цифр. Если вы хотите визуально разделить группы цифр (например, код региона), маска может выглядеть так: 99-99-999999.

Решение №2: Программное управление фокусом через ТекущийЭлемент

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


Процедура Поле1ПриИзменении(Элемент)
    // Эта процедура сработает после нажатия Enter в Поле1
    ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.Поле2;
КонецПроцедуры

Важно помнить, что в 8.1 ЭлементыФормы — это коллекция, через которую мы обращаемся к визуальным объектам. Чтобы этот код был эффективен без нажатия Enter, некоторые разработчики пытаются использовать WScript.Shell для имитации нажатия клавиши Tab. Разберем этот пример:


Процедура Поле1ПриИзменении(Элемент)
    Попытка
        ОбъектShell = Новый COMОбъект("Wscript.Shell");
        ОбъектShell.SendKeys("{TAB}");
    Исключение
        // Обработка ошибки, если COM-объект недоступен
    КонецПопытки;
КонецПроцедуры

Внимание: данный метод также страдает от того, что событие ПриИзменении не "стреляет" мгновенно. В обычных формах 8.1 нет стандартного события OnKeyPress. Если вам крайне важен переход именно по нажатию одной клавиши без Enter, придется использовать вставку ActiveX компонента (например, Microsoft Forms 2.0 TextBox), который имеет событие Change, срабатывающее при каждом нажатии.

Как отследить количество введенных символов?

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

Проанализируем пример функции для проверки длины:


Процедура ПроверитьЗаполнениеИНН()
    // Предположим, наше поле связано с реквизитом "ИННКонтрагента"
    ДлинаТекста = СтрДлина(СокрЛП(ИННКонтрагента));
    
    Если ДлинаТекста < 10 Тогда
        Сообщить("ИНН введен не полностью! Ожидается 10 или 12 цифр.");
    КонецЕсли;
КонецПроцедуры

Важный технический нюанс: в момент набора текста в поле ввода, значение самого реквизита в базе данных (или в объекте формы) еще не обновлено. Оно обновится только после фиксации ввода. Если вам нужно знать, что пользователь набрал прямо сейчас (до нажатия Enter), в обычных формах можно попробовать обратиться к свойству Элемент.ТекстРедактирования, однако оно доступно не для всех типов полей и требует осторожного обращения.

Дополнительные настройки для удобства пользователя

Чтобы работа с вашими полями ввода была максимально комфортной, рекомендуем установить следующие свойства в палитре свойств элементов формы:

Итоги

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

← На главную