Bill,

Wow, it looks like I started a small war here. That wasn't my intent - well, maybe a little, just to keep the blood pumping. I am putting the source at the end of this email, as some people don't or can't receive attachments. It's not too long. If you, or anyone else, knows how, please feel free to post it on the U2 wiki and/or Pickwiki. Post it anywhere else you'd like. Use it, share it, modify it to make it better, just share your improvements with me and don't claim it as your own. I've also done code 39, Codabar, int25 and Postnet. I haven't done codes like UPC because I didn't have a need for them. With the algorithms, I'd be glad to, just for the pleasure of doing it. And yes, I'm a Linux geek. I heartily approve of sharing knowledge, information and source code, as long as it doesn't violate someone's license or copyright. I have to express my gratitude here to Tony for QSORT. We use it a lot, and credit Tony as author.

[Excuse me for a minute, my mouse cursor just took off by itself across the screen while I was typing, and I had to see how far it would go. It crawled slowly to the left of the screen and just sat there. Spooky!!!]

It looks like Print Wizard does a whole lot more than just barcodes, and is certainly worth a serious look. I will be looking at it, and don't mind buying software that's genuinely useful to me.

This barcode routine can be used as is or adapted easily for pretty much any MV system. I've used it in Universe, Unidata, Advanced Pick, and most recently, Jbase. Since it is an MV Basic program and outputs simple escape codes, it can be used on Unix, AIX (our platform), Linux or Windows.

All the best to all who have participated in this discussion, especially Bob Rasmussen, who is a gentleman of the first order, and a hell of a developer.

Charlie

Here's the source. It may wrap a little, but should straighten out if you paste it into a wider screen. Brackets (]) in a string are probably literal value marks. Have fun!

  SUBROUTINE PRINT.BARCODE.128.HP.SUB (MESSAGE, INDENT, BAR.WIDTH, BAR.HEIGHT, 
ORIENTATION, PASSED.PARAMS)
  * Title:        PRINT.BARCODE.128.HP.SUB
  * Written by:   Charlie Noah
  * Date written: 1988
  * Print barcode in Code 128 on HP Laserjet printers
  *" (C) Copyright 1988 Charles W. Noah Associates"
  ****************************************
  *
  * Rev 02-19-2010 12:50 by:    40 charlien charlien     350 lines;  13,149 
bytes  5,271,091,321
  *
  * Start modification history
  * Mod 02 02-16-2010 CWN Modify Mod 01 to make all barcode routines consistent 
SMURF AA2001
  * Mod 01 06-25-2002 TEM Remove printer on/off. The parent process will do 
this.
  * End modification history
  *
  * Requires HP LaserJet (compatible) printer
  *
  * Specifications
  *
  * MESSAGE (passed)         - This is the actual data to be encoded.
  *
  * INDENT (passed)          - Spacing to indent message if it is printed below 
barcode.
  *
  * BAR.WIDTH (passed)       - If a whole number is passed it will be the 
number of
  *                            dots for a single bar (300 dpi).  If a number 
less
  *                            one is used it is assumed to be inches for a 
single
  *                            bar (ex .010 is the same as 3 dots).  If the 
