Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
23,724

Ever since coming across a QR code in my passport  (http://en.wikipedia.org/wiki/Passport_stamp#Use) I have wanted to integrate them into SAP. I like the idea of a "quick response" of data into a mobile device as I hate typing on mobile phone keyboards. This starting point lead me to a zebra crossing and then onto the Barcode Writer in Pure Postscript  (http://www.terryburton.co.uk/barcodewriter/). The Zebra Crossing   (http://code.google.com/p/zxing/)will be covered elsewhere. However through my interest in QR codes I found a method to introduce the wide variety of barcodes found in the Barcde Writer in Pure Postscript into SAP.

Now this is a technical solution and no business case is provided, but if you need or want a barcode for any reason then I am sure it will be covered in some form by the Barcode Writer in Pure Postscript. Obviously SAP includes standard barcodes, and the ADS is available. However if you want a barcode, that is available in the BWIPP and not standard SAP, for SAPscript, smartforms or ABAP list with printer controls then you could try the following method. As the solution is purely postscript based, the barcode can be printed on any postscript level 2 compatible printers. However this blog focuses on a Windows desktop solution by generating a PDF document with the barcode.

An overview of the process to an open source/freeware based barcode  in standard SAP.

) The application to do the actual barcode generation is Barcode Writer in Pure Postscript  (http://www.terryburton.co.uk/barcodewriter/postscriptbarcode.zip) (BWIPP).</p><p>) Configure ABAP list program/SAPSCRIPT/SMARTFORMS to use the device type printer controls to generate the barcode(s).

) For simplicity I use the Cute PDF writer  (http://www.cutepdf.com/products/cutepdf/writer.asp) to generate a PDF via SAPlpd. A mention must go out to Ghostscript as this is used to do the actual barcode PDF conversion. So this needs to be installed as per the instructions for Cute PDF writer.</p><p> </p><p> </p><p>So to list the steps covered in this blog,</p><p>)  Identifying the text to convert into a barcode.

)  Integrating the BWIPP code with the SAP output (through a device type). </p><p>)  Pass the text to the BWIPP code to produce the barcode.

)  Generate a PDF with the Barcode.</p><p> </p><p>_Identify the Text for the Barcode_</p><p>For example if we use the following text</p><p> "This is some text that we want to turn into a barcode" </p><p>in smartforms, sapscript and ABAP list and pass it through a SAP printer with the POST2 device type. The postscript output is sent to a file so we can check the generated postscript encoding.</p><p>1) smartforms (ASCII85  (http://en.wikipedia.org/wiki/Ascii85) encoding), internet sites to decode ASCII85 can be found here  (http://www.tools4noobs.com/online_tools/ascii85_decode/) or here  (http://www.webutils.pl/index.php?idx=ascii85).</p><p><~<oueDGm>F)Po,+EV1>F<G[=@<<W9AKZ2DKI!> s</p><p><FDi:DF`M@BBl8$2CQC%@<,jrA7Y> s<br /> <br />2) sapscript (again ASCII85 encoding)</p><p><<oueDGm>F)Po,EV1>F<G[=@<<W9AKZ2DKI!> s</p><p><FDi:DF`M@BBl8$2+CQC%@<,jrA7Y> s </p><p>3) ABAP list (HEX  encoding), an internet site to decode HEX to string can be found here</p><p><5468697320> s<br />3016 950 mt<br /><697320736f> s<br />3016 1660 mt<br /><6d65207465> s<br />3016 2370 mt<br /><7874207468> s<br />3016 3080 mt<br /><6174207765> s<br />3016 3790 mt<br /><2077616e74> s<br />3016 4500 mt<br /><20746f2074> s<br />3016 5210 mt<br /><75726e2069> s<br />3016 5920 mt<br /><6e746f2061> s<br />3016 6630 mt<br /><2062617263> s<br />3016 7340 mt<br /><6f6465> s</p><p>Now from the above list the actual text  is split across a number of lines and appears with "s" at the end of the line. The "s" is actually a defined postscript procedure for the postscript show command. The "mt" line in the ABAP list is another postscript procedure for the moveto command. Both these procedures will be important to note for later reference.</p><p>Standard formatted text can appear with the "s" command however sometimes especially if small text formatting is used other postscript procedures such as "w1" and "w2" appear. So any new form or output that requires a barcode should be output to a flat file. This is to check the file for the postscript formatting and commands used by SAP. This can be useful to note where to insert postscript commands via print controls (also for any trouble shooting). A tip for smartforms and sapscript is to search for lines with "<" and "~>" as this signals ASCII85 encoded text.  </p><p>_Integrating the BWIPP into an SAP device type_* 

What follows is how to integrate the BWIPP into a device type. For reference you can check out the one I prepared earlier. The device type is for the QR Code barcode called ZBWIPPQR.

http://bit.ly/zbwippqr

The link points to a text file ZBWIPPQR.PRI, which can be imported through transaction SPAD.

!https://weblogs.sdn.sap.com/weblogs/images/251909024/1SPADimportdevicetype.png|height=123|alt=|width...

Enter ZBWIPPQR as the object name and the system will then prompt to create a transport.

There are a few options on how to introduce the BWIPP code into the SAP output to generate the barcode. One way is with client or printer side scripting to insert the code prior to further processing. Another way is to insert the code into an SAP device type.

Inserting the code into the device type allows direct use of the Cute PDF writer without extra client side scripts/configuration. So this blog focuses on this method. I could expand on the options available in subsequent posts, depending on feedback.

SAP device types have some built in limitations that make the use of the postscript BWIPP code harder than a simple cut and paste of the code. However it is possible to integrate the BWIPP into a device type. It should be clear but to clearly state, inserting postscript programs is outside normal SAP helpdesk support.

The way a page is printed in SAP is linked to so called formats in a device type. If you take a look into a format of POST2 it looks like the following. 

Run transaction SPAD-> extended administration-> Device Types

Select Formats

Double click on DINA4, which the SAP demo programs for sapscript and smartforms use.   

Double click on ACTION Printer initialization

If you note the way the DINA4 format ACTION initilization makes a reference to another device type format with \i.  So the POST2 device type uses the POSTSCPT device type's initialization ACTION. This method of reference is used to introduce the BWIPP into SAP by referring to a number of formats sections due to the limitations in SAP. Also refer to the ACTION +end of line +(not shown).  This is used to integrate the BWIPP with the end of line  \n reference.

If you take a look at POSTSCPT format DINA4. Then the initialisation section is also the place where SAP define a number of postscript procedures, if you search the code you will come across "s" and the "mt" procedures mentioned earlier. These procedures play an important role in generating the barcodes.

ACTION page limitations

The limitations found in any ACTION page are that they are limited to 72 characters per line ,  can have a total of 255 lines and any white space at the end of a line will be truncated.

Formatting BWIPP so that it can be Inserted into the Device Type

After downloading BWIPP we need to use the barcode.ps file as this contains all barcodes supported by the BWIPP. We need to extract the appropriate code for the barcode required. The barcode.ps comments and format make it easy to extract this code.

Take QR Code as an example and the barcode.ps first needs to be manually split into 3 files. The code sections required would appear in the following text files.

1) The credits/copyright notice 

Create a new file with the code between the following lines of barcode.ps

%!PS-Adobe-2.0

   - make sure not to copy this line.

....

....

....

% END PREAMBLE

2) The encoder - generates a structured representation of the barcode

