Как решить проблемы при печати и сканировании штрихкодов Code128 в 1С:Предприятие?

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

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

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

Ограничения стандарта Code128: поддержка кириллицы и пробелов

Начнем с базовых правил работы со стандартом Code128. Часто у начинающих разработчиков возникает вопрос, почему при передаче русской строки штрихкод не формируется или выводится некорректно. Разберем технические особенности этого типа кодирования.

Штрихкод Code128 не поддерживает кириллицу. Попытка закодировать в него русские буквы приведет к ошибке генерации компоненты печати. Стандарт работает исключительно с символами ASCII в диапазоне от 0 до 127. Если вам необходимо передать текстовую информацию, используйте только латинские буквы, цифры и спецсимволы.

Также существует распространенное заблуждение, что Code128 не поддерживает пробелы. Это неверно. Стандарт Code128 разделяется на три подмножества (набора символов): A, B и C:

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


// Получаем рисунок из макета, где D2 — имя объекта штрихкода
ОбъектШтрихкода = Макет.Рисунки.D2.Объект;
ОбъектШтрихкода.ТипКода = 4; // Обычно соответствует типу Code128 в компоненте 1С
ОбъектШтрихкода.Сообщение = "DOC-2023-00015"; // Данные для кодирования
ОбъектШтрихкода.ТекстКода = "DOC-2023-00015"; // Текст, отображаемый под кодом

Проблема длины штрихкода: сжатие GUID

Попытка закодировать результат системной функции ЗначениеВСтрокуВнутр() напрямую в Code128 обречена на провал. Данная строка содержит фигурные скобки, русские названия метаданных и GUID. Полученный штрихкод будет иметь огромную длину. Физическая плотность штрихов окажется настолько высокой, что обычные лазерные или светодиодные сканеры просто не смогут его считать.

Использование «чистого» GUID (36 символов, например, 550e8400-e29b-41d4-a716-446655440000) также формирует достаточно плотный штрихкод. Проанализируем, как можно сократить длину строки GUID почти в два раза.

Логически GUID — это 128-битное число, состоящее из 16 байт. Текстовое представление с дефисами — лишь один из способов его записи. Мы можем преобразовать эти 16 байт в компактную строку формата Base64. Длина сократится с 36 до 22 символов.

Разберем по шагам алгоритм сжатия и восстановления идентификатора в 1С:


// Функция сжимает GUID в короткую строку Base64
Функция СжатьGUID(Знач СсылкаНаОбъект) Экспорт
    УникальныйИд = СсылкаНаОбъект.УникальныйИдентификатор();
    // Убираем дефисы из строкового представления GUID (получаем 32 символа HEX)
    СтрокаHEX = СтрЗаменить(Строка(УникальныйИд), "-", "");
    
    // Преобразуем HEX-строку в двоичные данные
    ДвоичныеДанныеGUID = ПолучитьДвоичныеДанныеИзГексагональнойСтроки(СтрокаHEX);
    
    // Кодируем двоичные данные в Base64 (получаем строку длиной 24 символа с "==" на конце)
    СтрокаBase64 = ПолучитьBase64СтрокуИзДвоичныхДанных(ДвоичныеДанныеGUID);
    
    // Убираем символы заполнения "=" и заменяем неподдерживаемые символы для безопасности
    СтрокаBase64 = СтрЗаменить(СтрокаBase64, "+", "-");
    СтрокаBase64 = СтрЗаменить(СтрокаBase64, "/", "_");
    СтрокаBase64 = СтрЗаменить(СтрокаBase64, "=", "");
    
    Возврат СтрокаBase64; // Получаем строку длиной всего 22 символа!
КонецФункции

Для обратного преобразования при считывании штрихкода сканером используем следующую функцию:


