Штрихкоды в Аксапте
Печать штрихового кода в Аксапте
Чтение штрихового кода
Заключение

barcode.zip (Проект для Axapta 3.0 SP4 EE, 23Kb, Для загрузки требуется регистрация на форуме у Mazzy)

Сергей Пикин, pikin@rabota-na-rezultat.ru

Использование штриховых кодов в Axapta 3.0

Большинство людей, умеющих пользоваться Интернетом, с легкостью найдут информацию о том, что такое штриховой код и для чего он нужен, поэтому не будем подробно останавливаться на этом вопросе (на всякий случай приведем пару ссылок – посмотрите тут (eng) или тут (rus)).

В общем случае, правильное использование штрихового кода позволяет сократить время ввода информации в систему и при этом значительно понизить уровень ошибок ввода за счет устранения т.н. «человеческого фактора». Конечно, под правильным использованием подразумевается не только безошибочная печать штриховых кодов и их корректное считывание сканером штрихкодов, а использование данной технологии для ускорения и улучшения качества бизнес-процессов предприятия. В рамках данной статьи не будут рассматриваться вопросы технологии применения штриховых кодов в Microsoft Axapta, задача стоит более утилитарная – на конкретных примерах показать, как напечатать и как получить штриховой код, считанный сканером штрихкодов в Microsoft Axapta, и какие механизмы используются для реализации этих задач.

 

Штрихкоды в Аксапте

До того, как в начинать работу со штрихкодами в Microsoft Axapta 3.0, необходимо выполнить настройку используемых типов штриховых кодов (Основное\Настройки\Настройка штрихового кода).

Настройка типов штрихкодов

Настройка типа штрихкода

При создании новой настройки штрихового необходимо указать его тип:

Поддерживаемые в Microsoft Axapta штрихкоды

Далее указать шрифт, используемый при печати (в правой колонке приводится коэффициент плотности шрифта, чем выше коэффициент – тем меньше плотность печати шрифта):

Шрифты для печати штрихкода

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

После настройки типов, штриховые коды номенклатуры (в форме «Управление запасами\Номенклатура» выбрать «Настройки\Штриховые коды»):

Настройка штрихкодов в номенклатуре

Форма заполнения данных о штриховом коде номенклатуры:

штрихкод в номеклатуре

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

Для каждой номенклатуры может быть указано неограниченное количество штриховых кодов. Настройки штриховых кодов для одной номенклатуры могут отличаться по типу кода, количеству единиц номенклатуры*, установками опций «Для печати» и «Сканирование»**.

* Установка значения количества единиц номенклатуры влияет на поведение системы при заполнении строк журналов прибытия модуля «Управление запасами» (автоматически заполняется поле количества номенклатуры).

** Установка опции «Для печати» влияет на поведение системы при обработке заказов (при добавлении номенклатуры, на вкладке «Прочее» подставляется штрихкод, у которого опция включена). Установка опции «Сканирование» влияет на поведение системы при заполнении строк журналов прибытия модуля «Управление запасами» (при поиске номенклатуры по штриховому коду используются штрихкоды с включенной опцией).

Разная настройка штрихового кода может использоваться, например, для разного вида упаковки одной номенклатуры товара. Скажем, штриховой код упаковки бумаги из 5 пачек отличается от штрихового кода, указанного на пачке, и тогда в настройке штрихового кода для номенклатуры «Бумага» будет две настройки, отличающиеся параметром количества.

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

В Microsoft Axapta представлены следующие отчеты, использующие при печати штриховые коды: AssetBarcode и R AssetBarcode (Штрих-коды ОС), JmgIpcBarcode (Производственные издержки), JmgProjBarcode (Деятельность по проекту), ProdRouteCard (Карта маршрута) и WMSLocationLabel (Этикетка ячейки), WMSPalletNumber (Этикетка палеты).

В Microsoft Axapta есть формы, в которых работает сканер штриховых кодов, подключенный в разрыв клавиатуры.

Сканер может использоваться при заполнении строк всех складских журналов. При ручном вводе значения в поле «Номенклатура» система осуществляет поиск по введенному значению. Поиск производится последовательно, сначала ищется соответствующий идентификатор номенклатуры, затем производится поиск по ее штриховому коду (см. рис.). При успешном поиске по штриховому коду поле «Номенклатура» заполняется кодом найденой номенклатуры.

Штрихкодсканер можно использовать для заполнения строк складских журналовШтрихкодсканер можно использовать для заполнения строк складских журналов

