В процессе разработки и настройки торгового оборудования в среде 1С программисты часто сталкиваются с неприятной ситуацией: при попытке напечатать штрихкод (например, на ценнике или этикетке) на печать упорно выводится стандартный шаблон 1234567890128. Это происходит выборочно — большинство товаров печатаются корректно, но на некоторых позициях система дает сбой.
В этой статье мы подробно разберем, почему возникает эта проблема, как работает валидация штрихкодов в компонентах 1С, и предоставим готовые решения для исправления ошибок округления и расчета контрольных сумм штрихкодов EAN-13.
Значение 1234567890128 — это жестко зашитая строка по умолчанию (заглушка) во внешней компоненте печати штрихкодов (например, в классической 1CBarCod.ocx или встроенных механизмах платформы). Данный штрихкод выводится на печать только в одном случае: когда переданный в компоненту штрихкод не соответствует стандарту EAN-13.
Стандарт штрихкодирования EAN-13 состоит из 13 цифр, где первые 12 цифр — это информационный блок, а последняя, 13-я цифра — это контрольный символ (контрольная сумма), рассчитываемый по строгому математическому алгоритму на основе первых 12 цифр.
Проанализируем конкретный пример. Предположим, у нас есть штрихкод 2000001559261, который отказывается печататься стандартными средствами. Если мы отбросим последнюю цифру и передадим первые 12 знаков (200000155926) в специализированный калькулятор стандартов GS1, то мы увидим, что правильный контрольный символ для этой последовательности должен быть равен 0, а вовсе не 1!
Таким образом, штрихкод 2000001559261 является невалидным ("левым"). Внешняя компонента 1С при получении некорректного значения отклоняет его запись, выдает ошибку инициализации и возвращает картинку-заглушку по умолчанию — тот самый штрихкод 1234567890128.
Иногда разработчики пытаются обойти ограничения внешней компоненты 1С и используют специализированные Windows-шрифты (например, EAN13 или Code EAN 13). При использовании шрифта штрихкод выводится на печать без каких-либо ошибок. Однако при попытке считать его любым физическим сканером ничего не происходит.
Объясним причину этого явления. Шрифт — это просто набор графических символов (глифов), которые заменяют обычные цифры на черные и белые полосы. У шрифта нет встроенной логики валидации: что вы ему передали в качестве строки, то он и отобразит на экране. Но аппаратный сканер штрихкодов имеет встроенный процессор, который при считывании мгновенно рассчитывает контрольную сумму полученной комбинации полос. Видя, что контрольный символ в штрихкоде не совпадает с расчетным, сканер определяет штрихкод как поврежденный или фальшивый и просто игнорирует его.
Поэтому единственным правильным решением является программный расчет и подстановка корректного контрольного символа перед выводом штрихкода на печать.
Рассмотрим алгоритм расчета контрольной цифры для штрихкода EAN-13 по шагам:
Ниже представлен готовый код функции на встроенном языке 1С, которая рассчитывает контрольный символ как для EAN-13, так и для более короткого формата EAN-8:
Функция глКонтрольныйСимволEAN(ШтрКод, Тип) Экспорт
Четн = 0;
Нечетн = 0;
Если Тип = 13 Тогда
КолвоИтераций = 6;
Иначе
КолвоИтераций = 4;
КонецЕсли;
Для Индекс = 1 По КолвоИтераций Цикл
Четн = Четн + Число(Сред(ШтрКод, 2 * Индекс, 1));
Нечетн = Нечетн + Число(Сред(ШтрКод, 2 * Индекс - 1, 1));
КонецЦикла;
Если Тип = 13 Тогда
Четн = Четн * 3;
Иначе
Нечетн = Нечетн * 3;
КонецЕсли;
КонтЦифра = 10 - (Четн + Нечетн) % 10;
Возврат ?(КонтЦифра = 10, "0", Строка(КонтЦифра));
КонецФункции
Используйте эту функцию для валидации ваших штрихкодов перед передачей их в макет для печати. Если выгружаемый штрихкод содержит неверный символ, вы можете автоматически заменить его на корректный.
Если вам необходимо напечатать очень мелкий штрихкод (например, на маленьком ценнике для ювелирных изделий или парфюмерии), стандартная компонента ActiveX может размывать линии при масштабировании. В таких ситуациях отлично помогает использование системного шрифта EanGnivc (который можно найти в папках регламентированной отчетности 1С).
Однако просто вывести цифры этим шрифтом нельзя — стандарт EAN-13 использует разные таблицы символов для левой и правой половины кода, чтобы сканер мог определить направление чтения. Нам необходимо предварительно преобразовать строку цифр в специальную последовательность символов.
Рассмотрим по шагам функцию преобразования строки штрихкода в строку для шрифта EanGnivc:
Функция СформироватьСтрокуEanGnivc(ШтрихкодСтрокойСимволов) Экспорт
Перем СпособыКодированияЛевойЧасти[10];
СимволыСпособовКодирования = "#$%&'()*+,";
ЛевыйЗащитныйШаблон = "!";
СреднийЗащитныйШаблон = "-";
ПравыйЗащитныйШаблон = "!";
СимволыШрифтаПоТипамКодов = СоздатьОбъект("ТаблицаЗначений");
СимволыШрифтаПоТипамКодов.НоваяКолонка("Ключ");
СимволыШрифтаПоТипамКодов.НоваяКолонка("Значение");
СимволыШрифтаПоТипамКодов.НоваяСтрока();
СимволыШрифтаПоТипамКодов.Ключ = "L";
СимволыШрифтаПоТипамКодов.Значение = "0123456789";
СимволыШрифтаПоТипамКодов.НоваяСтрока();
СимволыШрифтаПоТипамКодов.Ключ = "G";
СимволыШрифтаПоТипамКодов.Значение = "ABCDEFGHIJ";
СимволыШрифтаПоТипамКодов.НоваяСтрока();
СимволыШрифтаПоТипамКодов.Ключ = "R";
СимволыШрифтаПоТипамКодов.Значение = "abcdefghij";
СпособыКодированияЛевойЧасти[1] = "LLLLLL";
СпособыКодированияЛевойЧасти[2] = "LLGLGG";
СпособыКодированияЛевойЧасти[3] = "LLGGLG";
СпособыКодированияЛевойЧасти[4] = "LLGGGL";
СпособыКодированияЛевойЧасти[5] = "LGLLGG";
СпособыКодированияЛевойЧасти[6] = "LGGLLG";
СпособыКодированияЛевойЧасти[7] = "LGGGLL";
СпособыКодированияЛевойЧасти[8] = "LGLGLG";
СпособыКодированияЛевойЧасти[9] = "LGLGGL";
СпособыКодированияЛевойЧасти[10] = "LGGLGL";
СпособКодированияПравойЧасти = "RRRRRR";
Если СтрДлина(ШтрихкодСтрокойСимволов) = 13 Тогда
КоличествоСимволовВГруппе = 6;
ИначеЕсли СтрДлина(ШтрихкодСтрокойСимволов) = 8 Тогда
КоличествоСимволовВГруппе = 4;
СимволыСпособовКодирования = "";
ШтрихкодСтрокойСимволов = "0" + ШтрихкодСтрокойСимволов;
Иначе
Предупреждение("Поддерживаются только штрихкоды длиной 13 и 8 символов");
Возврат "";
КонецЕсли;
ИндексСпособаКодирования = Число(Лев(ШтрихкодСтрокойСимволов,1));
ЛеваяЧастьКода = "";
ПраваяЧастьКода = "";
Для ИндексСимвола = 1 По КоличествоСимволовВГруппе Цикл
СпосКодЛевЧаст = СпособыКодированияЛевойЧасти[ИндексСпособаКодирования + 1];
СимвКодКлюч = Сред(СпосКодЛевЧаст,ИндексСимвола,1);
Стр = "";
Если СимволыШрифтаПоТипамКодов.НайтиЗначение(СимвКодКлюч,Стр,"Ключ") = 1 Тогда
СимвПоТипу = СимволыШрифтаПоТипамКодов.ПолучитьЗначение(Стр,"Значение");
КонецЕсли;
ЛеваяЧастьКода = ЛеваяЧастьКода + Сред(СимвПоТипу,Число(Сред(ШтрихкодСтрокойСимволов,(ИндексСимвола+1),1))+1,1);
Стр = "";
СимвКодПравКлюч = Сред(СпособКодированияПравойЧасти,ИндексСимвола,1);
Если СимволыШрифтаПоТипамКодов.НайтиЗначение(СимвКодПравКлюч,Стр,"Ключ") = 1 Тогда
СимвПоТипуПрав = СимволыШрифтаПоТипамКодов.ПолучитьЗначение(Стр,"Значение");
КонецЕсли;
ПраваяЧастьКода = ПраваяЧастьКода + Сред(СимвПоТипуПрав,Число(Сред(ШтрихкодСтрокойСимволов,(ИндексСимвола + КоличествоСимволовВГруппе+1),1))+1,1);
КонецЦикла;
Результат = "" + Сред(СимволыСпособовКодирования,ИндексСпособаКодирования+1,1)
+ ЛевыйЗащитныйШаблон
+ ЛеваяЧастьКода
+ СреднийЗащитныйШаблон
+ ПраваяЧастьКода
+ ПравыйЗащитныйШаблон;
Возврат Результат;
КонецФункции
Передайте полученную из функции строку в ячейку табличного документа и установите для этой ячейки шрифт EanGnivc. На выходе вы получите красивый, компактный и легко читаемый сканерами штрихкод.
Проанализируем современные тенденции в разработке печатных форм. Использование ActiveX-компонент (таких как 1CBarCod.ocx) уходит в прошлое из-за проблем с регистрацией библиотек в 64-битных операционных системах и сложностей работы в терминальном режиме (RDP).
Если вам необходимо реализовать надежную систему печати, рассмотрите следующие альтернативы: