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