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

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

Печать штрихкода на печатных формах первичных документов с последующим автоматическим поиском объекта в информационной базе при сканировании — классическая задача автоматизации документооборота. На первый взгляд реализация выглядит тривиальной: добавить реквизит в документ, заполнять его при записи и искать по нему в списке. Однако на практике разработчики часто сталкиваются с неочевидными проблемами: блокировкой документов датами запрета редактирования, нечитаемостью длинных одномерных кодов и потерей фокуса ввода при работе сканеров.

Разберем детально, как спроектировать надежную, масштабируемую и производительную схему штрихкодирования документов в среде 1С:Предприятие.

Выбор архитектуры хранения: реквизит документа или регистр сведений?

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

  1. Хранение в реквизите документа. Если штрихкод хранится непосредственно в документе и генерируется в событиях ПередЗаписью или ПриЗаписи, возникает серьезное ограничение. Если потребуется перепечатать документ из закрытого расчетного периода, а штрихкод ранее не был создан или требует переформирования, запись объекта завершится ошибкой из-за механизма Даты запрета изменения данных. Кроме того, любое обновление реквизита приводит к неоправданной регистрации изменений в планах обмена (РИБ) и модификации версий объектов.
  2. Использование независимого регистра сведений. Архитектура, принятая в Библиотеке стандартных подсистем (БСП) и типовых решениях, предусматривает хранение соответствий в отдельном непериодическом регистре. Это разделяет данные самого документа и служебную информацию штрихкодирования, позволяя генерировать и привязывать коды без изменения исходного документа.

Рассмотрим оптимальную структуру регистра сведений для штрихкодов документов:

  1. Измерение: Штрихкод (Тип: Строка, фиксированная или переменная длина, обязательно включено свойство Индексировать).
  2. Ресурс (или измерение): Документ (Составной тип, включающий ссылки на все штрихкодируемые виды документов конфигурации).

Такая структура обеспечивает мгновенный поиск ссылки по известному штрихкоду по прямому индексу измерений:


// Пример быстрого поиска документа по штрихкоду через регистр
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |	Штрихкоды.Документ КАК Документ
    |ИЗ
    |	РегистрСведений.ШтрихкодыДокументов КАК Штрихкоды
    |ГДЕ
    |	Штрихкоды.Штрихкод = &Штрихкод";

Запрос.УстановитьПараметр("Штрихкод", СчитанныйШтрихкод);
РезультатЗапроса = Запрос.Выполнить();

Если НЕ РезультатЗапроса.Пустой() Тогда
    Выборка = РезультатЗапроса.Выбрать();
    Выборка.Следующий();
    НайденнаяСсылка = Выборка.Документ;
КонецЕсли;

Выбор формата штрихкода: одномерные (1D) или двумерные (2D)

Выбор символики напрямую зависит от того, какую информацию необходимо закодировать и какое оборудование установлено на рабочих местах.

1. Одномерные коды (Code 128 / GS1-128 / EAN-13)

Попытка закодировать строковое представление УникальныйИдентификатор документа (GUID длиной 36 символов) в Code 128 приводит к созданию физически длинного штрихкода. При сжатии его до размеров стандартного колонтитула листа A4 штрихи становятся настолько тонкими, что бюджетные лазерные или светодиодные сканеры не могут надежно считать код. Кроме того, использование внутренних сериализаторов вроде ЗначениеВСтрокуВнутр() категорически не рекомендуется: формат внутренней строки зависит от версии платформы, содержит служебные разделители и избыточен по объему.

Если требуется использовать именно 1D-код:

  1. Используйте детерминированную короткую структуру, например: Префикс базы (2 знака) + Код типа метаданных (3 знака) + Номер/Идентификатор документа.
  2. Для формата EAN-13 можно задействовать диапазон внутренних префиксов предприятия (от 20 до 29), дополнив его порядковым номером из специализированного счетчика и рассчитав контрольную цифру.

