Richard Kaye wrote:
> To our Spanish speaking members,
> 
> Would anyone here be willing.have the time to translate this article 
> from PortalFox? Or if it has been translated, point this gringo to the URL?
> 
> <http://www.portalfox.com/index.php?name=News&file=article&sid=117&mode=nested&order=0&thold=0>
> 
> or
> 
> <http://tinyurl.com/4ch8e9>
> 
> The code & fonts work very well (3 of the 7 encoding schemes scan 
> perfectly with my equipment with little effort) but I'm sure there's 
> more information in here that would be useful/helpful.
> 
> Muchas gracias
> 

Here you go Richard (see below).

Rafael, hice lo mejor que pude, tal vez te sirva de punto de partida 
para una mejor traducción. Cualquier corrección es bienvenida.
Saludos
Ricardo

------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------
CONTENTS

This document describes the way to add bar codes to VFP reports using 
True Type fonts. The bar codes with which we'll deal here are :
. Code 39
. Code 128
. EAN-13
. EAN-8
. Interleaved 2 of 5

In order to accomplish this we'll need, besides the True Type fonts, 
user defined VFP functions which will codify the input text into the 
proper format for each code and font. The True Type fonts and the 
functions can be downloaded from further down in this page.

At the bottom of this page you'll find examples on how to use these 
functions, a results sample from VFP reports, and notes for it's best 
usage. A VFP example with two reports may also be downloaded.



BAR CODES

We will briefly describe each possible code in order to help you choose 
the best fit for the app we will be deploying.

CODE 39
This is a variable length code, whose top length is given by the 
available printing space and the bar code reader we'll be using.
The character set of code 39 includes 43 characters : digits 0-9, 
letters A-Z (only upper case), space, and the following symbols: - + . / 
*. The "*" must be at the beginning and end of the code, so it shouldn't 
be used in an input text.
Each character is compose of 5 bars and 4 spaces, 3 of these 9 elements 
are wide (from there the name "3 of 9") and 6 thin elements.
Code 39 is composed of : Start + InputText + End

CODE 128
This is also a variable length code, and shorter than code 39.
Code 128 includes digits 0-9, letters A-Z (upper and lower case), and 
all standard ASCII characters (for a total of 128 characters, that's 
where the name comes from).
Code 128 is divided in three sub-sets A, B and C.
   . A includes: digits, upper case letters, and control codes.
   . B includes: digits, upper and lower case letters, and control codes.
   . C includes: only digits and compresses two digits into each 
character giving an excellent density.
This code has a control digit that offers more safety. This digit must 
be as follows:
   * initial digit for subset A = 203
   * initial digit for subset B = 204
   * initial digit for subset C = 205
   * final digit for all subsets = 206
sum = initial digit
for each inputCharacter
     sum = sum + (valueOfInputCharacter * position)
ChckDigit = sum % 103
Code 128 is composed of : Start + InputText + ChckDigit + End