Create a new file with the code between the following sections of barcode.ps

% BEGIN ENCODER qrcode

% --DESC: QR Code

% --EXAM: http://www.terryburton.co.uk/barcodewriter/

% --EXOP: eclevel=M

% --RNDR: renmatrix

.....

.....

.....

% END ENCODER qrcode 

3) The renderer - takes the output of the encoder and generates the visual representation of the barcode.

The renderer required is stated in the encoder section of the file, so for QR Code we need the +renmatrix +renderer.

Create a new file with the code between the following sections of barcode.ps.

% BEGIN RENDERER renmatrix

.....

.....

.....

% END RENDERER renmatrix

So due to the limitation in the ACTION pages described earlier, then you need to manually split the code into lines no longer than 72 characters and the number of lines of each file is less than 255.  Also add the \n to the end of the line and check that no lines end with a space....

Or

 If you have a UNIX system then the following korn shell script can do this for each file.

#!/bin/ksh

#This script requires  that the maximum

# line size to be less than 140 characters.

  1. to overcome the ACTION page limitation, it splits lines greater than 71 characters

#adds a space to the start of the next line if the previous line ended with a space

# and splits the file every 250 lines.

#uncomment the next line for the credits file 

 #egrep -v "^$" $1 |sed "s/$/

\n/" | awk '{

