Microsoft Dynamics AX 2012 R3 introduces label printing capabilities. It does this by sending ZPL commands directly to a Zebra printer.
After researching the new capabilities, in tangent with the new warehouse License Plate functionality I was able to derive enough information to design my own label printing functionality.
There are several stages involved in the development process, which is a prerequisite to printing labels directly to Zebra printers.
- A label designer, which will print ZPLII code and allow for field names where data substitution needs to occur (optional).
- A table in Dynamics AX to store the design in ZPL format (memo field).
- A class that does the data substitution against the ZPL code, which then sends the resulting string of data directly to the printer.
- A printer capable of interpreting ZPL commands.
This article will explain the prerequisites, and give code examples on how to send label output directly to a Zebra printer.
Note: I do not have a Zebra printer, and even though the printer I do use, doesn't print anything it does recognize that commands are being sent to the printer. So I am concluding that should I have a Zebra prnter, the code example in this article would work. If anyone can confirm that would be great.
The first step in the process is to create a label design. Preferably a design that can be used as a template for reuse. The example I am creating will contain just one barcode. I won't go into how to create the label, that can be determined by reading the documentation for ZebraDesigner.
The next step is to print the label to a .prn file. Notice the highlighted fieldname in the text below. I came up with that field name. Later in the process that field name will get substituted with data.
Now that we have a 'template', we need to create the infrastructure in Dynamics AX to store the template and act upon it. To do this a table was created called ZPLDocumentLayout. It will store three things.
- A layout Id.
- A description of the layout.
- The ZPL code from the template. (This is a memo field in the table)
To support data entry for the table a form called ZPLDocumentLayout was created and data was populated as follows:
Notice the form has a LayoutId of 'ZPL1'. That is a code that I made up, and will use later in the process to identify which ZPL template data to use for the labels. Also notice the template data has been inserted into the record.
Next I created a table called ZPLDocumentLabel to hold the data for the labels. It is a simple table with one field called BarcodeId, and holds 3 records, whose values are 'Label1', 'Label2', 'Label3'.
Now that the underlying data, and templates exist, a class needs created specifically to do the data substitution for the template.
Create a class called ZPLDocumentPrint with the following methods.
The code for the methods are listed below:
classDeclaration
getFieldList
initMenuFields
new
printDocument
The magic in this whole process is the new CSharp project WHS.DeviceCom, which was introduced in R3. It allows communicating directly with printers with raw data.
Microsoft.Dynamics.AX.WHS.DeviceCom.Printer::SendStringToPrinter().
translate
What's fascinating about the translate method it substitutes the field names in the ZPL code, with the table field values in the ZPLDocumentLabel table by matching the field names between the ZPL code and table.
The final piece to the process is to bring it altogether and print the label data from the ZPLDocumentLabel table. I did this using a job, which invokes the ZPLDocumentPrint class. The code for the job is as follows:
The output from this article looks like this:
Please note that you might need to enable pass through mode on the printer properties, Prior to WHS.DeviceCom, the method I would use would be to send the ZPL string, wrapped in pass through codes ${ and }$ respectively.