// Функция восстанавливает исходный GUID из сжатой строки Base64
Функция ВосстановитьGUID(Знач СжатаяСтрока) Экспорт
    // Возвращаем на место символы Base64
    СтрокаBase64 = СтрЗаменить(СжатаяСтрока, "-", "+");
    СтрокаBase64 = СтрЗаменить(СжатаяСтрока, "_", "/");
    
    // Восстанавливаем символы выравнивания "=" до кратности 4
    Остаток = СтрДлина(СтрокаBase64) % 4;
    Если Остаток > 0 Тогда
        СтрокаBase64 = СтрокаBase64 + Лев("==", 4 - Остаток);
    КонецЕсли;
    
    // Декодируем из Base64 в двоичные данные, затем в HEX
    ДвоичныеДанные = ПолучитьДвоичныеДанныеИзBase64Строки(СтрокаBase64);
    СтрокаHEX = ПолучитьГексагональнуюСтрокуИзДвоичныхДанных(ДвоичныеДанные);
    
    // Восстанавливаем дефисы для стандартного формата GUID (8-4-4-4-12)
    ФорматныйGUID = Сред(СтрокаHEX, 1, 8) + "-" +
                    Сред(СтрокаHEX, 9, 4) + "-" +
                    Сред(СтрокаHEX, 13, 4) + "-" +
                    Сред(СтрокаHEX, 17, 4) + "-" +
                    Сред(СтрокаHEX, 21);
                    
    Возврат Новый УникальныйИдентификатор(ФорматныйGUID);
КонецФункции

Этот метод позволяет существенно укоротить штрихкод Code128, сделав его легко читаемым для любого 1D-сканера без потери уникальности идентификации.

Решение проблемы с раскладкой клавиатуры при сканировании

Если сканер штрихкодов подключен к компьютеру в режиме эмуляции клавиатуры (HID-mode), то при сканировании символы передаются операционной системе так, будто их быстро вводит пользователь на клавиатуре. Из-за этого возникает критическая проблема: если на компьютере в момент сканирования активна русская раскладка клавиатуры (РУС), то латинские буквы превратятся в русские (например, латинская «e» превратится в русскую «у», «w» — в «ц» и так далее).

Выясним, какие существуют пути решения этой проблемы.

Вариант 1. Программная транслитерация (быстрый «костыль»)

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

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


Процедура ПерекодировкаРУС2Англ(Текст) Экспорт
    СимволыАнгл = "~@#$^&QWERTYUIOP{}ASDFGHJKL:""ZXCVBNM<>?`qwertyuiop[]asdfghjkl;'zxcvbnm,./";
    СимволыРУС  = "Ё""№;:?ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,ёйцукенгшщзхъфывапролджэячсмитьбю.";
    
    ТекстАнгл = "";
    Для Сч = 1 ПО СтрДлина(Текст) Цикл
        СимволИсточника = Сред(Текст, Сч, 1);
        ПозицияСимвола = Найти(СимволыРУС, СимволИсточника);
        
        Если ПозицияСимвола <> 0 Тогда
            СимволРезультата = Сред(СимволыАнгл, ПозицияСимвола, 1);
        Иначе
            СимволРезультата = СимволИсточника;
        КонецЕсли;
        
        ТекстАнгл = ТекстАнгл + СимволРезультата;
    КонецЦикла;
    Текст = ТекстАнгл;
КонецПроцедуры

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

Вариант 2. Профессиональное решение: эмуляция COM-порта (RS-232)

Чтобы полностью исключить зависимость от раскладки клавиатуры и фокуса ввода, необходимо перевести сканер в режим работы через виртуальный COM-порт. При этом данные передаются в 1С в виде «сырого» потока байтов напрямую, минуя буфер клавиатуры Windows.

Проанализируем шаги настройки этого режима:

  1. Перевод сканера в режим эмуляции: Найдите в инструкции к вашему сканеру специальный настроечный штрихкод (обычно он называется «USB Virtual COM», «USB-to-Serial» или «Enable Bi-directional USB») и отсканируйте его бумажную или электронную версию. Устройство переинициализируется в системе.
  2. Проверка в диспетчере устройств: Откройте диспетчер устройств Windows. Сканер должен исчезнуть из раздела клавиатур (HID) и появиться в разделе «Порты (COM и LPT)» как виртуальный последовательный порт (например, COM3).
  3. Установка драйвера 1С: В конфигурации 1С зайдите в раздел настройки подключаемого оборудования. Добавьте новое устройство с типом «Сканеры штрихкода». Используйте сертифицированный драйвер «1С:Сканеры штрихкода (NativeApi)».
  4. Параметры подключения: В свойствах подключения укажите порт (например, COM3), скорость передачи (обычно 9600) и сохраните настройки.

