Как определить, что ячейка табличной части находится в режиме редактирования при обработке внешнего события

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

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

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

Ограничения платформы 1С при работе с активным редактором ячейки

Проанализируем, почему нельзя напрямую узнать состояние внутреннего текстового редактора ячейки:

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

Способ 1. Использование программных флагов в событиях таблицы

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

Разберем по шагам реализацию данного механизма:

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

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


Перем ВРежимеРедактированияСтроки;
Перем РедактируемаяКолонка;

&НаКлиенте
Процедура ТоварыПередНачаломИзменения(Элемент, Отказ)
    ВРежимеРедактированияСтроки = Истина;
    РедактируемаяКолонка = Элемент.ТекущаяКолонка.Имя;
КонецПроцедуры

&НаКлиенте
Процедура ТоварыПриОкончанииРедактирования(Элемент, ОтменаРедактирования)
    ВРежимеРедактированияСтроки = Ложь;
    РедактируемаяКолонка = "";
КонецПроцедуры

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

Важные риски метода:

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

Способ 2. Корректировка сценария работы и разделение интерфейсов

Как справедливо отмечено в обсуждении, необходимость двойного клика перед сканированием усложняет пользовательский сценарий (workflow). Рассмотрим более надежные архитектурные подходы:

  1. Разделение режимов работы сканера:
    1. Если сканер подключен в режиме эмуляции клавиатуры (HID / разрыв клавиатуры), он отправляет символы напрямую в активный элемент ввода операционной системы, в котором стоит курсор. В этом случае внешнее событие 1С не генерируется, и эмуляция нажатий (через SendKeys) не требуется.
    2. Если сканер работает через COM-порт/драйвер с генерацией события ВнешнееСобытие, сканирование должно обрабатывать бизнес-логику документа независимо от фокуса (поиск позиции, добавление строки, инкремент количества).
  2. Использование явной команды привязки: если бизнес-процесс требует именно привязать штрихкод к конкретной позиции, надежнее вынести эту операцию на отдельную кнопку или вызывать модальное/блокирующее окно ожидания сканирования. Это исключает двусмысленность между поиском товара и записью данных в строку.
← На главную