¡Subscríbete AHORA!

Código de Barras

Explicación de la codificación del código de barras con un fuente en VFP que te permite imprimir códigos de barras sin usar fonts u otro tipo de utilidades.

Por Luis Martínez

¿Qué producto no está, hoy en día, identificado por un código de barras? La respuesta es obvia. Muy pocos o ninguno, son los productos que hoy en día no identifican sus productos con códigos de barras.

A la pregunta de ¿qué es un código de barras? Se podría afirmar que es un sistema de identificación automática, único, normalizado y homologado que no sólo permite controlar la gestión de stocks y racionalizar el suministro de mercancías, sino que crea nuevos cauces de comunicación entre fabricantes y distribuidores.

Código Fuente
  Los suscriptores pueden conseguir el código en el fichero correspondiente a este número de la revista
  Códigos Fox.2x, VFP 3.0/5.0/60

Existen distintos tipos de codificación entre los que destacan el UPC, EAN 13, EAN 8, ... Particularmente, en España el sistema de codificación más extendido es el EAN 13. Este será el objeto de nuestro estudio y de su posterior codificación. Grafico 1

Representación del sistema EAN 13.

El sistema EAN es un conjunto de normas que homogeneizan la numeración de todos los productos de gran consumo y tiene tres características principales:

- Puede ser utilizado por fabricantes y distribuidores en el intercambio y en la mejora de las informaciones.

- Identifica la unidad del producto de forma biunívoca (un código, un producto).

- No es explicativo o significativo: toda la información está contenida en el registro de la base de datos al que se accede con el código.

- Puede recogerse datos en el punto de venta.

La representación del código EAN se efectúa mediante la visualización de 13 dígitos que identifican el producto:

- Los dos primeros dígitos/caracteres corresponden al país. Para el caso que nos ocupa decir que el código numérico asociado a nuestro país es el 84. Grafico 2

- Los cinco caracteres siguientes identifican la empresa fabricante del artículo.

- Los cinco siguientes caracteres será un número que identificará cada uno de los productos que la empresa produzca. La empresa podrá poner su propia numeración de productos.

- Por último, el dígito 13, es un dígito de control y se calcula mediante una sencillo algoritmo matemático que comentaremos más adelante. Este algoritmo elimina cualquier posibilidad de error en la lectura.

Características del símbolo

La representación del código se ha de efectuar mediante la simbolización de los dígitos de forma que puedan leerse y traducirse directamente del decodificador, que a través de la interface se comunica con el ordenador o terminal.

El símbolo estándar está formado por una serie de barras paralelas, de diferente grosor. En la parte inferior del símbolo se representa el mismo código en cifras para que sea legible.

El símbolo es de tamaño variable. Su tamaño estándar es de 37,29*26,26 mm., pero este tamaño puede variar en función de las medidas del envase o de la etiqueta. En estos casos la variación está entre el 0,8 y 2 veces el tamaño del estándar.

El dígito de control

La utilización del dígito de control tiene por objetivo el establecer un mecanismo que evite errores en el tratamiento automático de los códigos EAN.

El dígito de control es la última cifra del código EAN de un producto. Su cálculo se realiza automáticamente en función del valor de las posiciones que le preceden en el código, mediante un sencillo algoritmo.

Algoritmo para calcular el dígito de control

Los pasos a seguir a la hora de calcular el dígito de control (para este tipo de simbolización EAN-13) son: Grafico 3


Posición	13	12	11	10	9	8	7	6	5	4	3	2	1

Valores	8	4	1	2	3	4	5	6	7	8	9	0	Control
Corrector	1	3	1	3	1	3	1	3	1	3	1	3	
Valor*corrector	8	12	1	6	3	12	5	18	7	24	9	0	

1.- Multiplicamos por 1 las posiciones impares y por 3 las posiciones pares del código empezando de derecha a izquierda.