При такой настройке при сканировании в 1С будет срабатывать предопределенное событие ОбработкаВнешнегоСобытия. Раскладка клавиатуры больше не имеет никакого значения — данные всегда приходят в корректной кодировке ASCII.

Оптимизация поиска документа по GUID в 1С

Рассмотрим еще одну частую ошибку разработчиков при поиске документов по считанному идентификатору. Часто в коде используют неоптимальный перебор коллекций метаданных, нагружающий базу данных:


// НЕОПТИМАЛЬНЫЙ КОД (Избегайте этого подхода!)
Для Каждого Менеджер Из Документы Цикл
    СсылкаНаОбъект = Менеджер.ПолучитьСсылку(УникальныйИдентификатор);
    Если СсылкаНаОбъект.ПолучитьОбъект() <> Неопределено Тогда
        СсылкаНаОбъект.ПолучитьОбъект().ПолучитьФорму().Открыть();
        Прервать;
    КонецЕсли;
КонецЦикла;

Почему это плохо: Метод ПолучитьОбъект() выполняет тяжелый SQL-запрос к СУБД, считывая все реквизиты и табличные части документа. Если в вашей базе данных более 100 видов документов, система сделает до 100 ресурсоемких запросов, пытаясь выгрузить несуществующие объекты в оперативную память. Это приведет к сильным зависаниям интерфейса.

Разберем, как сделать поиск максимально легким с помощью запроса к СУБД, который проверяет только факт существования ссылки:


// ОПТИМАЛЬНЫЙ КОД поиска документа по GUID
Функция НайтиИОткрытьДокументПоИдентификатору(Знач Идентификатор) Экспорт
    Для Каждого МетаданныеДокумента Из Метаданные.Документы Цикл
        ИмяТаблицы = МетаданныеДокумента.Имя;
        
        // Формируем быструю ссылку без обращения к базе данных
        Ссылка = Документы[ИмяТаблицы].ПолучитьСсылку(Идентификатор);
        
        // Легким запросом проверяем физическое наличие записи в конкретной таблице
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ
            |   Т.Ссылка КАК Ссылка
            |ИЗ
            |   Документ." + ИмяТаблицы + " КАК Т
            |ГДЕ
            |   Т.Ссылка = &Ссылка";
            
        Запрос.УстановитьПараметр("Ссылка", Ссылка);
        РезультатЗапроса = Запрос.Выполнить();
        
        Если Не РезультатЗапроса.Пустой() Тогда
            // Объект найден. Открываем форму
            ПараметрыФормы = Новый Структура("Ключ", Ссылка);
            ОткрытьФорму("Документ." + ИмяТаблицы + ".ФормаОбъекта", ПараметрыФормы);
            Возврат Истина;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Ложь;
КонецФункции

Этот код работает в десятки раз быстрее, так как СУБД выполняет только проверку наличия индексированного поля Ссылка, не загружая в память лишние данные.

Использование встроенных механизмов БСП и переход на 2D-коды

Если ваша конфигурация построена на базе БСП (Библиотеки Стандартных Подсистем), рекомендуем использовать готовую подсистему «Штрихкодирование печатных форм». Она автоматически берет на себя формирование, печать и распознавание штрихкодов документов.

БСП формирует штрихкод по оптимальному алгоритму, кодируя тип документа коротким числовым префиксом, а номер — в формате EAN-13 или укороченном символьном представлении. Это избавляет от необходимости генерировать и сжимать GUID вручную.

Если бизнес-процессы вашей компании всё же требуют передачи больших объемов структурированной информации (например, GUID, дата, сумма и склад одновременно), рассмотрите переход на использование 2D-кодов (QR-код или DataMatrix). Платформа 1С v8.3 начиная с релиза 8.3.16 имеет встроенные инструменты для генерации QR-кодов прямо на уровне платформы без использования сторонних внешних компонент. 2D-коды обладают колоссальной плотностью записи и механизмами коррекции ошибок чтения, что делает сканирование стабильным даже при повреждении или загрязнении распечатанного документа.

← На главную