#

#uncomment the next line for the encoder and renderer files.

#egrep -v "$|%" $1 |cut -f1 -d'%' |sed "s/$/

\n/" | awk '{

if ( length($0) > 71 )

{

        print substr($0,1,71)

                if ( substr($0,71,1) == " " )

                        { print " "substr($0,72) }

                else

                        {print substr($0,72)}

} else {print $0}

}

' |split -l 250 -  $.

You need to run this script against the 3 files, making sure not to remove all the comments from the credits file.  Filenames generated should have the following naming convention

encoder.ps.aa

encoder.ps.ab

Etc.

_ _

Inserting the BWIPP code into an SAP Device Type

Now we need to COPY POST2 device type to a new device type, for example called ZBWIPPQR.

Then we need to cut and paste the code into the ACTION page for the chosen format DINA4.

As shown below the QR code example required

1 ACTION for the credits

4 ACTIONs for the encoder

1 ACTION for the renderer

If the split of the encoder file was done with the UNIX script then

ZENC1 equals encoder.ps.aa

ZENC2 equals encoder.ps.ab  

ZENC3 equals encoder.ps.ac

ZENC4 equals encoder.ps.ad

To include these ACTION pages in any SAP output then we need to reference these in the initialization ACTION page as shown below.

<u>Passing the Barcode Text to the BWIPP</u>

First let's take a look at the printer controls of the SAP standard device type POST2 as we will follow this method used by SAP to control the BWIPP.

Screen shot of selected printer controls of POST2

Printer control SPMSI  uses PrintModeSimplex in plaintext.

This links to a postscript procedure in the initialisation ACTION code.

!https://weblogs.sdn.sap.com/weblogs/images/251909024/11showinitpagelink.PNG|height=238|alt=|width=53...

So now we have the BWIPP code in a device type then we need to actually use the BWIPP to generate the barcode at an appropriate place with the correct text. This will be achieved by using print controls to call postscript procedures in the same way as the SAP method above.

The postscript procedures to use BWIPP will be added to the CREDITS  ACTION PAGE.

These procedures are called at the required place via printer controls in smartforms or sapscript.

##usage: CREDITS

##DO NOT CHANGE the first two lines!

%% SAP device type put together by Robert Russell, \n

%% send any comments to rob.roosky@yahoo.com. \n

%% 2010 RJR......\n

/ctxt {\n

         2 copy length exch length add  % \n

           string dup     % string1 string2 string string\n

           4 2 roll       % string string string1 string2\n

           2 index 0 3 index\n

           % string string string1 string2 string 0 string1\n

           putinterval    % stuff the first string in.\n

           % string string string1 string2\n

          exch length exch putinterval\n

} def\n

/sqrd {bcopt /qrcode /uk.co.terryburton.bwipp findresource exec} def\n

/bct () def\n

/bchor 0 def\n

/bcver 0 def\n

/bcscx 1.0 def\n

/bcscy 1.0 def\n

/bcopt () def\n

/bcrot 0 def \n

/bwippst {\n

gsave\n

currentpoint translate\n

bcscx bcscy scale\n

bchor bcver rmoveto\n

bcrot rotate\n

} def \n

/bwippen {\n

grestore\n

/bct () def\n

/s {show} def\n

/bchor  0 def\n

/bcver  0 def\n

/bcscx  1.0 def\n

/bcscy  1.0 def\n

/bcopt () def\n

/bcrot 0 def \n

} def\n

All the postscript code is now in place in the initialisation process of the device type.

From the code above the

/ctxt  = this procedure is used to concatenate text. It is taken from the

postscript FAQ here

