При разработке собственных документов в системе 1С:Предприятие 8.3 часто возникает задача автоматизации ввода данных с помощью торгового оборудования. Наиболее востребованным устройством является сканер штрихкодов. Однако программисты, особенно начинающие, часто сталкиваются с ситуацией, когда код «под копирку» перенесен из типового решения, но оборудование упорно отказывается реагировать на действия пользователя. В этой статье мы подробно разберем, как правильно интегрировать поддержку сканера в новый документ, проанализируем типичные ошибки и рассмотрим рабочие примеры кода на базе Библиотеки подключаемого оборудования (БПО).
Рассмотрим ситуацию, когда вы создали новый документ (например, «Лист доставки»), добавили в модуль формы процедуры ПриОткрытии или ВнешнееСобытие, но при запуске системы они не выполняются. Вы ставите точку останова или команду Сообщить, но никакой реакции не следует. Проанализируем причину.
В платформе 1С недостаточно просто написать текст процедуры с правильным именем в модуле формы. Каждый обработчик события должен быть явно назначен в палитре свойств формы. Если вы создаете документ с нуля (а не копируете существующий), связи между событиями (такими как «При открытии», «При создании на сервере», «Внешнее событие») и программными процедурами отсутствуют.
Чтобы исправить это (или реализовать программное изменение форм), выполните следующие шаги:
ПриОткрытии.Только после этого процедуры станут «живыми» и будут вызываться платформой при наступлении соответствующих событий.
Современные конфигурации (включая «Бухгалтерию для Казахстана», «ERP», «УТ 11» и др.) работают со сканерами через общий механизм БПО. Разберем, как программно инициализировать работу со сканером в модуле управляемой формы. В качестве альтернативы для настройки оборудования без использования БПО и дополнительных драйверов можно применить пример подключения сканера «в разрыв клавиатуры» с генерацией внешнего события.
Рассмотрим процедуру подключения при открытии формы. Нам необходимо сообщить менеджеру оборудования, что данная форма готова принимать данные от сканера.
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Определяем типы оборудования, которые нам нужны
ПоддерживаемыеТипыПодключаемогоОборудования = "СканерШтрихкода";
// Создаем описание оповещения для обработки результата подключения
ОповещениеПриПодключении = Новый ОписаниеОповещения("ПодключитьОборудованиеЗавершение", ЭтотОбъект);
// Вызываем метод БПО для инициализации сканера на форме
МенеджерОборудованияКлиент.НачатьПодключениеОборудованиеПриОткрытииФормы(
ОповещениеПриПодключении,
ЭтотОбъект,
ПоддерживаемыеТипыПодключаемогоОборудования);
КонецПроцедуры
&НаКлиенте
Процедура ПодключитьОборудованиеЗавершение(РезультатВыполнения, Параметры) Экспорт
Если Не РезультатВыполнения.Результат Тогда
ТекстСообщения = НСтр("ru = 'При подключении оборудования произошла ошибка: ""%ОписаниеОшибки%"".'");
ТекстСообщения = СтрЗаменить(ТекстСообщения, "%ОписаниеОшибки%", РезультатВыполнения.ОписаниеОшибки);
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
КонецЕсли;
КонецПроцедуры
Важный момент: использование асинхронных вызовов (с префиксом «Начать...») является стандартом для современных версий платформы. Это гарантирует, что интерфейс не «зависнет» в ожидании ответа от драйвера оборудования.
Проанализируем критическую ошибку: многие забывают отключать оборудование при закрытии формы. Если этого не сделать, порт сканера может остаться занятым («захваченным» этой формой), и в других документах сканирование работать не будет до полной перезагрузки сеанса 1С. Для решения проблемы блокировки COM-порта при одновременной работе в нескольких сеансах системы пригодится утилита для организации совместного доступа к RS232-сканеру из нескольких окон 1С.
Обязательно добавим обработчик события ПриЗакрытии:
&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
// Отключаем сканер, чтобы освободить ресурсы для других окон
МенеджерОборудованияКлиент.НачатьОтключениеОборудованиеПриЗакрытииФормы(Неопределено, ЭтотОбъект);
КонецПроцедуры
Когда пользователь нажимает кнопку на сканере, устройство посылает сигнал, который трансформируется платформой во «Внешнее событие» или «Оповещение». В современных конфигурациях чаще всего используется ОбработкаОповещения. Разберем, как вычленить сам штрихкод из параметров события.
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
ДанныеШтрихкода = Неопределено;
// Проверяем, что событие пришло именно от торгового оборудования
Если Источник = "ПодключаемоеОборудование" И ИмяСобытия = "ScanData" Тогда
// Параметр обычно представляет собой массив
// Параметр[0] - собственно данные штрихкода
Если Параметр[1] = Неопределено Тогда
ДанныеШтрихкода = Параметр[0];
Иначе
// В некоторых драйверах данные могут находиться в расширенной структуре
ДанныеШтрихкода = Параметр[1][1];
КонецЕсли;
КонецЕсли;
Если ДанныеШтрихкода <> Неопределено Тогда
// Здесь мы вызываем нашу логику поиска товара
ОбработатьПолученныйШтрихкод(ДанныеШтрихкода);
КонецЕсли;
КонецПроцедуры
Получение строки цифр (штрихкода) — это лишь половина дела. Нам нужно найти соответствующий товар в справочнике. Проанализируем, как это реализовать на стороне сервера. Обычно поиск ведется по регистру сведений ШтрихкодыНоменклатуры (или аналогичному в вашей конфигурации).
Рекомендуется создать серверную функцию, которая будет принимать штрихкод и возвращать структуру с данными товара (ссылка на номенклатуру, единица измерения, коэффициент, характеристика).
&НаСервере
Процедура ОбработатьПолученныйШтрихкод(Штрихкод)
// 1. Ищем штрихкод в регистре
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Штрихкоды.Номенклатура КАК Номенклатура,
| Штрихкоды.Характеристика КАК Характеристика,
| Штрихкоды.Упаковка КАК Упаковка
|ИЗ
| РегистрСведений.ШтрихкодыНоменклатуры КАК Штрихкоды
|ГДЕ
| Штрихкоды.Штрихкод = &Штрихкод";
Запрос.УстановитьПараметр("Штрихкод", Штрихкод);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
// 2. Если товар найден, добавляем его в табличную часть
НоваяСтрока = Объект.Товары.Добавить();
НоваяСтрока.Номенклатура = Выборка.Номенклатура;
НоваяСтрока.Количество = 1;
// Вызываем типовые механизмы пересчета цен и сумм
// (например, ОбработатьПриИзмененииНоменклатуры)
Иначе
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Товар со штрихкодом " + Штрихкод + " не найден!");
КонецЕсли;
КонецПроцедуры
Рассмотрим несколько практических советов, которые сделают работу со сканером в вашем новом документе профессиональной:
ТЧ.НайтиСтроки().ОбработатьПолученныйШтрихкод.NativeApi. Обычный поиск по регистру штрихкодов здесь не поможет — потребуется разбор кода маркировки через специализированные модули БПО (например, МенеджерОборудованияКлиент.РазобратьШтрихкод).Вопрос() или Предупреждение() в блокирующем режиме.Таким образом, для успешной работы сканера в самописном документе необходимо соблюдение трех условий: правильная привязка событий в конфигураторе, корректная инициализация БПО в коде и грамотная серверная обработка найденных данных. Следуя этим правилам, вы сможете внедрить поддержку торгового оборудования в любой объект конфигурации.