Формат GS1 DataBar Expanded Stacked относится к многострочным композитным символикам, которые позволяют кодировать расширенный набор данных GS1 (например, вес, срок годности, номер партии, серийный номер) в компактном виде. При попытке сформировать такой штрихкод штатной внешней компонентой 1С разработчики сталкиваются с отсутствием поддержки данного типа, а при использовании сторонних устаревших COM-объектов нередко происходит аварийное завершение работы платформы.
Выясним причину проблемы и разберем проверенные способы формирования и вывода штрихкода GS1 DataBar Expanded Stacked на печать как на обычные офисные принтеры, так и на специализированные принтеры этикеток.
Проанализируем технические особенности символики:
GS1 DataBar Expanded, вариант Expanded Stacked формируется в несколько строк (от 2 до 11) с обязательными строками-разделителями (separator patterns) между ними. Превратить линейный код в многострочный простым изменением ширины невозможно.FNC1 или срабатыванием механизма защиты памяти DEP.Рассмотрим универсальный вариант, который позволяет выводить штрихкод на любой принтер через штатный табличный документ 1С. Для этого воспользуемся свободной утилитой генерации штрихкодов Zint, поддерживающей тип символики 79 (GS1 DataBar Expanded Stacked).
Разберем по шагам алгоритм взаимодействия с утилитой из встроенного языка 1С:
--barcode=79), числа сегментов в строке (--cols) и исходных данных.ЗапуститьПриложение() и сохраняем изображение во временный графический файл.Картинка и помещаем его в область ТабличныйДокумент.Посмотрим на пример программного кода генерации штрихкода:
Функция СформироватьШтрихкодDataBar(Знач ТекстШтрихкода, Знач ЧислоСегментов = 4) Экспорт
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("png");
ПутьКУтилите = "C:\Zint\zint.exe";
// Формируем командную строку:
// -b 79: тип GS1 DataBar Expanded Stacked
// --cols: количество сегментов в одной строке
// -d: кодируемые данные
// -o: путь к выходному файлу
КоманднаяСтрока = СтрШаблон(
"""%1"" -b 79 --cols=%2 -o ""%3"" -d ""%4""",
ПутьКУтилите,
Формат(ЧислоСегментов, "ЧГ=0"),
ИмяВременногоФайла,
ТекстШтрихкода
);
КодВозврата = 0;
ЗапуститьПриложение(КоманднаяСтрока, , Истина, КодВозврата);
Если КодВозврата <> 0 Или Не Новый Файл(ИмяВременногоФайла).Существует() Тогда
ВызватьИсключение "Ошибка генерации штрихкода GS1 DataBar Expanded Stacked.";
КонецЕсли;
ИтоговаяКартинка = Новый Картинка(ИмяВременногоФайла);
Попытка
УдалитьФайлы(ИмяВременногоФайла);
Исключение
// Игнорируем блокировку временного файла
КонецПопытки;
Возврат ИтоговаяКартинка;
КонецФункции
Полученный объект Картинка затем вставляется в макет печати:
ТабДокумент = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("МакетЭтикетки");
ОбластьЭтикетки = Макет.ПолучитьОбласть("Шапка");
КартинкаШК = СформироватьШтрихкодDataBar("(01)04601234567893(3103)001500(17)251231", 4);
РисунокШК = ОбластьЭтикетки.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
РисунокШК.Картинка = КартинкаШК;
РисунокШК.РазмерКартинки = РазмерКартинки.РеальныйРазмер;
// Размещаем рисунок в границах ячеек макета
РисунокШК.Расположить(ОбластьЭтикетки.Области.ОбластьДляШтрихкода);
ТабДокумент.Вывести(ОбластьЭтикетки);
ТабДокумент.Показать();
Если печать выполняется на специализированный термопринтер (Godex, Zebra, TSC), наиболее надежным и быстрым способом является отправка готового набора команд управления напрямую в принтер без использования графических драйверов Windows.
Рассмотрим подробнее сценарии для различных принтеров:
GS1 DataBar Exp Stacked, после чего экспортируем макет в текстовый командный файл. В тексте шаблона заменяем фиксированные данные переменными подстановки (например, [ШТРИХКОД], [НАИМЕНОВАНИЕ]) и отправляем готовый текстовый поток из 1С в порт принтера.^BR (параметр типа символики 6 соответствует GS1 DataBar Expanded Stacked). В команде задаются множитель модуля, высота строки и количество сегментов. Символ FNC1 в данных экранируется символом #.Посмотрим на пример отправки текстовых команд напрямую на сетевой принтер по протоколу TCP/IP (порт 9100):
Процедура ОтправитьКомандыНаПринтер(Знач IPАдрес, Знач Порт, Знач ТекстКоманд) Экспорт
Сокет = Новый COMОбъект("MSWinsock.Winsock");
Сокет.RemoteHost = IPАдрес;
Сокет.RemotePort = Порт;
Сокет.Connect();
// Ожидаем подключения
ТекущееВремя = ТекущаяДата();
Пока Сокет.State <> 7 И (ТекущаяДата() - ТекущееВремя < 5) Цикл
// Ожидание
КонецЦикла;
Если Сокет.State = 7 Тогда
Сокет.SendData(ТекстКоманд);
Сокет.Close();
Иначе
Сокет.Close();
ВызватьИсключение "Не удалось подключиться к принтеру этикеток по адресу: " + IPАдрес;
КонецЕсли;
КонецПроцедуры
Если требуется централизованная генерация для множества рабочих мест тонкого клиента или веб-клиента, развернем небольшой внутренний веб-сервис (на базе генератора штрихкодов), изолированный от процессов 1С.
В этом случае платформа 1С отправляет запрос через объект HTTPСоединение, а полученный бинарный ответ помещается в документ:
Соединение = Новый HTTPСоединение("barcode-service.local", 8080);
Запрос = Новый HTTPЗапрос("/generate?type=databar-exp-stacked&data=" + КодироватьСтроку(ТекстКода, СпособКодированияСтроки.КодировкаURL));
Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 200 Тогда
КартинкаШК = Новый Картинка(Ответ.ПолучитьТелоКакДвоичныеДанные());
Иначе
ВызватьИсключение "Ошибка сервиса генерации штрихкодов: " + Ответ.КодСостояния;
КонецЕсли;
Данный подход полностью исключает падение процессов 1cv8.exe или rphost, так как сложная математика построения композитных штрихкодов вынесена за пределы адресного пространства 1С.