Как исправить очистку поля ввода при сканировании штрихкода в 1С?

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

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

В этой статье мы подробно разберем внутреннюю механику работы платформы «1С:Предприятие» при вводе текста, выясним истинную причину очистки поля ввода и рассмотрим правильные шаблоны кода как для обычных, так и для управляемых форм.

Выясняем причину: как платформа обрабатывает окончание ввода текста

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

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

В этот момент платформа ожидает, что мы сами программно найдем нужный объект и передадим его обратно. Передача осуществляется через специальный выходной параметр процедуры, который в обычных формах называется Значение. Если мы находим документ, записываем его напрямую в реквизит объекта или реквизит формы, но при этом оставляем сам параметр процедуры Значение пустым (равным Неопределено), платформа считает, что наша попытка программного поиска завершилась неудачей.

Как следствие, платформа отрабатывает стандартный сценарий защиты от ввода некорректных данных:

  1. Выдает предупреждение об ошибке валидации.
  2. Откатывает значение поля ввода к первоначальному состоянию, из-за чего оно визуально очищается.

Разбор ошибочного кода

Давайте рассмотрим типичный пример некорректного обработчика, который приводит к описанной проблеме в обычных формах:


Если СтрДлина(Текст) > 11 Тогда 
    СтандартнаяОбработка = Ложь; 
    МассивСсылок = ШтрихкодированиеПечатныхФорм.ПолучитьСсылкуПоШтрихкодуТабличногоДокумента(Текст); 
    Если МассивСсылок.Количество Тогда 
        Расходная = МассивСсылок[0].Ссылка; 
        ЭлементыФормы.Расходная.Значение = МассивСсылок[0].Ссылка; 
    КонецЕсли; 
Иначе 
    СтандартнаяОбработка = Истина; 
КонецЕсли;

Проанализируем ключевые ошибки в этом фрагменте:

  1. Игнорирование параметра Значение. Разработчик пытается напрямую заполнить реквизит Расходная и свойство элемента формы ЭлементыФормы.Расходная.Значение. При этом выходной параметр процедуры Значение остается пустым. Платформа не понимает, что поиск завершился успешно.
  2. Синтаксическая ошибка работы с коллекцией. Конструкция Если МассивСсылок.Количество Тогда некорректна для встроенного языка 1С. Метод Количество() пишется со круглыми скобками и возвращает число. Хотя в некоторых старых версиях платформы числовые значения могли неявно приводиться к булеву типу, хорошим тоном является явное сравнение: МассивСсылок.Количество() > 0.

Правильное решение для обычных форм

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

Давайте перепишем код правильно:


Процедура РасходнаяОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)

    // Если длина строки указывает на то, что это штрихкод (например, более 11 символов)
    Если СтрДлина(Текст) > 11 Тогда 
        
        // Отключаем стандартный поиск платформы по строке
        СтандартнаяОбработка = Ложь; 
        
        // Выполняем поиск документа по штрихкоду
        МассивСсылок = ШтрихкодированиеПечатныхФорм.ПолучитьСсылкуПоШтрихкодуТабличногоДокумента(Текст); 
        
        Если МассивСсылок.Количество() > 0 Тогда 
            // КЛЮЧЕВОЙ МОМЕНТ: Присваиваем ссылку выходному параметру процедуры!
            Значение = МассивСсылок[0].Ссылка; 
        Иначе
            // Если ничего не нашли, очищаем параметр
            Значение = Неопределено;
            ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Документ по считанному штрихкоду не найден!");
        КонецЕсли; 
        
    Иначе 
        // Если это обычный ручной ввод номера, оставляем стандартную обработку
        СтандартнаяОбработка = Истина; 
    КонецЕсли;

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

При такой реализации значение будет корректно подставлено в поле формы, а платформа без ошибок перейдет к обработке события ПриИзменении.

Особенности реализации в Управляемых формах (платформа 8.3)

Если мы работаем с управляемым интерфейсом, логика работы события ОкончаниеВводаТекста меняется. Сигнатура этого метода больше не содержит параметра Значение. Вместо него используется параметр ДанныеВыбора, который ожидает объект типа СписокЗначений.

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


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

&НаСервереБезКонтекста
Функция ПоискДокументаПоШтрихкодуНаСервере(Знач ТекстШтрихкода)
    
    МассивСсылок = ШтрихкодированиеПечатныхФорм.ПолучитьСсылкуПоШтрихкодуТабличногоДокумента(ТекстШтрихкода);
    Если МассивСсылок.Количество() > 0 Тогда
        Возврат МассивСсылок[0].Ссылка;
    КонецЕсли;
    
    Возврат Документы.РеализацияТоваровУслуг.ПустаяСсылка();
    
КонецФункции

Важный нюанс: Обратите внимание, что серверная функция объявлена с директивой &НаСервереБезКонтекста. При работе со стандартными событиями ввода текста на клиенте крайне важно избегать вызовов контекстных серверных процедур (&НаСервере), так как они передают на сервер все данные формы, что может привести к нежелательному сбросу состояния элементов управления во время выполнения серверного вызова.

Борьба со случайным срабатыванием автоподбора

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

Чтобы система не пыталась подбирать документы по частичному совпадению начальных цифр штрихкода (что приводит к зависанию интерфейса и открытию лишних диалоговых окон), рекомендуется принудительно гасить автоподбор для этого поля:


Процедура РасходнаяАвтоПодборТекста(Элемент, Текст, ТекстАвтоПодбора, СтандартнаяОбработка)
    
    // Если длина текста превышает стандартную длину префиксов и номеров, 
    // отключаем стандартный автоподбор
    Если СтрДлина(Текст) > 5 Тогда
        СтандартнаяОбработка = Ложь;
    КонецЕсли;
    
КонецПроцедуры

Архитектурный совет: почему эмуляция клавиатуры — это плохо?

Использование текстового поля ввода для сканирования штрихкодов имеет право на существование, но этот подход крайне ненадежен в условиях реального склада или магазина по следующим причинам:

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

← На главную