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