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