14

Click here to load reader

Códigos de barra en informes

  • Upload
    ernesto

  • View
    554

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Códigos de barra en informes

Códigos de barra en informes

NUEVO: Descargue libremente la nueva clase FoxBarcode para generar códigos de barras desde Visual FoxPro, haciendo click en el siguiente enlace: http://sites.google.com/site/foxbarcode

Actualizaciones de este artículo:

2002/04/08 - Corrección del código 128 2002/08/10 - Añadido código Interleaved 2 of 5 2002/08/14 - Nuevas fuentes True Type 2004/09/15 - Añadido código Interleaved 2 of 5 con lectura humana 2005/05/05 - Ejemplo de informes para descarga 2008/04/25 - Enlace a la versión en inglés de este artículo traducida por Ricardo

Aráoz

Contenido

En este documento se describe la forma de añadir códigos de barra a los informes 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 Interleaved 2 of 5

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 y pueden ser descargadas.

Al final del documento se encuentran ejemplos de uso de las funciones, una muestra de los resultados obtenidos en informes de VFP, y notas para su mejor implementación. También se adjunta un ejemplo en VFP con dos informes para su descarga.

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.

Page 2: Códigos de barra en informes

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 = 206Suma = valor del caracter de inicio del subconjuntoPor cada caracter a codificar Suma = Suma + (valor de cada caracter * posicion)Final de los caracteresDí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.

Page 3: Códigos de barra en informes

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 = 0Por 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 correctorFinal de los dígitosDigito de control = 10 - módulo 10 de SumaSi Digito de control = 10 Digito de control = 0Final Si

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

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

Código Interleaved 2 of  5

Este es un código de longitud variable, al igual que los códigos 39 y 128.

El Interleaved 2 of 5 incluye solamente los dígitos numéricos [0..9] y comprime dos dígitos numéricos en cada carácter, proporcionando una muy buena densidad. Todos los códigos Interleaved 2 of 5 tienen una cantidad par de dígitos.

Cada par de dígitos, se codifica en un caracter formado por una serie de 5 barras y 5 espacios. 2 de cada 5 barras son anchas, de allí el nombre "2 of 5".

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:

Suma = 0Por cada uno de los 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 correctorFinal de los dígitosDigito de control = 10 - módulo 10 de SumaSi Digito de control = 10 Digito de control = 0Final Si

Los códigos Interleaved 2 of 5 se forman de la siguiente manera:

Start + Cadena + Check_Digit + End

Page 4: Códigos de barra en informes

Fuentes True Type

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

A las fuentes utilizadas se las puede descargar de: fuentes.zip (30,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

PF Barcode 39 PF_C39.ttf 20 ó 22

PF Barcode 128 PF_C128.ttf 22, 24, 26 ó 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 ó 48

PF Interleaved 2 of 5 Wide

PF_I2OF5_W.ttf 28 ó 36

PF Interleavev 2 of 5 Text

PF_I2OF5_Text.ttf 28 ó 36

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 (2,2 Kb.)

*------------------------------------------------------* FUNCTION _StrTo39(tcString) * CODIGO 39*------------------------------------------------------* Convierte un string para ser impreso con* fuente True Type "PF Barcode 39"* USO: _StrTo39('Codigo 39')* RETORNA: Caracter*------------------------------------------------------FUNCTION _StrTo39(tcString) LOCAL lcRet lcRet = '*' + tcString + '*' RETURN lcRetENDFUNC*------------------------------------------------------* FUNCTION _StrTo128A(tcString) * CODIGO 128A*------------------------------------------------------* Convierte un string para ser impreso con* fuente True Type "PF Barcode 128"* Caracteres numéricos y alfabeticos (solo mayúsculas)* Si un caracter es no válido lo remplaza por espacio* USO: _StrTo128A('CODIGO 128 A')* RETORNA: Caracter

Page 5: Códigos de barra en informes

*------------------------------------------------------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)) lcRet = STRTRAN(lcRet,CHR(128),CHR(193)) RETURN lcRetENDFUNC*------------------------------------------------------* FUNCTION _StrTo128B(tcString) * CODIGO 128B*------------------------------------------------------* Convierte un string para ser impreso con* fuente True Type "PF Barcode 128"* Caracteres numéricos y alfabeticos (mayúsculas y minúsculas)* Si un caracter es no válido lo remplaza por espacio* USO: _StrTo128B('Codigo 128 B')* RETORNA: Caracter*------------------------------------------------------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)) lcRet = STRTRAN(lcRet,CHR(128),CHR(193)) RETURN lcRetENDFUNC*------------------------------------------------------* FUNCTION _StrTo128C(tcString) * CODIGO 128C

