Está en la página 1de 10

Códigos de barra en reportes de Visual FoxPro

Por Luis María Guayán - Tucumán - Argentina

Contenido

En este documento se describe la forma de añadir códigos de barra a los reportes de


Visual FoxPro, para su impresión con fuentes True Type. Los códigos de barra
tratados aquí son los siguientes:

 Código 39
 Código 128
 EAN-13
 EAN-8

Para lograr esto, aparte de las fuentes True Type, se necesitan funciones definidas
por el usuario en VFP, que conviertan el texto a codificar en el formato adecuado
según cada código y cada fuente True Type. Las fuentes True Type y las funciones se
encuentran mas abajo.

Al final del documento se encuentran ejemplos de uso de las funciones, una muestra
de los resultados obtenidos en reportes de VFP, y notas para su mejor
implementación.

Códigos de Barra

Solo haremos una breve descripción de cada uno de los posibles códigos, para elegir
el mas adecuado para la aplicación que vamos a implementar.

Código 39

Este código es de longitud variable, cuya limitación en el largo la da el espacio


disponible para imprimir y la capacidad del lector de código de barra que usaremos.

El juego de caracteres del código 39 incluye 43 caracteres: los dígitos 0-9, las letras
A-Z (mayúscula solamente), el espacio y los siguientes símbolos: - + . $ / *. El "*"
es el carácter de inicio y final del código, por lo que no deberá usarse en un texto a
codificar.

Cada caracter se compone de 5 barras y 4 espacios. 3 de estos 9 elementos son


anchos (de allí el nombre "3 de 9") y 6 angostos.

El código 39 se forma de la siguiente manera:

Start + Cadena + End

Código 128
Este también es un código de longitud variable, y menos largo que el código 39.

El código 128 incluye los dígito 0-9, letras A-Z (mayúsculas y minúsculas), y todos
los caracteres estándares ASCII (en total 128 caracteres, de allí su nombre).

El código 128 se divide en tres subconjuntos A, B, y C.

 El subconjunto A incluye: los dígitos, las letras mayúsculas, y los códigos de


control.
 El subconjunto B incluye: los dígitos, las letras mayúsculas y minúsculas, y
los códigos de control.
 El subconjunto C incluye: solo los dígitos y comprime dos dígitos numéricos
en cada carácter, proporcionando una densidad excelente.

Este código tiene un dígito de control que ofrece mas seguridad en la lectura. Dicho
dígito de control se calcula con el siguiente algoritmo:

* Valor de inicio del subconjunto A = 203


* Valor de inicio del subconjunto B = 204
* Valor de inicio del subconjunto C = 205
* Valor de final de todos los subconjuntos = 206
Suma = valor del caracter de inicio del subconjunto
Por cada caracter a codificar
Suma = Suma + (valor de cada caracter * posicion)
Final de los caracteres
Dígito de control = módulo 103 de Suma

Los códigos 128 se forman de la siguiente manera:

Start + Cadena + Check_Digit + End

Código EAN-13 y EAN-8 (European Article Numbering)

El EAN-13 se utiliza por todo el mundo para las mercaderías de venta al por menor.
Es de longitud fija (13 caracteres). El EAN-8 es una versión acortada del código EAN-
13 e incluye solo 8 caracteres.

Estos códigos los asigna y controla EAN International (http://www.ean.be) y las


entidades autorizadas por EAN en cada país.

En el código Ean-13, los primeros 6 dígitos representan el país y la empresa, los


siguientes 6 dígitos representan el producto, y el restante es el dígito de control.
Aparte del país, los primeros dos o tres dígitos pueden representar por ejemplo:
libros (ISBN), periódicos (ISSN), usos internos, etc.

En el código Ean-8, los primeros 4 dígitos representan el país y la empresa, los


siguientes 3 dígitos representan el producto, y el restante es el dígito de control.

El dígito de control se calcula con el siguiente algoritmo:

Suma = 0
Por cada uno de los 12 ó 7 dígitos a codificar
Valor corrector = 1 si la posición del dígito es impar ó 3 si la
posición es par
Suma = Suma + Valor del dígito * Valor corrector
Final de los dígitos
Digito de control = 10 - módulo 10 de Suma
Si Digito de control = 10
Digito de control = 0
Final Si

Los códigos EAN se forman de la siguiente manera:

Código_País + Código_Empresa + Codigo_Artículo + Check_Digit

Fuentes True Type

Las fuentes True Type que se usan en estos ejemplo, son archivos shareware
descargados de Internet y funcionan perfectamente con las funciones para VFP
descritas mas abajo.

A las fuentes utilizadas se las puede descargar de: fuentes.zip (11,9 Kb.)

Para una mejor impresión y lectura de los códigos, se aconseja utilizar los tamaños
de fuentes que a continuación se detallan:

Fuente True Type Archivo Tamaño


3 of 9 Barcode 3of9.ttf 20 ó 22
Barcode128 Bcode128.ttf 22
EanP36Tt Ean13_36.ttf 36
EanP72Tt Ean13_72.ttf 72

Funciones en VFP

A continuación se detallan las funciones en VFP que transforman un texto al formato


de código de barra elegido.

Estas funciones se las puede descargar de: funcion.zip (1,9 Kb.)

*-----------------------------------------------------------------------
---
* FUNCTION _StrTo39(tcString)
*-----------------------------------------------------------------------
---
* Convierte un string para ser impreso con
* fuente True Type Barcode 3 of 9
* USO: _StrTo39("Codigo 39")
* RETORNA: Caracter
* AUTOR: Luis María Guayán
*-----------------------------------------------------------------------
---
FUNCTION _StrTo39(tcString)
lcRet = "*"+tcString+"*"
RETURN lcRet
ENDFUNC

*-----------------------------------------------------------------------
---
* FUNCTION _StrTo128A(tcString)
*-----------------------------------------------------------------------
---
* Convierte un string para ser impreso con
* fuente True Type Barcode 128 A
* Caracteres numéricos y alfabéticos (solo mayúsculas)
* Si un caracter es no válido lo reemplaza por espacio
* USO: _StrTo128A("CODIGO 128")
* RETORNA: Caracter
* AUTOR: Luis María Guayán
*-----------------------------------------------------------------------
---
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
*--- Esto es para cambiar los espacios y caracteres invalidos
lcRet = STRTRAN(lcRet, CHR(32), CHR(232))
lcRet = STRTRAN(lcRet, CHR(127), CHR(192))
*---
RETURN lcRet
ENDFUNC

*-----------------------------------------------------------------------
---
* FUNCTION _StrTo128B(tcString)
*-----------------------------------------------------------------------
---
* Convierte un string para ser impreso con
* fuente True Type Barcode 128 B
* Caracteres numéricos y alfabéticos (mayúsculas y minúsculas)
* Si un caracter es no válido lo reemplaza por espacio
* USO: _StrTo128B("Codigo 128")
* RETORNA: Caracter
* AUTOR: Luis María Guayán
*-----------------------------------------------------------------------
---
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
*--- Esto es para cambiar los espacios y caracteres invalidos
lcRet = STRTRAN(lcRet, CHR(32), CHR(232))
lcRet = STRTRAN(lcRet, CHR(127), CHR(192))
*---
RETURN lcRet
ENDFUNC

*-----------------------------------------------------------------------
---
* FUNCTION _StrTo128C(tcString)
*-----------------------------------------------------------------------
---
* Convierte un string para ser impreso con
* fuente True Type Barcode 128 C
* Solo caracteres numéricos
* USO: _StrTo128C("01234567")
* RETORNA: Caracter
* AUTOR: Luis María Guayán
*-----------------------------------------------------------------------
---
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

*--- Convierto los pares a caracteres


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
*--- Esto es para cambiar los espacios y caracteres invalidos
lcRet = STRTRAN(lcRet, CHR(32), CHR(232))
lcRet = STRTRAN(lcRet, CHR(127), CHR(192))
*---
RETURN lcRet
ENDFUNC

*-----------------------------------------------------------------------
---
* FUNCTION _StrToEan13(tcString, .T.)
*-----------------------------------------------------------------------
---
* Convierte un string para ser impreso con
* fuente True Type EAN-13
* PARAMETROS:
* tcString: Caracter de 12 dígitos (0..9)
* tlCheckD: .T. Solo genera el dígito de control
* .F. Genera dígito y caracteres a imprimir
* USO: _StrToEan13("123456789012")
* RETORNA: Caracter
* AUTOR: Luis María Guayán
*-----------------------------------------------------------------------
---
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 len = 12
RETURN ""
ENDIF
*--- Genero dígito de control
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
*--- Si solo genero dígito de control
RETURN lcRet
ENDIF

*--- Para imprimir con fuente True Type EAN13


*--- 1er. dígito (lnPri)
lnPri = VAL(LEFT(lcRet, 1))
*--- Tabla de Juegos de Caracteres
*--- según "lnPri" (¡NO CAMBIAR!)
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

*--- Caracter inicial (fuera del código)


lcIni = CHR(lnPri + 35)
*--- Caracteres lateral y central
lcLat = CHR(33)
lcMed = CHR(45)

*--- Resto de los caracteres


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
*--- Armo código
lcCod = lcIni + lcLat + SUBS(lcResto,1,6) + lcMed + SUBS(lcResto,7,6)
+ lcLat
RETURN lcCod
ENDFUNC

*-----------------------------------------------------------------------
---
* FUNCTION _StrToEan8(tcString, .T.)
*-----------------------------------------------------------------------
---
* Convierte un string para ser impreso con
* fuente True Type EAN-8
* PARAMETROS:
* tcString: Caracter de 7 dígitos (0..9)
* tlCheckD: .T. Solo genera el dígito de control
* .F. Genera dígito y caracteres a imprimir
* USO: _StrToEan8("1234567")
* RETORNA: Caracter
* AUTOR: Luis María Guayán
*-----------------------------------------------------------------------
---
FUNCTION _StrToEan8(tcString, tlCheckD)

LOCAL lcLat, lcMed, lcRet, ;


lcIni, lcCod, ;
lnI, lnCheckSum, lnAux

lcRet=ALLTRIM(tcString)

IF LEN(lcRet) # 7
*--- Error en parámetro
*--- debe tener un len = 7
RETURN ""
ENDIF

*--- Genero dígito de control


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
*--- Si solo genero dígito de control
RETURN lcRet
ENDIF

*--- Para imprimir con fuente True Type EAN8


*--- Caracteres lateral y central
lcLat = CHR(33)
lcMed = CHR(45)

*--- Caracteres
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

*--- Armo código


lcCod = lcLat + SUBS(lcRet,1,4) + lcMed + SUBS(lcRet,5,4) + lcLat
RETURN lcCod
ENDFUNC

*-----------------------------------------------------------------------
---

Ejemplos de uso

Estos son algunos ejemplos de cómo utilizar las funciones de conversión. Todas las
funciones reciben como parámetro el texto a codificar en formato CARACTER.

Ejemplo 1: Para pasar el texto "Esto es un ejemplo" al formato de código de barra


Código 128 B:

lcTexto = "Esto es un ejemplo"


lcCodBar = _StrTo128B(lcTexto)

Ejemplo 2: Para pasar el número 12345678 al formato de código de barra Código


128 C (este código solo acepta números de longitud par, si la longitud es impar,
justifica con un "0" (cero) a la izquierda):

lcTexto = "12345678"
lcCodBar = _StrTo128C(lcTexto)

Ejemplo 3: Para pasar el país Argentina ("779"), la empresa "1234" y el producto


"01234" al formato de código de barra Código EAN-13 (solo paso 12 caracteres, ya
que la función agrega y codifica el dígito de control):

lcTexto = "779123401234"
lcCodBar = _StrToEAN13(lcTexto)

Para utilizar estos códigos en reportes de VFP, se debe formatear el campo con la
fuente True Type elegida, y en la expresión se debe invocar a la función
correspondiente pasándole como parámetro el texto a codificar.

Para codificar y mostrar el campo MiCodigo de la tabla MiTabla en un campo del


reporte, en el cuadro de diálogo del campo, debemos poner por ejemplo en
Expresión: _StrTo128B(MiTabla.MiCampo).
Otra forma es crear un cursor mediante un SELECT con un campo con los datos ya
formateados y generar el informe a partir del cursor:

SELECT *, _StrTo39(MiTabla.MiCampo) as CodBar FROM MiTabla INTO CURSOR


MiCursor

Muestra de los resultados

Estos gráficos fueron generados usando las funciones y las fuentes de este
documento, en reportes de Visual FoxPro:

Notas finales

Una vez generados los reportes con códigos de barra es conveniente imprimirlos en
impresoras láser por su excelente definición, con esto no habrá ningún problema con
la lectura del código de barra.

Con las impresoras de inyección de tinta, los resultados no son óptimos y quizás
algunos lectores de código de barra no podrán leer el código en el primer "escaneo".

Estos códigos también se pueden colocar en formularios de VFP, pero solo para su
visualización, ya que ningún lector de código de barra los podrá leer del monitor.

Para usar estas funciones en FoxPro para Windows, hay que modificar algunas
sentencias que FPW no soporta.

Hasta la próxima.

También podría gustarte