Сканер используется при заполнении строк журналов прибытия модуля «Управление запасами» («Управление запасами\Журналы\Прибытие товара»).

Строки журнала с возможностью работы штрихкод сканера

Примечание: Для правильной работы алгоритма данные, вводимые в поле « EAN 128/ UCC 128» должны соответствовать стандарту EAN 128/ UCC 128. Дополнительную информацию по стандарту можно получить тут. Проверить работу без сканера можно следующим образом: выберите поле « EAN 128/ UCC 128», наберите в поле 01, потом введите 14 символов штрихового кода товара (если штрихкод меньше – впереди дополняется пробелами), потом введите 30 и введите количество товара, после чего нажмите Tab. Система должна найти номенклатуру, соответствующую введенному коду и автоматически заполнить поле количества (количество будет умножено на количество, указанное в настройке штрихкода).

 

Печать штрихового кода в Аксапте

В стандартном функционале Microsoft Axapta просмотр и печать штриховых кодов реализованы с использованием TrueType-шрифтов Windows, поставляемых вместе с системой. В процессе инсталляции клиентской части программы шрифты копируются в соответствующий системный каталог операционной системы (см. рис.)

Шрифты для печати штрихкодовШрифты для печати штрихкодов

Поставляются шрифты для штриховых кодов семейств Code 128, Code39, Codabar, Interleave 2 of 5, EAN/ UPC. Шрифты для одинаковых семейств различаются по плотности и значению модуля для штрихового кода (основной размер, которому кратны все величины, определяющие размеры элементов).

В названии шрифта можно встретить следующие аббревиатуры:

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

В принципе, шрифты Axapta для штриховых кодов можно применить в любом Windows-приложении, скажем в WordPad или Word. Вводишь текст, скажем «12345», выделяешь, выбираешь нужный шрифт и на экране видишь заветные черточки. Полученный штриховой код можно распечатать на бумаге и попытаться считать его сканером, однако сканер в лучшем случае выдаст нам совсем не то, что мы напечатали, а в худшем – просто не считает наш штриховой код.

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

В Axapta 3.0 все функции, необходимые для работы со шрифтами штриховых кодов, а также функции декодирования и проверки для различных семейств штриховых кодов, реализованы в базовых классах системы.

Иерархия классов для работы со штриховыми кодами выглядит следующим образом:

Иерархия классов для работы со штрихкодами

В основе иерархии находится класс Barcode, реализующий общие функции и интерфейсы для работы со штриховыми кодами. На втором уровне иерархии находятся классы, отражающие специфику работы с различными семействами штриховых кодов (в том числе и используемые TrueType-шрифты). На третьем уровне находятся классы, определяющие индивидуальные особенности для конкретных типов штриховых кодов (количество символов, информационное наполнение и т.д.).

Основные методы классов:

Метод

Описание

construct(BarcodeType barcodeType)

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

string (boolean set = false, str _string = '', BarcodeContentType _barcodeContentType = BarcodeContentType::Undefined)

Чтение/запись строки штрихового кода

encode()

Кодирование строки штрихового кода в символах соответствующего TrueType -шрифта*

barcodeStr()

Возвращает строку штрихового кода, преобразованную с учетом набора символов соответствующего TrueType -шрифта*

barcodeStrHR()

Возвращает расшифровку штрихового кода**

* При преобразовании строки из нее удаляются все символы, не поддерживаемые выбранным семейством штриховых кодов, или генерируется сообщение об ошибке. Например, для семейства Code 39 удаляются маленькие латинские буквы, для кода EAN 13 генерируется сообщение об ошибке, если длина кодируемой строки не равна 12 символам и т.д.

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

Пример №1 (Job):

static void barCodeTest_rnr(Args _args)
{
   str           s;
   BarcodeString bs, bsHR;
   Barcode       b;
;
   s = "123456789012";

   b = Barcode::construct(BarcodeType::EAN13);
   b.string(true, s);
   b.encode();

   bs   = b.barcodeStr();
   bsHR = b.barcodeStrHR();

   info(bs);
   info(bsHR);
}

barcode info

 

Пример №2 (Отчет «Счет на оплату»):

В принципе, для того чтобы отобразить поле в отчете, содержащее штриховой код, вполне достаточно указать в свойствах поля соответствующий шрифт и указать его размеры (см. отчет AssetBarcode). В таком случае при выводе штрихового кода необходимо заранее формировать для него данные и подставлять их при выводе. Такой подход имеет свое право на существование, однако мы рассмотрим пример, в котором преобразование и форматирование данных для вывода штрихового кода производится непосредственно в отчете.