2. Двумерные коды (QR-код, DataMatrix)

Двумерные матричные коды значительно компактнее и содержат встроенные алгоритмы коррекции ошибок (Рида — Соломона), что позволяет считывать даже помятые или надорванные бумажные листы. В 2D-код можно поместить как глобальный идентификатор объекта, так и готовую навигационную ссылку 1С вида:


НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(ДокументСсылка);
// Формат строки: "e1cib/data/Документ.РеализацияТоваровУслуг?ref=80bf00505699bb8e11e8..."

При считывании такой строки обработчик может вызвать стандартный платформенный метод ПерейтиПоНавигационнойСсылке(), что мгновенно откроет нужный документ без дополнительных ручных запросов к базе данных. Однако важно учитывать ограничение: для чтения 2D-кодов на рабочих местах обязательно должны использоваться фотосканеры (2D Imager), классические линейные сканеры прочитать их не смогут.

Генерация и печать штрихкода

Генерировать штрихкод наиболее рационально не при интерактивной записи документа, а по требованию — в момент формирования печатной формы. Это предотвратит засорение базы кодами отмененных или тестовых документов.

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

Вывод штрихкода в табличный документ через подсистему БСП выглядит следующим образом:


// Подготовка параметров генерации через БСП
ПараметрыШтрихкода = Новый Структура;
ПараметрыШтрихкода.Вставить("Ширина",           40);
ПараметрыШтрихкода.Вставить("Высота",           15);
ПараметрыШтрихкода.Вставить("Штрихкод",         СтрокаШтрихкода);
ПараметрыШтрихкода.Вставить("ТипВходногоКода",  2); // Например, Code 128 или QR-код
ПараметрыШтрихкода.Вставить("ОтображатьТекст",  Истина);

// Получение двоичных данных картинки через модуль генерации
ДвоичныеДанныеКартинки = ГенерацияШтрихкода.СформироватьШтрихкод(ПараметрыШтрихкода);

Если ДвоичныеДанныеКартинки <> Неопределено Тогда
    Рисунок = ОбластьМакета.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
    Рисунок.Картинка = Новый Картинка(ДвоичныеДанныеКартинки);
    Рисунок.РазмерКартинки = РазмерКартинки.АвтоРазмер;
КонецЕсли;

Обработка события сканирования в управляемом интерфейсе

Проанализируем механизм перехвата данных от сканера. Если сканер работает в режиме эмуляции клавиатуры (HID), он посылает поток символов в активное поле ввода. Если фокус находится вне поля поиска формы списка, считывание штрихкода не вызовет позиционирования на документе.

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


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Подключаем форму к обработке событий сканера через БПО
    ПодключитьОбработчикОповещения("ОбработкаОповещенияБПО");
КонецПроцедуры

&НаКлиенте
Процедура ОбработкаОповещенияБПО(ИмяСобытия, Параметр, Источник)
    Если ИмяСобытия = "Штрихкод" Или ИмяСобытия = "ScanData" Тогда
        // Считываем полученный штрихкод и вызываем поиск документа
        СчитанныйКод = ?(ТипЗнч(Параметр) = Тип("Структура"), Параметр.Штрихкод, Параметр);
        ОбработатьШтрихкодСервер(СчитанныйКод);
    КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ОбработатьШтрихкодСервер(Знач Штрихкод)
    // Поиск документа в регистре и открытие формы
    НайденнаяСсылка = НайтиДокументПоШтрихкоду(Штрихкод);
    Если ЗначениеЗаполнено(НайденнаяСсылка) Тогда
        ПараметрыОткрытия = Новый Структура("Ключ", НайденнаяСсылка);
        ОткрытьФорму("Документ." + НайденнаяСсылка.Метаданные().Имя + ".ФормаОбъекта", ПараметрыОткрытия);
    КонецЕсли;
КонецПроцедуры

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

← На главную