Tomemos como ejemplo el siguiente código : 841234567890 sabiendo que el 84 corresponde con el país, los siguientes 5 dígitos con la empresa y los últimos 5 dígitos con el artículo/producto.

2.- Sumamos los valores resultantes.

8+12+1+6+3+12+5+18+7+24+9+0 = 105

3.- Restamos de la decena superior ( es módulo 10) el valor de la suma de los valores resultantes. El resultado de esta operación es el valor del código de control (primera posición del código de barras).

110 - 105 = 5 ==> valor del código de control.

Otra posibilidad es dividir la suma resultante (105) por 10 siendo el resto de ésta división el valor del dígito de control.

105 / 10 = 10 Cociente y 5 de resto

El resultado final del código es:

84 12345 67890 5 (EAN-13).

¿Cómo representar gráficamente el código?

Ya sabemos qué tipo de codificación se utiliza mayoritariamente en España y como averiguar su dígito de control. Pero, ¿ cómo representar el código resultante en forma de código de barras ?

Cada carácter numérico debe tener obligatoriamente dos barras y dos espacios. Para conformar un carácter es necesario la unión de 7 módulos. Un módulo es la unidad mínima o básica del código. Visualmente, un carácter podría representarse como: Grafico 4

Este carácter se compone de 7 módulos, 2 barras y 2 espacios de diferente grosor (casualmente el grosor de los espacios es el mismo).

Por norma estándar la anchura de un módulo es de 0,33 mm. De tal forma que si un carácter dispone de 7 módulos la anchura total de un carácter será: 0,33 mm X 7 = 2,31 mm.

Los juegos de símbolos

Para poder identificar simbólicamente los caracteres numéricos usando los siete módulos se definen 3 juegos de caracteres llamados A, B y C. Cada uno de ellos tiene 10 valores (del 0 al 9), que combinan dos barras y dos espacios para los siete módulos que componen cada carácter numérico.

los juegos de caracteres se simbolizan de la siguiente maneraGrafico 5

: El juego A tiene un número impar de módulos oscuros. Por esta razón se dice que el juego de simbolización A tiene paridad impar. Los juegos B y C son juegos de simbolización con paridad par (el número de módulos oscuros es par).

Los caracteres auxiliares

Los caracteres auxiliares se componen de la siguiente forma:


Caracteres Auxiliares	Número de Módulos 
Separador lateral	3
Separador Central	5

Secuencia del módulo del separador lateralGrafico 6:

Secuencia del módulo del separador centralGrafico 7:

Como su nombre indica, el separador central está en el centro del símbolo, separando los doce caracteres simbolizados, en dos grupos de seis. Los módulos del principio y del final son claros, con lo que de ésta forma, los caracteres situados a la izquierda y a la derecha de este separador central, cambian la alineación.

Los separadores laterales indican principio y fin de las barras del símbolo. El separador lateral izquierdo se representará con los 3 módulos laterales más 11 módulos claros a la izquierdaGrafico 8.

El separador lateral derecho se representará con los tres módulos laterales más 7 módulos claros a la derechaGrafico 9.

Estos módulos claros deben de existir de tal forma que la omisión de estos, no garantizaría la correcta lectura.

El formato del símbolo EAN-13

Volviendo a nuestro código de ejemplo (84 12345 67890 5) veamos qué formato y qué simbolización tendría cada uno de los caracteres dependiendo de la posición de estos.

El formato, de izquierda a derecha y de mayor a menor posición , es el siguiente:

Según nuestro código el carácter décimo tercero es el 8 (España), como comentábamos antes, el prefijo en España es el 84. Este carácter no será representado mediante códigos de barras quedando a la izquierda del código de barras.

Según el cuadro siguiente utilizaremos la tabla de simbolización A o B para las posiciones del 7 al 12 según convenga. Del 1 al 6 utilizaremos la tabla C.

El código queda a partir de este momento de la siguiente manera : 8 412345 678905