В ClassDeclaration отчета SalesPurchInvoice4Paym_RU добавляется код:

BarCode	barcodeInvoiceId;
#DEFINE.BarCodeFontSize(35)
#DEFINE.BarCodeWidth(5000)
#DEFINE.BarCodeHeight(1100) 

В методе Init() отчета:

 ReportStringControl rsc; 
 barcodeInvoiceId = BarCode::construct(BarcodeType::Code39); 
 rsc = element.design().controlName(identifierStr(InvoiceIdBarCode)); 
 rsc.visible(true); 
 rsc.font(barcodeInvoiceId.defaultfont()); 
 rsc.fontSize(#BarCodeFontSize); 
 rsc.width100mm(#BarCodeWidth); 
 rsc.height100mm(#BarCodeHeight); 
 rsc.visible(true); 

Далее добавляем display-метод для отображения штрихового кода номера счета в заголовке отчета (на рис. - InvoiceIdBarCode), создаем для него поле вывода (на рис. InvoiceIdBarCode) и задаем координаты поля:

Добавить методСвойства поля

Текст метода:

display BarcodeString InvoiceIdBarCode()
{
   BarcodeString ret;
;
 
   if (TmpSalesPurchReportTable_RU_1. InvoiceId) 
   { 
      barcodeInvoiceId.string(true,strUpr(TmpSalesPurchReportTable_RU_1.InvoiceId)); 
      barcodeInvoiceId.encode(); 
      ret = barcodeInvoiceId.barcodeStr(); 
   } 
   else 
   { 
     ret = ''; 
   } 
   return ret; 
} 

Выводим отчет на экран:

Внешний вид отчета со штрикодомВнешний вид отчета со штрикодом

Примечание: На рисунке видно, что номер счета на оплату содержит русские буквы. Необходимо учитывать, что штриховой код семейства Code 39, которым напечатан номер счета, не поддерживает кириллицу и, следовательно, эти буквы будут удалены при печати функцией проверки.

Данная форма счета на оплату может использоваться наряду с обычной формой счета, поэтому выбор текущей формы отчета лучше вынести в настройку форм (см. рис).

Настройка форм

 

Чтение штрихового кода

В стандартном функционале Axapta не предусмотрено специальных механизмов для ввода данных с использованием сканера штриховых кодов, однако, как и в любом приложении, мы можем использовать сканер штриховых кодов, подключенный в «разрыв клавиатуры» (см. рис). В этом случае пользователю необходимо предварительно выбрать поле в приложении для ввода данных, затем считать штриховой код сканером, после чего считанные данные будут введены в этом поле, как будто набраны вручную на клавиатуре.

Подключение штрихкод сканера в разрыв клавиатурыПодключение штрихкод сканера в разрыв клавиатуры

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

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

Итак, поставим перед собой задачу организовать в журнале счетов (Расчеты с клиентами\Запросы\Журналы\Счета на оплату) поиск счета на оплату по его номеру. Для поиска будем использовать штриховой код номера счета (см. Задание 1).

В качестве тестового оборудования используем сканер LS 2208 фирмы Symbol.

В комплекте программного обеспечения, поставляемого с данным сканером (также доступно для загрузки с сайта) есть специальная утилита «123 Scan», позволяющая в диалоговом режиме конфигурировать сканер и создавать расширенные правила форматирования данных, считанных сканером ( ADF), т.е фактически программировать сканер на выполнение определенной последовательности действий в зависимости от типа считанного штрихового кода, его длины и содержимого.

Используем некоторые возможности конфигурирования сканера утилитой «123 Scan»:

а) Перейдем на вкладку «ADF rules» и создадим правило форматирования считанного штрихового кода (см. рис):

  1. Эмулировать нажатие клавиши F1
  2. Эмулировать нажатие клавишей Ctrl+F
  3. Эмулировать ввод символа «*»
  4. Эмулировать ввод содержимого считанного штрихкода
  5. Эмулировать нажатие клавиши Enter

Настройка последовательности клавиш для сканераНастройка последовательности клавиш для сканера

б) Настроим сканер на чтение штрихового кода семейства Code 39 длиной 6 символов (см. рис.)

Настройка сканера на тип штрихкодаНастройка сканера на тип штрихкода

в) Сохраним полученную конфигурацию и загрузим ее в сканер.

 

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