EAN-13 AND EAN-8 (European Article Numbering)
EAN-13 is used world wide for retail sales. It is of fixed length (13 
characters). EAN-8 is a shortened version of EAN-13 which includes only 
8 characers.
These codes are assigned and controlled by EAN International 
(http://www.ean.be) and authorized entities in every country.
In EAN-13, the first 6 digits stand for the country and company, the 
next 6 digits stand for the product, and the last digit is a control 
digit. Besides the country, the first two or three digits may stand for: 
books (ISBN), newspapers (ISSN), internal use, etc.
In EAN-8, the first 4 digits stand for the country and company, the next 
3 digits stand for the product, and the last one is a control digit.
The control digit's algorithm is :
Sum = 0
for each InputDigit (12 or 7 digits)
     CorrectionValue = 1 if the digit's position is odd
                           3 if the digit's position is even
     Sum = Sum + ValueOfInputDigit * CorrectionValue
CheckDigit = 10 - (Sum % 10)
If CheckDigit = 10
     CheckDigit = 0
endif

EAN codes are composed of : CountryCode + CompanyCode + ProductCode + 
CheckDigit


INTERLEAVED 2 OF 5
This is a variable length code, just like Code 39 and 128.
Interleaved 2 of 5 only includes digits 0-9 and fits two digits per 
character, giving a very good density. All Interleaved 2 of 5 codes have 
an even number of digits.
Every couple of digits is codified in a character composed by 5 bars and 
5 spaces, 2 out of 5 bars are wide, hence the name "2 of 5".
This code has check digit by the following algorithm:
Sum = 0
for each InputDigit
     CorrectionValue = 1 if the digit's position is odd
                       3 if the digit's position is even
     Sum = Sum + ValueOfInputDigit * CorrectionValue
CheckDigit = 10 - (Sum % 10)
If CheckDigit = 10
     CheckDigit = 0
endif

Interleaved 2 of 5 is composed of: Start + InputText + CheckDigit + End


TRUE TYPE FONTS

The true type fonts used in these examples are freeware files and work 
perfectly with the VFP functions included below.
The fonts used here may be downloaded from: fuentes.zip (30.9 Kb)
For better printing and readability of the codes our advise is to use 
the following font sizes :
True type font                  File                    Size
PF Barcode 39                   PF_C39.ttf              20 or 22
PF Barcode 128                  PF_C128.ttf             22, 24, 26 or 28
PF EAN P36                      PF_EAN_P36.ttf          36
PF EAN P72                      PF_EAN_P72.ttf          72
PF Interleaved 2 of 5           PF_I2OF5.ttf            36 or 48
PF Interleaved 2 of 5 Wide      PF_I2OF5_W.ttf          28 or 36
PF Interleaved 2 of 5 Text      PF_I2OF5_Text.ttf       28 or 36


VFP FUNCTIONS
See below the VFP functions that transform an input text to the selected 
bar code.
These functions may be downloaded from: funcion.zip (2.2 Kb)

*------------------------------------------------------
* FUNCTION _StrTo39(tcString) * CODIGO 39
*------------------------------------------------------
* Converts a string to be printed with
* True Type Font "PF Barcode 39"
* USE: _StrTo39('Codigo 39')
* RETURNS: Character
*------------------------------------------------------
FUNCTION _StrTo39(tcString)
   LOCAL lcRet
   lcRet = '*' + tcString + '*'
   RETURN lcRet
ENDFUNC
*------------------------------------------------------
* FUNCTION _StrTo128A(tcString) * CODIGO 128A
*------------------------------------------------------
* Converts a string for printing with
* True Type Font "PF Barcode 128"
* Numerics and alphabetic (only upper case)
* If a character is not valid it is replaced by a space
* USE: _StrTo128A('CODIGO 128 A')
* RETURNS: Character
*------------------------------------------------------
FUNCTION _StrTo128A(tcString)
   LOCAL lcStart, lcStop, lcRet, lcCheck, ;
     lnLong, lnI, lnCheckSum, lnAsc
   lcStart = CHR(103 + 32)
   lcStop = CHR(106 + 32)
   lnCheckSum = ASC(lcStart) - 32
   lcRet = tcString
   lnLong = LEN(lcRet)
   FOR lnI = 1 TO lnLong
     lnAsc = ASC(SUBS(lcRet,lnI,1)) - 32
     IF NOT BETWEEN(lnAsc,0,64)
       lcRet = STUFF(lcRet,lnI,1,CHR(32))
       lnAsc = ASC(SUBS(lcRet,lnI,1)) - 32
     ENDIF
     lnCheckSum = lnCheckSum + (lnAsc * lnI)
   ENDFOR
   lcCheck = CHR(MOD(lnCheckSum,103) + 32)
   lcRet = lcStart + lcRet + lcCheck + lcStop
   *--- This changes spaces and invalid characters
   lcRet = STRTRAN(lcRet,CHR(32),CHR(232))
   lcRet = STRTRAN(lcRet,CHR(127),CHR(192))
   lcRet = STRTRAN(lcRet,CHR(128),CHR(193))
   RETURN lcRet
ENDFUNC
*------------------------------------------------------
* FUNCTION _StrTo128B(tcString) * CODIGO 128B
*------------------------------------------------------
* Converts a string to be printed with
* True Type Font "PF Barcode 128"
* Numerics and alphabetic (upper and lower case)
* If a character is not valid it is replaced by a space
* USE: _StrTo128B('Codigo 128 B')
* RETURNS: Character
*------------------------------------------------------
FUNCTION _StrTo128B(tcString)
   LOCAL lcStart, lcStop, lcRet, lcCheck, ;
     lnLong, lnI, lnCheckSum, lnAsc
   lcStart = CHR(104 + 32)
   lcStop = CHR(106 + 32)
   lnCheckSum = ASC(lcStart) - 32
   lcRet = tcString
   lnLong = LEN(lcRet)
   FOR lnI = 1 TO lnLong
     lnAsc = ASC(SUBS(lcRet,lnI,1)) - 32
     IF NOT BETWEEN(lnAsc,0,99)
       lcRet = STUFF(lcRet,lnI,1,CHR(32))
       lnAsc = ASC(SUBS(lcRet,lnI,1)) - 32
     ENDIF
     lnCheckSum = lnCheckSum + (lnAsc * lnI)
   ENDFOR
   lcCheck = CHR(MOD(lnCheckSum,103) + 32)
   lcRet = lcStart + lcRet + lcCheck + lcStop
   *--- This changes spaces and invalid characters
   lcRet = STRTRAN(lcRet,CHR(32),CHR(232))
   lcRet = STRTRAN(lcRet,CHR(127),CHR(192))
   lcRet = STRTRAN(lcRet,CHR(128),CHR(193))
   RETURN lcRet
ENDFUNC
*------------------------------------------------------
* FUNCTION _StrTo128C(tcString) * CODIGO 128C
*------------------------------------------------------
* Converts a string to be printed with
* True Type Font "PF Barcode 128"
* Only numeric characters
* USE: _StrTo128C('1234567890')
* RETURNS: Character
*------------------------------------------------------
FUNCTION _StrTo128C(tcString)
   LOCAL lcStart, lcStop, lcRet, lcCheck, lcCar, ;
     lnLong, lnI, lnCheckSum, lnAsc
   lcStart = CHR(105 + 32)
   lcStop = CHR(106 + 32)
   lnCheckSum = ASC(lcStart) - 32
   lcRet = ALLTRIM(tcString)
   lnLong = LEN(lcRet)
   *--- La longitud debe ser par
   IF MOD(lnLong,2) # 0
     lcRet = '0' + lcRet
     lnLong = LEN(lcRet)
   ENDIF
   *--- Convert couple of digits to character
   lcCar = ''
   FOR lnI = 1 TO lnLong STEP 2
     lcCar = lcCar + CHR(VAL(SUBS(lcRet,lnI,2)) + 32)
   ENDFOR
   lcRet = lcCar
   lnLong = LEN(lcRet)
   FOR lnI = 1 TO lnLong
     lnAsc = ASC(SUBS(lcRet,lnI,1)) - 32
     lnCheckSum = lnCheckSum + (lnAsc * lnI)
   ENDFOR
   lcCheck = CHR(MOD(lnCheckSum,103) + 32)
   lcRet = lcStart + lcRet + lcCheck + lcStop
   *--- This changes spaces and invalid characters
   lcRet = STRTRAN(lcRet,CHR(32),CHR(232))
   lcRet = STRTRAN(lcRet,CHR(127),CHR(192))
   lcRet = STRTRAN(lcRet,CHR(128),CHR(193))
   RETURN lcRet
ENDFUNC
*------------------------------------------------------
* FUNCTION _StrToEan13(tcString,.T.) * CODIGO EAN-13
*------------------------------------------------------
* Converts a string to be printed with
* True Type Font "PF EAN P36" or "PF EAN P72"
* PARAMETERS:
*   tcString: 12 dígit string (0..9)
*   tlCheckD: .T. Only generates check digit
*             .F. Generates check digit and characters to be printed
* USE: _StrToEan13('123456789012')
* RETURNS: Character
*------------------------------------------------------
FUNCTION _StrToEan13(tcString,tlCheckD)
   LOCAL lcLat, lcMed, lcRet, lcJuego, ;
     lcIni, lcResto, lcCod, lnI, ;
     lnCheckSum, lnAux, laJuego(10), lnPri
   lcRet = ALLTRIM(tcString)
   IF LEN(lcRet) # 12
     *--- Error en parámetro
     *--- debe tener un largo = 12
     RETURN ''
   ENDIF
   *--- Generate Check digit
   lnCheckSum = 0
   FOR lnI = 1 TO 12
     IF MOD(lnI,2) = 0
       lnCheckSum = lnCheckSum + VAL(SUBS(lcRet,lnI,1)) * 3
     ELSE
       lnCheckSum = lnCheckSum + VAL(SUBS(lcRet,lnI,1)) * 1
     ENDIF
   ENDFOR
   lnAux = MOD(lnCheckSum,10)
   lcRet = lcRet + ALLTRIM(STR(IIF(lnAux = 0,0,10-lnAux)))
   IF tlCheckD
     *--- If I only generate a check digit
     RETURN lcRet
   ENDIF
   *--- To print with True Type Font PF_EAN_PXX
   *--- 1st. dígit (lnPri)
   lnPri = VAL(LEFT(lcRet,1))
   *--- Character code table
   *--- according to 'lnPri' (¡DO NOT TOUCH!)
   laJuego(1) = 'AAAAAACCCCCC'   && 0
   laJuego(2) = 'AABABBCCCCCC'   && 1
   laJuego(3) = 'AABBABCCCCCC'   && 2
   laJuego(4) = 'AABBBACCCCCC'   && 3
   laJuego(5) = 'ABAABBCCCCCC'   && 4
   laJuego(6) = 'ABBAABCCCCCC'   && 5
   laJuego(7) = 'ABBBAACCCCCC'   && 6
   laJuego(8) = 'ABABABCCCCCC'   && 7
   laJuego(9) = 'ABABBACCCCCC'   && 8
   laJuego(10) = 'ABBABACCCCCC'   && 9
   *--- Initial character (outside the code)
   lcIni = CHR(lnPri + 35)
   *--- Lateral and central characters
   lcLat = CHR(33)
   lcMed = CHR(45)
   *--- Rest of the characters
   lcResto = SUBS(lcRet,2,12)
   FOR lnI = 1 TO 12
     lcJuego = SUBS(laJuego(lnPri + 1),lnI,1)
     DO CASE
       CASE lcJuego = 'A'
         lcResto = STUFF(lcResto,lnI,1,CHR(VAL(SUBS(lcResto,lnI,1)) + 48))
       CASE lcJuego = 'B'
         lcResto = STUFF(lcResto,lnI,1,CHR(VAL(SUBS(lcResto,lnI,1)) + 65))
       CASE lcJuego = 'C'
         lcResto = STUFF(lcResto,lnI,1,CHR(VAL(SUBS(lcResto,lnI,1)) + 97))
     ENDCASE
   ENDFOR
   *--- Compose code
   lcCod = lcIni + lcLat + SUBS(lcResto,1,6) + lcMed + ;
        SUBS(lcResto,7,6) + lcLat
   RETURN lcCod
ENDFUNC
*------------------------------------------------------
* FUNCTION _StrToEan8(tcString,.T.) * CODIGO EAN-8
*------------------------------------------------------
* Converts a string to be printed with
* True Type Font "PF EAN P36" ó "PF EAN P72"
* PARAMETERS:
*   tcString: 7 digit string (0..9)
*   tlCheckD: .T. Only generates check digit
*             .F. Generates check digit and characters to be printed
* USE: _StrToEan8('1234567')
* RETURNS: Character
*------------------------------------------------------
FUNCTION _StrToEan8(tcString,tlCheckD)
   LOCAL lcLat, lcMed, lcRet, ;
     lcIni, lcCod, lnI, ;
     lnCheckSum, lnAux
   lcRet = ALLTRIM(tcString)
   IF LEN(lcRet) # 7
     *--- Parameter error
     *--- must have length = 7
     RETURN ''
   ENDIF
   *--- Generate check digit
   lnCheckSum = 0
   FOR lnI = 1 TO 7
     IF MOD(lnI,2) = 0
       lnCheckSum = lnCheckSum + VAL(SUBS(lcRet,lnI,1)) * 1
     ELSE
       lnCheckSum = lnCheckSum + VAL(SUBS(lcRet,lnI,1)) * 3
     ENDIF
   ENDFOR
   lnAux = MOD(lnCheckSum,10)
   lcRet = lcRet + ALLTRIM(STR(IIF(lnAux = 0,0,10-lnAux)))
   IF tlCheckD
     *--- If I only generate check digit
     RETURN lcRet
   ENDIF
   *--- To print with True Type Font PF_EAN_PXX
   *--- Lateral and central characters
   lcLat = CHR(33)
   lcMed = CHR(45)
   *--- Characters
   FOR lnI = 1 TO 8
     IF lnI <= 4
       lcRet = STUFF(lcRet,lnI,1,CHR(VAL(SUBS(lcRet,lnI,1)) + 48))
     ELSE
       lcRet = STUFF(lcRet,lnI,1,CHR(VAL(SUBS(lcRet,lnI,1)) + 97))
     ENDIF
   ENDFOR
   *--- Compose code
   lcCod = lcLat + SUBS(lcRet,1,4) + lcMed + SUBS(lcRet,5,4) + lcLat
   RETURN lcCod
ENDFUNC
*------------------------------------------------------
* FUNCTION _StrToI2of5(tcString) * INTERLEAVED 2 OF 5
*------------------------------------------------------
* Converts a string to be printed with
* True Type Font "PF Interleaved 2 of 5"
* or "PF Interleaved 2 of 5 Wide"
* or "PF Interleaved 2 of 5 Text"
* Only numeric characters
* USE: _StrToI2of5('1234567890')
* RETURNS: Character
*------------------------------------------------------
FUNCTION _StrToI2of5(tcString)
   LOCAL lcStart, lcStop, lcRet, lcCheck, ;
     lcCar, lnLong, lnI, lnSum, lnAux
   lcStart = CHR(40)
   lcStop = CHR(41)
   lcRet = ALLTRIM(tcString)
   *--- Generate check digit
   lnLong = LEN(lcRet)
   lnSum = 0
   lnCount = 1
   FOR lnI = lnLong TO 1 STEP -1
     lnSum = lnSum + VAL(SUBSTR(lcRet,lnI,1)) * ;
       IIF(MOD(lnCount,2) = 0,1,3)
     lnCount = lnCount + 1
   ENDFOR
   lnAux = MOD(lnSum,10)
   lcRet = lcRet + ALLTRIM(STR(IIF(lnAux = 0,0,10 - lnAux)))
   lnLong = LEN(lcRet)
   *--- Length must be even
   IF MOD(lnLong,2) # 0
     lcRet = '0' + lcRet
     lnLong = LEN(lcRet)
   ENDIF
   *--- Convert a couple of digits to character
   lcCar = ''
   FOR lnI = 1 TO lnLong STEP 2
     IF VAL(SUBS(lcRet,lnI,2)) < 50
       lcCar = lcCar + CHR(VAL(SUBS(lcRet,lnI,2)) + 48)
     ELSE
       lcCar = lcCar + CHR(VAL(SUBS(lcRet,lnI,2)) + 142)
     ENDIF
   ENDFOR
   *--- Compose code
   lcRet = lcStart + lcCar + lcStop
   RETURN lcRet
ENDFUNC
*------------------------------------------------------


USE EXAMPLES

These are some examples on how to use the conversion functions. All 
functions have the text to be codified as a CHARACTER parameter.

Example 1: To convert text "This is an example" to Code 128 B:
cTexto = "This is an example"
lcCodBar = _StrTo128B(lcTexto)
? lcCodBar FONT "PF Barcode 128",36

Example 2: To convert number 12345678 to Code 128 C (this code only 
takes even length numbers, if length is odd then it adds a "0" to the 
left of the number):
lcTexto = "12345678"
lcCodBar = _StrTo128C(lcTexto)
? lcCodBar FONT "PF Barcode 128",36

Example 3: To convert country Argentina ("779"), the company "1234" and 
the product "01234" to EAN-13 (I can only use 12 characters, the 
thirteenth character is the check code added by the function):
lcTexto = "779123401234"
lcCodBar = _StrToEAN13(lcTexto)
? lcCodBar FONT "PF EAN P72",72

Example 4: To code number 123456789 to Interleaved 2 of 5 (this code 
only takes even length numbers, if length is odd then it adds a "0" to 
the left of the number) with the three true type fonts:
lcTexto = "123456789"
lcCodBar = _StrToI2of5(lcTexto)
*-- I 2of5 Normal
? lcCodBar FONT "PF Interleaved 2 of 5",36
*-- I 2of5 Wide
? lcCodBar FONT "PF Interleaved 2 of 5 Wide",36
*-- I 2of5 Human Readable
? lcCodBar FONT "PF Interleaved 2 of 5 Text",36

To use these codes in VFP reports, you must format the field with the 
chosen True Type font, and in the expression you must call the 
corresponding function passing as parameter the text to be codified.

To codify and show field MiCodigo from table MiTabla in a report field, 
in the field dialog window, we must input in expression: 
_StrTo128B(MiTabla.MiCampo).
Another way is to create a cursor through a SELECT with a field with the 
  data already formatted and generate the report from the cursor:
SELECT *, ;
    _StrTo39(MiTabla.MiCampo) as CodBar ;
    FROM MiTabla ;
    INTO CURSOR MiCursor

RESULTS SAMPLE
These graphics where generated using the functions and fonts in this 
document, in VFP reports:
< Here goes the sample (see the web page) >

DOWNLOADS
        . VFP Functions : funcion.zip (2.2 Kb)
        . Bar code True Type Fonts : fuentes.zip (30.9 Kb)
        . Project with sample reports : ejemplo.zip (16.7 Kb)

FINAL NOTES
Once generated the bar code reports it is convenient to print them in 
laser printers due to their excellent definition, given this there'll be 
no problems with the reading of the bar codes.
With bubble jet printers, results are not optimum and maybe some bar 
code readers wont be able to read the code in the first scan.
These codes may also be placed in VFP forms, but only for visualizing, 
as no bar code reader will be able to read them from the monitor.
In order to use these functions in FoxPro for Windows, you will have to 
modify some commands that are not supported by FPW.
------------------------------------------------------------------------------
------------------------------------------------------------------------------
------------------------------------------------------------------------------

HTH

Ricardo



_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/profox
OT-free version of this list: http://leafe.com/mailman/listinfo/profoxtech
Searchable Archive: http://leafe.com/archives/search/profox
This message: http://leafe.com/archives/byMID/profox/[EMAIL PROTECTED]
** All postings, unless explicitly stated otherwise, are the opinions of the 
author, and do not constitute legal or medical advice. This statement is added 
to the messages for those lawyers who are too stupid to see the obvious.

Reply via email to