La tabla de uso de los juegos de caracteres de simbolización en el símbolo EAN-13 es la siguiente:



13		12	11	10	9	8	7		6	5	4	3	2	1
(1)				(2)							(3)			
0		A	A	A	A	A	A							
1		A	A	B	A	B	B							
2		A	A	B	B	A	B							
3		A	A	B	B	B	A							
4		A	B	A	A	B	B				C			
5		A	B	B	A	A	B							
6		A	B	B	B	A	A							
7		A	B	A	B	A	B							
8		A	B	A	B	B	A							
9		A	B	B	A	B	A							

  • (1) Valor del décimo tercer carácter.
  • (2) Juegos de simbolización utilizados en los caracteres de la izquierda.
  • (3) Juego de simbolización utilizado en los caracteres de la derecha.

    La parte del código que es representada mediante barras tiene el siguiente formato:

    1.- El separador lateral izquierdo incluyendo los 11 módulos claros a la izquierda.

    2.- 6 caracteres numéricos, simbolizados por medio de los juegos A y B, que corresponde a los caracteres de la izquierda del símbolo.

    3.- El separador centralGrafico 10.

    4.- 6 caracteres numéricos, simbolizados por medio del juego de caracteres C, correspondientes a los caracteres de la derecha del símbolo.

    5.- El separador lateral derecho incluyendo los 7 módulos claros por la derecha.

    El siguiente cuadro detalla el número de módulos: A partir de este momento ya tenemos creado nuestro código de barras. ¿ Seremos capaces de desarrollar un programa que imprima códigos de barras ?

    Un ejemplo

    Supongamos que tenemos un producto y queremos simbolizarlo mediante códigos de barras. Una vez tenemos creado y calculado el código completo el resultado es: 84 23455 01011 0

    Comenzando por la izquierda, identificamos el primer carácter/dígito que nos indica el país. Con este número iremos a la tabla de uso de los juegos de caracteres para la simbolización de los demás caracteres. Para saber el símbolo correspondiente al carácter 3 del código anterior (posición 10) seguiremos los pasos siguientes:

  • 1.- Averiguar el valor que corresponde al carácter décimo tercero (en este caso 8).
  • 2.- Ir a la tabla de juegos de caracteres de simbolización y situarnos en la fila correspondiente al valor 8.
  • 3.- Seguidamente, nos posicionaremos en la columna correspondiente a la posición que ocupa el carácter dentro del código.
  • 4.- Esa posición en la tabla correspondería a un valor (A o B) que identificará qué juego de caracteres he de utilizar; el A o el B. En este caso, el juego a utilizar es el A.
  • 5.- Vamos a la tabla de los juegos de caracteres y nos posicionamos en la fila correspondiente al valor del carácter a simbolizar -el valor 3- y en la columna correspondiente al juego de caracteres A.
  • 6.- El contenido de esa posición en la tabla es la simbolización del carácter 3 de la posición 10 del código a representar. Si tomamos el 0 como barra clara y el 1 como barra oscura, la simbolización del carácter 3 sería 0111101. Grafico 11

    La función

    La función cdbarras(...), cuyo código más adelante se describe, nos permite sacar por impresora el código de barras del tipos EAN-13A(el más estándar en España).

    Esta función contiene una tabla llamada codigos.dbf con la siguiente descripción de registroGrafico 12

    El campo codigo contiene el tipo de descripción de códigos de barras utilizado (EAN-13). Este campo, en principio, es puramente informativo a no ser que la función permitiera la impresión de distintos tipos de códigos de barras en el que la descripción de este campo pudiera ser de utilidad.

    El campo juego contiene la tabla de simbolización que se está utilizado para cada dígito, estos van del 0 al 9 como hemos podido comprobar anteriormente.

    Por último, valor contiene la traducción a 0 y 1 del dígito dependiendo de cada tabla de simbolización (juego).

    ¿ Por qué la longitud del campo valor es 28 y no 7 que es el número de módulos de representación de cada dígito ?

    Cojamos como ejemplo el dígito 9 de la tabla de simbolización A. La disposición de los módulos sería la siguienteGrafico 13:

    Como consecuencia, el contenido del campo valor debería ser (como se explicaba antes) 0 y 1 dependiendo de si el módulo es claro u oscuro. El registro tendría que contener = 0001011.

    Todo esto es cierto, y el programa funcionaría perfectamente pero la visualización de cada barra del código sería muy estrecha(fina) y no se ajustaría a las especificaciones propias del EAN-13. Por esta causa, cada uno de los módulos al traducirlo a 0 y 1 se multiplica por 4 quedando el contenido del registro de esta manera = 0000000000001111000011111111

    Parámetros y llamada desde Fox.

    La función recibe tres parámetros que son :

    
    	- El país al que pertenece, 2 caracteres numéricos.
    	- El código de la empresa , 5 caracteres numéricos.
    	- El código del artículo, 5 caracteres numéricos.
    

    Desde la ventana de comandos de FoxPro la llamada a la función sería de la siguiente forma:

    
    	pais=84
    	empresa=12345
    	codproducto=67890
    
    	=cdbarras(pais,empresa,codproducto)
    

    El código fuente.

    El código fuente de la función es el siguiente:

    
    ***********************************************************
    ** Función: cdbarras() 
    ***********************************************************
    ** Objetivo: imprimir un código de barras a partir
    ** de una especificaciones 
    ***********************************************************
    ** Parametros :
    **	pais	-->Código del pais
    **	empresa --> Código de la empresa
    ** 	producto --> Código del producto
    ***********************************************************
    ** Funciones llamadas:	convertir()		
    ***********************************************************
    ** Procedimientos llamados: control()
    ***********************************************************
    ** Tablas utilizadas: codigos.dbf
    ***********************************************************
    ** Fecha de creación: 25-Enero-1995
    ** Versión : 1.1
    ***********************************************************
    ** Autor : Luis Martínez Pérez
    ***********************************************************
    
    FUNCTION cdbarras
    PARAMETERS pais, empresa, producto
    
    *************************************
    ** Declara variable de entorno
    *************************************
    SET TALK OFF
    *************************************
    ** Declara e inicializa variables 
    *************************************
    STORE "" TO codigo, barrasep, codbarras, lin_codigo, lin_sep, lin_blanco, parte1, parte2, digito, vercod
    esc = 27	&& define el valor ASCII chr() de la tecla ESC
    alto_barra = 300	&& Ancho de las barras
    acumulado = 20	&& Ancho de las barras que sobresalen
    esp_numeros = 10 && Espacio para los caraceres
    modulos = 7	&& Número de módulos por caracter
    car_control = 0	&& caracter de control
    posicionh = 20	&& posicion horizontal del cursor
    tablaA = 1	
    * número de registro de comienzo de los digitos 
    * de la tabla de simbolizacion A
    tablaB = 11	&& idem al anterior pero de la tabla B
    tablaC = 21	&& idem al anterior pero de la tabla C
    
    ********************************************
    ** Define los separadores del código
    ** de barras pasados a 0 y 1
    ********************************************
    lat_izq = "000000000000111100001111"
    lat_der = "111100001111000000000000000000000000000000"
    sepcentral = "00001111000011110000"
    vacio = "0000000000000000000000000000"
    cPais = ALLTRIM(STR(pais))
    * Define el parametro pais como una cadena
    cPais1 = SUBSTR(cPais,1,1)	
    * Define cPais en dos partes
    cPais2 = SUBSTR(cPais,2,1)
    cEmpresa = ALLTRIM(STR(empresa))	
     *Define el parametro empresa como una cadena
    cProducto = ALLTRIM(STR(producto))	
    * Define el parametro producto como una cadena	
    parte1 = cPais2 + cEmpresa		
    * Declara la primera parte del código
    parte2 = cProducto + ALLTRIM(STR(car_control)) 
    *Declara y define la segunda parte del código
    
    ***************************
    ** Restaura 
    ***************************
    CLOSE ALL
    CLOSE DATABASE
    CLEAR
    
    **************************************
    ** Genera el carácter de control
    **************************************
    DO control
    
    **********************************
    ** Abre a tabla codigos.dbf
    **********************************
    USE codigos ALIAS "barras"
    SELECT barras
    
    **************************************
    ** Activa la salida de impresora
    **************************************
    SET DEVICE TO PRINTER
    SET CONSOLE OFF
    ***********************************************
    ** Cálculo para la impresión del código
    ***********************************************
     codbarras = codbarras + lat_izq
     barrasep = barrasep + lat_izq 
    
    FOR contador = 1 TO LEN(parte1)
    	IF contador = 1 OR contador = 3 OR contador = 6
    		go tablaA+val(SUBSTR(parte1,contador,1))
    	ELSE
    		go tablaB+val(SUBSTR(parte1,contador,1))
    	ENDIF
    	
    	codbarras = codbarras + ALLTRIM(valor)
    	barrasep = barrasep + vacio
    ENDFOR
    
    codbarras = codbarras + sepcentral
    barrasep = barrasep + sepcentral
    
    FOR contador = 1 TO LEN(parte2)
    	go tablaC+val(SUBSTR(parte2,contador,1))
    	codbarras = codbarras + ALLTRIM(valor)
    	barrasep = barrasep + vacio
    ENDFOR
    
    codbarras = codbarras + lat_der
    barrasep = barrasep + lat_der
    
    FOR contador = 1 TO (LEN(codbarras)/modulos)
             caracter = SUBSTR(codbarras, 1 + (modulos * (contador - 1)), modulos)
             lin_codigo = lin_codigo + CHR(convertir(caracter))
    ENDFOR
    
    FOR contador = 1 TO (LEN(barrasep)/modulos)
             caracter = SUBSTR(barrasep, 1 + (modulos * (contador - 1)), modulos)
             lin_sep = lin_sep + CHR(convertir(caracter))
             lin_blanco = lin_blanco + CHR(0)
    ENDFOR
    
    *****************************************************************
    ** Configura la impresora antes de empezar a imprimir
    ** Esta configuracion es propia de las HP II en adelante.
    ** Para otras impresoras mirar en el manual que acompaña
    ** a la impresora.
    *****************************************************************
    _PSCODE = CHR(esc) + "*t300R" + ;
    		CHR(esc) + "*r0F" + ;
    		CHR(esc) + "*r1A" + ;
     		CHR(esc) + "*b0M"
    
    ***********************************************************
    ** Define cada uno de los tipos de línea que van a 
    ** ser impresas 
    ***********************************************************
    lin_codigo = "*b" + LTRIM(STR((LEN(codbarras)/modulos),10,0)) + "W" + lin_codigo
    lin_sep = "*b" + LTRIM(STR((LEN(barrasep)/modulos),10,0)) + "W" + lin_sep
    lin_blanco = "*b" + LTRIM(STR((LEN(barrasep)/modulos),10,0)) + "W" + lin_blanco
    ***********************************************************
    ** Activa la impresora si no estamos en Windows
    ************************************************************
    IF .NOT. _WINDOWS
              SET PRINTER ON
    ENDIF
    ************************************************************
    ** Realiza la impresion del código de barras
    ************************************************************
    ** Imprime un linea en blanco
    ? SPACE(posicionh)
    ******************************************************************
    ** Imprime directamente a la impresora la configuración 
    ** preestablecida
    ******************************************************************
    ??? _PSCODE
    *************************
    ** Imprime las barras
    *************************        
    FOR contador = 1 TO alto_barra
    	??? CHR(esc) + lin_codigo
    ENDFOR
    ************************************************************
    ** Imprime las barras que sobresalen por  debajo
    ************************************************************
    FOR contador = alto_barra TO (alto_barra + acumulado)
    	?? CHR(esc) + lin_sep
    ENDFOR
     **************************************************************        
    ** Imprime en blanco 'esp_numeros' puntos 
    ** para luego pode imprimir los numeros en el lugar 
    ** correcto si sobreescribir ninguna linea de codigo
    **************************************************************        
    FOR contador = (alto_barra + acumulado) TO (alto_barra + acumulado + esp_numeros)
    	??? CHR(esc) + lin_blanco
    ENDFOR
    **********************************************************
    ** Inicializa la posición del cursor en la impresora
    **********************************************************
    _PCOLNO = posicionh -1
    ******************************************************************
    ** Define la variable vercod que contiene el código entero
    ******************************************************************
    vercod = cPais1 + space(1) + cPais2 + cEmpresa + space(1) + ;
    		cproducto + alltrim(str(car_control))
    ** Imprime en la linea actual de la impresora el codigo      
    ?? vercod                    
    ***************************************************************
    ** Desactiva la impresora si no estamos en Windows
    ***************************************************************
    IF .NOT. _WINDOWS
    	SET PRINTER OFF
    ENDIF
    ******************************************************************
    ** Procedimiento : Control
    ** Objetivo : Calcula el dígito/código de control según las 
    ** 	especificaciones EAN-13 y en su caso AECOC
    **
    **  La formula utilizada es la detallada en el artículo 
    ******************************************************************
    PROCEDURE control
    ************************************************
    ** Inicializa las variables auxiliares para
    ** generar el dígito/código de control
    ************************************************
    STORE "" TO auxiliar
    STORE 0 TO dividendo, posnum, resto
    STORE 3 TO pospar
    STORE 1 TO posimpar
    STORE 10 TO divisor
    auxiliar = cPais + cEmpresa + cProducto
    * Calula el valor
    FOR contador = 1 TO LEN(auxiliar)
    	posnum=VAL(SUBSTR(auxiliar, contador,1))
    	IF MOD(contador, 2) = 0 
    		dividendo = dividendo + (posnum * pospar)
    	ELSE
    		dividendo = dividendo + (posnum * posimpar)
    	ENDIF
    ENDFOR
    resto = MOD(dividendo, divisor)
    ** car_control es el valor del caracter de control 
    car_control = divisor - resto
    RETURN
    ****************************************************************
    ** Función : convertir
    ** Objetivo : Pasa los caracteres 0 y 1 tomados de 
    ** 7 en 7 (número de módulos por carácter) 
    ** a un carácter ASCII 
    ** Recibe como parámetro una cadena de 7 caracteres
    ** del tipo "0011010" por ejemplo
    ****************************************************************
    FUNCTION convertir
    PARAMETER caracter
    ***************************************
    ** Inicializa las variables locales
    ***************************************
      STORE 0 TO val_chr
      STORE 0 TO contador1 
      
    **********************************************************
    ** Gestiona uno a uno cada dígito pasado por la 
    ** variable carácter.
    **********************************************************
    FOR contador1 = 1 TO LEN(caracter)
          IF SUBSTR(caracter, contador1, 1) = "1"
            val_chr = (2^(6 - (contador1-1))) + val_chr
          ENDIF
          
    ENDFOR
     
     ** En val_chr devuelve el valor ASCII 
    RETURN val_chr
    

    Conclusión

    A partir de esta función cada uno puede crear su propio formato de código de barras, o bien manipular la función para su uso particular o profesional.

    Luis Martínez es diplomado en informática e Ingeniero Novell

    Por Luis Martínez
    © Copyrights 1998 by FoxPress, All rights reserved
    FoxPress, Noviembre 1998