/sqrd  = this calls the BWIPP to create the barcode. In this example it creates a QRcode and needs to be changed to the appropriate command to call the desired barcode, check the BWIPP wiki page  (http://groups.google.com/group/postscriptbarcode/web) for the barcode required.

The first appearance of the following variables is to initialise the values.

/bct () def\n       The actual text used to create the barcode

/bchor 0 def\n      horizontal shift

/bcver 0 def\n      vertical shift

/bcscx 1.0 def\n    scale x axis

/bcscy 1.0 def\n    scale y axis

/bcopt () def\n     BWIPP options

/bcrot 0 def \n     rotation

/bwippst  = uses the variables to position/size the barcode 

/bwippen   = resets all variables and resets the "s" procedure to the show command.

Print Controls for the BWIPP

Print Control = ZBW01

The following postscript code

/s {bct exch ctxt /bct exch def}  def \n

This printer control should be placed before the text required for the barcode.

By using  "s" as a procedure we swap out the SAP procedure for "s" for the concatenate text procedure. This procedure will be called every time "s" appears in the postscript output.

For example in smartforms using the same text "This is some text that we want to turn into a barcode" . The code in postscript would appear as.

 <<oueDGm>F)Po,+EV1>F<G[=@<<W9AKZ2*DKI!> s

<FDi:DF`M@BBl8$2+CQC%@<,jrA7Y> s

 

Now by swapping out the show command for the concatenate procedure, we can build a variable "bct" with the text required. The same concatenate text procedure works for the ABAP list, so it does not matter how SAP splits the line for postscript processing. The concatenate text procedure will build the text required for every "s" line. When the ZBW02 command is called then the "bct" variable would contain +This is some text that we want to turn into a barcode in the above example.+

Print Control = ZBW02

The following postscript code

bwippst\nbct sqrd\nbwippen\n

This printer control should be placed at the end of the text required for the barcode.

The bwippst procedure sets up the position and size of the barcode. The "bct sqrd" passes the variable bct, which contains the final text from all the concatenation calls, to the BWIPP. One important action is the bwippen procedure which resets all variables and sets the "s" procedure back to the SAP show procedure.

Other Example Print Controls

Below are other print controls that can control the appearance of the barcode. There are more possibilities to create more print controls with postscript commands linked to the BWIPP procedures in the device type's CREDITS ACTION page.

Barcode Position

The BWIPP code will generate the barcode at the current position on the page. E.g. if you recall all the "mt" calls in the ABAP list example earlier, this means that the output is at a certain position on the page. This is important as you need to pass consistent length of data to get a consistent position for the barcode. We can control the barcode size and position relative to the current position on the page. The consistent positioning is only possible if a known length of characters is passed every time within one print job.

Positioning the Barcode with Print Controls

Using the current position on the page we can move postscript points  (http://en.wikipedia.org/wiki/PostScript)

ZDN01            /bcver  bcver 1 sub def\n                 moves the barcode DOWN

ZUP01            /bcver  bcver 1 add def\n                 moves the barcode UP

ZLT01             /bchor  bchor 1 sub def\n                moves the barcode LEFT

ZRT01            /bchor  bchor 1 add def\n                moves the barcode RIGHT

Barcode Size

Allow enough room for the barcodes size in the smartforms cell or sapscript page. Carriage returns can be used before the actual text of the barcode to make the required space for the barcode. 

_Scale the Barcode with Print Controls

_The barcode can be scaled along the X and Y axis.

ZSX01 /bcscx bcscx 0.1 add def\n     expand barcode on  X axis

ZSX02 /bcscx bcscx 0.1 sub def\n     shrink barcode on X scale

ZSY01 /bcscy bcscy 0.1 add def\n      expand barcode on Y axis

ZSY02 /bcscy bcscy 0.1 sub def\n      shrink barcode on Y axis

Rotate Barcode with Print Controls

/bcrot  bcrot 45 add def\n                    rotate barcode 45 degrees

See the video at the end of this blog demonstrating the use of printer controls in smartforms.

<u>Generate a PDF with the Barcode</u>

To generate a PDF file with the barcode then Cute PDF writer  (http://www.cutepdf.com/products/cutepdf/writer.asp) needs to be installed. This is a freeware program that can be used for commercial purposes. This takes the output from SAP and processes the postscript file to generate the PDF with the barcodes.

During the install ghostscript needs to be installed, so answer yes to the following prompt.

!https://weblogs.sdn.sap.com/weblogs/images/251909024/14cutepdf.PNG|height=238|alt=|width=400|src=htt...

Next a Frontend output device needs to be created in SAP. To have a dedicated front end printer for barcodes then you can rename the Cute PDF writer to match the entry in the SAP output device. Here the frontend printer name matches the name of the printer on the desktop.

!https://weblogs.sdn.sap.com/weblogs/images/251909024/15frontendprinter.PNG|height=97|alt=|width=400|...!</body>

22 Comments