value
  *                            is null or zero the default of 3 dots (.010") 
will be
  *                            used.  (max is 15 dots or .5")
  *
  * BAR.HEIGHT (passed)      - If a whole number is passed it will be the 
number of
  *                            dots for the overall barcode height (300 dpi). 
If a
  *                            decimal number is used, it is assumed to be 
inches.
  *                            (ex. for a 1/2 inch barcode use 150 or .5).  The
  *                            maximum is 900 dots or 3.0 inches.
  *
  * ORIENTATION (passed)     - Orientation of the barcode.  Use 'H' for 
horizontal
  *                            (lines going up and down) and 'V' for vertical. 
The
  *                            default is horizontal.
  *
  * PASSED.PARAMS (passed)   - Attr 1  = true   Print message text below barcode
  *                            Attr 2  = true   Subroutine will control printer
  *                            null             No message will print, caller 
will control printer
  *
  * PASSED.PARAMS (returned) - attr 10 = true   status code - 1   Null message
  *                                                           2   Message too 
long     (N/A)
  *                                                           3   Invalid width 
param  (N/A)
  *                                                           4   Invalid 
indent param (N/A)
  *                                                           5   Invalid 
character    (N/A)
  *                                                           0   OK
  *
  * Note: The barcode is printed from the current cursor position.  After
  *       the barcode is printed the cursor is repositioned back to its
  *       original coordinates.
  *
  * Calling program must set printer print position and close print job.
  *
  ****************************************
  *
  * Initialize
  *
  EQU BS     TO CHAR(8)
  EQU ESC    TO CHAR(27)
  *
  EQU FALSE  TO 0
  EQU TRUE   TO 1
  *
  EQU CODE.A TO 1                                                             
;* Code fields
  EQU CODE.B TO 2
  EQU CODE.C TO 3
  *
  USER.NO             = @USER.NO
  LOG.NAME            = @LOGNAME
  PHANTOM             = SYSTEM(25)
  *
  IF USER.NO >= 10000 THEN
     PHANTOM  = TRUE
  END
  *
  PROGRAM.NAME        = 'PRINT.BARCODE.128.HP.SUB'
  *
  ****************************************
  *
  * Main program
  *
  IF UNASSIGNED(PASSED.PARAMS) THEN
     PASSED.PARAMS  = ''
  END
  *
  PARAMS              = PASSED.PARAMS
  PRINT.MESSAGE.TEXT  = PARAMS<1>                                             
;* True if message text to be printed under barcode
  PRINTER.CONTROL     = PARAMS<2>                                             
;* True if this program is to turn printer on and off
  *
  * Validate parameters
  *
  * INDENT       - spaces to indent text message if printed
  * BAR.WIDTH    - width of each bar - number of dots at 300 dpi
  * BAR.HEIGHT   - barcode height - number of dots at 300 dpi
  * ORIENTATION  - H = horizontal, V = vertical
  *
  IF INDENT     = '' OR INDENT     = '0' OR NOT(NUM(INDENT))     THEN INDENT    
   = 0
  IF BAR.WIDTH  = '' OR BAR.WIDTH  = '0' OR NOT(NUM(BAR.WIDTH))  THEN BAR.WIDTH 
   = 3
  IF INDEX(BAR.WIDTH, '.', 1)                                    THEN BAR.WIDTH 
   = (BAR.WIDTH  * 300) 'R#0'
  IF BAR.WIDTH  > 15                                             THEN BAR.WIDTH 
   = 15
  *
  IF BAR.HEIGHT = '' OR BAR.HEIGHT = '0' OR NOT(NUM(BAR.HEIGHT)) THEN 
BAR.HEIGHT   = 150
  IF INDEX(BAR.HEIGHT, '.', 1)                                   THEN 
BAR.HEIGHT   = (BAR.HEIGHT * 300) 'R#0'
  IF BAR.HEIGHT > 900                                            THEN 
BAR.HEIGHT   = 900
  *
  IF NOT(ORIENTATION MATCHES 'H]V')                              THEN 
ORIENTATION  = 'H'
  *
  BEGIN CASE
  CASE MESSAGE = ''             ; STATUS.CODE  = 1                            
;* Null message
  CASE 1                        ; STATUS.CODE  = 0                            
;* OK - proceed
  END CASE
  *
  * If OK, set up and print
  *
  IF STATUS.CODE = 0 THEN
     GOSUB BUILD.BIT.TABLE
     *
     CHECK.SUM    = 0
     BAR.CNT      = 0
     X.COORD      = 0
     Y.COORD      = 0
     *
     * Print the start code
     *
     BEGIN CASE
     CASE MESSAGE[1,4] MATCHES '4N'
        CODE.FLD       = CODE.C
        BIT.TABLE.PTR  = 106
     CASE MESSAGE[1,1] < CHAR(32)                                             
;* Control character
        CODE.FLD       = CODE.A
        BIT.TABLE.PTR  = 104
     CASE TRUE
        CODE.FLD       = CODE.B
        BIT.TABLE.PTR  = 105
     END CASE
     *
   * PRINTER ON                                                               
;* Mod 01, Mod 02
     *
     IF PRINTER.CONTROL THEN                                                  
;* Mod 02
        PRINTER ON                                                            
;* Mod 02
     END                                                                      
;* Mod 02
     *
     GOSUB PRINT.BARCODE
     *
     * Print the bar code for each character
     *
     MESSAGE.LEN  = LEN(MESSAGE)
     *
     FOR CHR.PTR = 1 TO MESSAGE.LEN WHILE STATUS.CODE = 0
        BEGIN CASE
        CASE CODE.FLD # CODE.C AND MESSAGE[CHR.PTR,6] MATCHES '6N'
           BIT.TABLE.PTR  = 100                                               
;* From A or B to C
           *
           GOSUB PRINT.BARCODE
           *
           CODE.FLD       = CODE.C
        CASE CODE.FLD = CODE.C AND NOT(MESSAGE[CHR.PTR,2] MATCHES '2N')
           CHR            = MESSAGE[CHR.PTR,1]
           *
           LOCATE CHR IN BIT.TABLE<CODE.B> SETTING JUNK THEN
              BIT.TABLE.PTR  = 101                                            
;* From C to B
              *
              GOSUB PRINT.BARCODE
              *
              CODE.FLD       = CODE.B
           END ELSE
              BIT.TABLE.PTR  = 102                                            
;* From C to A
              *
              GOSUB PRINT.BARCODE
              *
              CODE.FLD       = CODE.A
           END
        END CASE
        *
        IF CODE.FLD = CODE.C THEN
           CHR      = MESSAGE[CHR.PTR,2]
           CHR.PTR += 1
        END ELSE
           CHR      = MESSAGE[CHR.PTR,1]
        END
        *
        LOCATE CHR IN BIT.TABLE<CODE.FLD> SETTING BIT.TABLE.PTR ELSE
           BEGIN CASE
           CASE CODE.FLD = CODE.A
              BIT.TABLE.PTR  = 101                                            
;* From A to B
              *
              GOSUB PRINT.BARCODE
              *
              CODE.FLD       = CODE.B
           CASE CODE.FLD = CODE.B
              BIT.TABLE.PTR  = 102                                            
;* From B to A
              *
              GOSUB PRINT.BARCODE
              *
              CODE.FLD       = CODE.A
           END CASE
           *
           LOCATE CHR IN BIT.TABLE<CODE.FLD> SETTING BIT.TABLE.PTR ELSE
              STATUS.CODE  = 5
           END
        END
        *
        IF STATUS.CODE = 0 THEN
           GOSUB PRINT.BARCODE
        END
     NEXT CHR.PTR
     *
     * Print the modulo 103 check character
     *
     IF STATUS.CODE = 0 THEN
        BIT.TABLE.PTR  = MOD(CHECK.SUM, 103) + 1
        *
        GOSUB PRINT.BARCODE
        *
        * Print the stop character
        *
        BIT.TABLE.PTR  = 107
        *
        GOSUB PRINT.BARCODE
     END
     *
     * Print message text below barcode if required
     *
     IF PRINT.MESSAGE.TEXT THEN
        *
        * Advance print position
        *
        PRINT
        PRINT
        PRINT
        *
        IF BAR.WIDTH > 150 THEN                                               
;* Width of each bar - number of dots at 300 dpi
           PRINT
        END
        *
        PRINT STR(' ', INDENT + INT(BAR.WIDTH / 4) + 10): MESSAGE
     END
     *
     * Reposition the cursor
     *
     PRINT ESC: '*p-': X.COORD: 'x-': Y.COORD: 'Y':
     *
   * PRINTER OFF                                                              
;* Mod 01, Mod 02
     *
     IF PRINTER.CONTROL THEN                                                  
;* Mod 02
        PRINTER OFF                                                           
;* Mod 02
     END                                                                      
;* Mod 02
  END
  *
  PASSED.PARAMS<10>   = STATUS.CODE
  *
  RETURN
  *
  ****************************************
  *
  * Subroutines
  *
****************
BUILD.BIT.TABLE: * Build bit table for characters
****************
  *
  BIT.TABLE           = ''
  MV.PTR              = 0
  *
  FOR ASCII.VALUE = 32 TO 95
     MV.PTR              += 1
     BIT.TABLE<1,MV.PTR>  = CHAR(ASCII.VALUE)
  NEXT ASCII.VALUE
  *
  FOR ASCII.VALUE = 0 TO 31
     MV.PTR              += 1
     BIT.TABLE<1,MV.PTR>  = CHAR(ASCII.VALUE)
  NEXT ASCII.VALUE
  *
  FOR ASCII.VALUE = 32 TO 127
     BIT.TABLE<2, ASCII.VALUE - 31>  = CHAR(ASCII.VALUE)
  NEXT ASCII.VALUE
  *
  FOR ASCII.VALUE = 0 TO 99
     BIT.TABLE<3, ASCII.VALUE + 1>  = ASCII.VALUE 'R%2'
  NEXT ASCII.VALUE
  *
  BIT.TABLE<4>        = 
'212222]222122]222221]121223]121322]131222]122213]122312'
  BIT.TABLE<4,-1>     = '132212]221213]221312]231212]112232]122132]122231'
  BIT.TABLE<4,-1>     = '113222]123122]123221]223211]221132]221231]213212'
  BIT.TABLE<4,-1>     = '223112]312131]311222]321122]321221]312212]322112'
  BIT.TABLE<4,-1>     = '322211]212123]212321]232121]111323]131123]131321'
  BIT.TABLE<4,-1>     = '112313]132113]132311]211313]231113]231311]112133'
  BIT.TABLE<4,-1>     = '112331]132131]113123]113321]133121]313121]211331'
  BIT.TABLE<4,-1>     = '231131]213113]213311]213131]311123]311321]331121'
  BIT.TABLE<4,-1>     = '312113]312311]332111]314111]221411]431111]111224'
  BIT.TABLE<4,-1>     = '111422]121124]121421]141122]141221]112214]112412'
  BIT.TABLE<4,-1>     = '122114]122411]142112]142211]241211]221114]413111'
  BIT.TABLE<4,-1>     = '241112]134111]111242]121142]121241]114212]124112'
  BIT.TABLE<4,-1>     = '124211]411212]421112]421211]212141]214121]412121'
  BIT.TABLE<4,-1>     = '111143]111341]131141]114113]114311]411113]411311'
  BIT.TABLE<4,-1>     = '113141]114131]311141]411131]211412]211214]211232'
  BIT.TABLE<4,-1>     = '2331112'
  *
  RETURN
  *
**************
PRINT.BARCODE: * Print one character of barcode
**************
  *
  BAR.PATTERN         = BIT.TABLE<4,BIT.TABLE.PTR>
  BAR.LEN             = LEN(BAR.PATTERN)
  *
  FOR BAR.PTR = 1 TO BAR.LEN STEP 2
     BAR  = BAR.PATTERN[BAR.PTR,     1]
     SPC  = BAR.PATTERN[BAR.PTR + 1, 1]
     *
     IF ORIENTATION = 'H' THEN                                                
;* Horizontal
        PRINT ESC: '*c': BAR * BAR.WIDTH: 'a': BAR.HEIGHT: 'b0P':
        *
        X.COORD.ADJUST  = (BAR * BAR.WIDTH) + (SPC * BAR.WIDTH) - 1
        *
        PRINT ESC: '*p+': X.COORD.ADJUST: 'x+0Y':
        *
        X.COORD        += X.COORD.ADJUST
     END ELSE                                                                 
;* Vertical
        PRINT ESC: '*c': BAR.HEIGHT: 'a': BAR * BAR.WIDTH: 'b0P':
        *
        Y.COORD.ADJUST  = (BAR * BAR.WIDTH) + (SPC * BAR.WIDTH) - 1
        *
        PRINT ESC: '*p+0x+': Y.COORD.ADJUST: 'Y':
        *
        Y.COORD        += Y.COORD.ADJUST
     END
  NEXT BAR.PTR
  *
  IF BAR.CNT = 0 THEN
     CHECK.SUM += (BIT.TABLE.PTR - 1)
  END ELSE
     CHECK.SUM += (BIT.TABLE.PTR - 1) * BAR.CNT
  END
  *
  BAR.CNT            += 1
  *
  RETURN
  *
  ****************************************
  *
  * End of program
  *
  END


On 05-19-2010 11:11 AM, Bill Haskett wrote:
Charlie:

Why don't you post the code on the U2 wiki, if you can figure out how, or on Pickwiki.

Bill

------------------------------------------------------------------------
Charlie Noah said the following on 5/18/2010 7:41 PM:
Marc,

If you are using a small Laserjet or a 9050, why spend extra money on hardware or software products which might tie you to a specific setup, when you can use a Basic subroutine to print your Code 128 barcode (or many other codes) anywhere on the page you want it? I've done the grunt work and written the program, which uses standard commands built into the printer. We use this program in production every day - it works. This assumes you are printing to a piece of printable stock you can feed through your printer. I will get the latest version of the program tomorrow and post it. Don't worry - I wrote it, I own it and I can share it with anyone I want.

Sorry, Tony, I have the greatest respect you you, but printing barcode is just too easy to pay a lot for it. Now, if you want to print labels, just buy a cheap barcode label printer like the ones UPS customers use (Zebra, Datamax, etc.), and send the very simple codes to it. Used or reconditioned ones are very inexpensive, and new ones aren't prohibitively expensive.

Charlie Noah
Sr. Systems Analyst
Inland Truck Parts Company

On 05-18-2010 3:45 PM, Caminiti, Marc wrote:
Quick, maybe not necessarily U2 related, question.  We are looking to
generate Code 128 Barcodes from an HP LaserJet printer.  Testing on a
4050, but the production printer (yet to be purchased) will be an HP
LaserJet 9050.



I'm leaning toward using a soft font, but was wondering if anyone out
there had any luck with a particular font and see what is being used out
there.



Thanks in advance

marc



Marc Caminiti

IS Manager

Nashbar Direct, Inc

6103 State Route 446

Canfield, OH 44406

330.533.1989, ext 336

330.702.9733, fax



All generalisations are dangerous, even this one.





CONFIDENTIALITY NOTICE: This e-mail and any attachments may contain confidential information that is legally privileged. The information is solely for the use of the intended recipient(s). Any disclosure, copying, distribution, or other use of this information is strictly prohibited. If you have received this e-mail in error, please notify the sender by return e-mail and delete this message.

_______________________________________________
U2-Users mailing list
U2-Users@listserver.u2ug.org
http://listserver.u2ug.org/mailman/listinfo/u2-users

_______________________________________________
U2-Users mailing list
U2-Users@listserver.u2ug.org
http://listserver.u2ug.org/mailman/listinfo/u2-users
_______________________________________________
U2-Users mailing list
U2-Users@listserver.u2ug.org
http://listserver.u2ug.org/mailman/listinfo/u2-users

_______________________________________________
U2-Users mailing list
U2-Users@listserver.u2ug.org
http://listserver.u2ug.org/mailman/listinfo/u2-users

Reply via email to