Page 6: Códigos de barra en informes

*------------------------------------------------------* Convierte un string para ser impreso con* fuente True Type "PF Barcode 128"* Solo caracteres numéricos* USO: _StrTo128C('1234567890')* RETORNA: Caracter*------------------------------------------------------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)) lcRet = STRTRAN(lcRet,CHR(128),CHR(193)) RETURN lcRetENDFUNC*------------------------------------------------------* FUNCTION _StrToEan13(tcString,.T.) * CODIGO EAN-13*------------------------------------------------------* Convierte un string para ser impreso con* fuente True Type "PF EAN P36" ó "PF EAN P72"* 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*------------------------------------------------------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

Page 7: Códigos de barra en informes

*--- 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 PF_EAN_PXX *--- 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 lcCodENDFUNC*------------------------------------------------------* FUNCTION _StrToEan8(tcString,.T.) * CODIGO EAN-8*------------------------------------------------------* Convierte un string para ser impreso con* fuente True Type "PF EAN P36" ó "PF EAN P72"

Page 8: Códigos de barra en informes

* 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*------------------------------------------------------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 largo = 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 PF_EAN_PXX *--- 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 lcCodENDFUNC*------------------------------------------------------* FUNCTION _StrToI2of5(tcString) * INTERLEAVED 2 OF 5*------------------------------------------------------* Convierte un string para ser impreso con* fuente True Type "PF Interleaved 2 of 5" * ó "PF Interleaved 2 of 5 Wide" * ó "PF Interleaved 2 of 5 Text" * Solo caracteres numéricos* USO: _StrToI2of5('1234567890')* RETORNA: Caracter*------------------------------------------------------FUNCTION _StrToI2of5(tcString) LOCAL lcStart, lcStop, lcRet, lcCheck, ;

Page 9: Códigos de barra en informes

lcCar, lnLong, lnI, lnSum, lnAux lcStart = CHR(40) lcStop = CHR(41) lcRet = ALLTRIM(tcString) *--- Genero dígito de control 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) *--- 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 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 *--- Armo código lcRet = lcStart + lcCar + lcStop RETURN lcRetENDFUNC*------------------------------------------------------

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)? lcCodBar FONT "PF Barcode 128",36

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)? lcCodBar FONT "PF Barcode 128",36

Page 10: Códigos de barra en informes

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)? lcCodBar FONT "PF EAN P72",72

Ejemplo 4: Para pasar el número 123456789 al formato de código Interleaved 2 of 5 (este código solo acepta números de longitud par, si la longitud es impar, justifica con un "0" (cero) a la izquierda) con las tres fuentes True Type disponibles:

lcTexto = "123456789"lcCodBar = _StrToI2of5(lcTexto)*-- I 2de5 Normal? lcCodBar FONT "PF Interleaved 2 of 5",36*-- I 2de5 Ancho? lcCodBar FONT "PF Interleaved 2 of 5 Wide",36*-- I 2de5 con lectura humana (Human Readable)? lcCodBar FONT "PF Interleavev 2 of 5 Text",36

Para utilizar estos códigos en informes 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 informe, 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 informes de Visual FoxPro:

Código 39 Codigo 128 A

Código 128 B

Código 128 C

Page 11: Códigos de barra en informes

Código EAN 13 Código EAN 8

Código I 2de5 (ancho) Código Interleaved 2de5

Código I 2de5 (lectura humana)

 

Descargas

Funciones en Visual FoxPro: funcion.zip (2,2 Kb.) Fuentes True Type de códigos de barra: fuentes.zip (30,9 Kb.) Proyecto con informes de ejemplo: ejemplo.zip (16,7 Kb.)

Notas finales

Una vez generados los informes 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 barrido.

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.