В ClassDeclaration формы:

 #VirtualKeyCodes
 
 DLL         _hotkeyDLL; 
 DLLFunction _AxhotkeysCr; 
 DLLFunction _AxhotkeysEn; 
 DLLFunction _AxhotkeysDi; 
void overruleFKeys(boolean _enable = true) 
{ 
   #DEFINE.HotKeyDll('Axhotlib') 
   #DEFINE.HotKeyCreate('AxhotKeysCreateParm') 
   #DEFINE.HotKeyEnable('AxEnableKeys') 
   #DEFINE.HotKeyDefFile('Axhotkey.hkd') 
   #DEFINE.HotKeyDisable('AxDisableKeys')
 
   try 
   { 
      _hotkeyDLL = new DLL(#HotKeyDll); 
   } 
   catch (Exception::Internal) 
   { 
     infolog.clear(); 
     throw error("@REP34"); 
   }
 
   if (_enable) 
   { 
      if (_hotkeyDLL) 
      { 
         _AxhotkeysCr = new DLLFunction(_hotkeyDLL, #HotKeyCreate); 
         _AxhotkeysEn = new DLLFunction(_hotkeyDLL, #HotKeyEnable); 
         _AxhotkeysCr.arg(ExtTypes::STRING); 
         _AxhotkeysEn.arg(ExtTypes::STRING); 
         _AxhotkeysCr.call(xInfo::directory(DirectoryType::INCLUDE)+#HotKeyDefFile); 
         _AxhotkeysEn.call('');
      } 
   } 
   else 
   { 
      _AxhotkeysDi = new DLLFunction(_hotkeyDLL, #HotKeyCreate); 
      _AxhotkeysDi.arg(ExtTypes::STRING); 
      _AxhotkeysDi.call(''); 
   } 
} 
int checkKeyPressed() 
{ 
   DLL _winApiDLL = new DLL("USER32"); 
   DLLFunction _getAsyncKeyState = new DLLFunction(_winApiDLL, "GetAsyncKeyState"); 
   int retval; 
;
 
   _getAsyncKeyState.returns(ExtTypes::Word); 
   _getAsyncKeyState.arg(ExtTypes::DWord);
 
   if ( _getAsyncKeyState.call(#VK_F1) ) 
   { 
      retval = 1; 
   }
   return retval; 
} 
public int task(int _taskId) 
{ 
   #Task
 
   int ret; 
   int KeyPressed;
; 
   ret = super(_taskId);
 
   switch(_taskId) 
   { 
      //check ALT-key or the F-keys 
      case #taskAlt: 
         keyPressed = this.checkKeyPressed();
         switch(keyPressed) 
         { 
            case 1: 
               Invoice4PaymJour_Invoice4PaymNum.setFocus(); 
               break; 
            default: 
               break; 
         }
         break; 

      default: 
         break; 
   }//switch(_taskId) 
   return ret;
} 
element.overruleFKeys(); 
element.overruleFKeys(false); 

Сохраняем форму и открываем ее. Теперь мы можем проверить ее работу. При нажатии клавиши F1 курсор ввода попадает в поле «Счет на оплату». Нажимаем на клавиатуре Ctrl+ F. Появляется окно поиска номера счета. Вводим символ «*» и номер счета. Нажимаем Enter. Система осуществила поиск счета и вывела нам результаты поиска (см. рис)

Журнал счетов на оплату

Теперь подключаем запрограммированный нами ранее сканер штрихкодов и считываем номер счета с формы счета (см. Задание 1). Система быстро и безошибочно осуществляет те же самые действия и показывает в форме нужный счет. Таким образом, мы выполнили поставленную задачу.

 

Заключение

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

При решении более сложных задач, связанных с вводом штриховых кодов, можно использовать оборудование, подключаемое по интерфейсам RS-232 или USB. Данный вариант предполагает больше возможностей для обработки поступающих данных. Обычно в комплекте с оборудованием поставляется набор библиотек и компонент для приема/передачи данных (OPOS-драйвер и т.д.). Для оборудования, подключаемого по интерфейсу RS-232, можно использовать различные OLE-компоненты (например, Microsoft Communications control) или другие специализированные dll-библиотеки. Пример использования таких компонент в Axapta 3.0 будет приведен позднее.

Сергей Пикин, pikin@rabota-na-rezultat.ru