Mostrando las entradas con la etiqueta Código de barras. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Código de barras. Mostrar todas las entradas

17 de noviembre de 2020

Códigos QR con FoxBarcodeQR v.2.25 (última version)

Actualización del 30/07/2025: Se libera una nueva versión v.2.25 de FoxBarcodeQR


FoxBarcodeQR es una clase libre que ofrece una solución alternativa para todos los desarrolladores de la comunidad de Visual FoxPro que solicitaron soporte para Códigos QR a la clase FoxBarcode. 

Ambas clases forman parte del proyecto VFPx:

FoxBarcodeQR utiliza las librerías:

Características de las librerías externas


BarCodeLibrary.dll 

  • Genera códigos QR  funcionales, pero sólo se puede establecer el tamaño y el tipo de la imagen generada. 
  • No tiene ajustes para el nivel de corrección de errores, colores y/o margenes.
  • No soporta cadenas de mas de 255 caracteres.

La librería BarCodeLibrary.dll contiene solo 3 funciones:

  • LibraryVersion: Retorna una cadena con la versión de la librería.
  • SetConfiguration: Método para establecer el tamaño y el tipo de archivo de imagen a generar.
  • GenerateFile: Método responsable de generar la imagen del código de barras QR.

QRCodeLib.dll  (versión 0.1b - www.validacfd.com)

  • Genera códigos QR funcionales con un mayor control de configuración.
  • Soporta cadenas de mas de 255 caracteres.

La librería BarCodeLib.dll contiene los métodos:

  • QRCodeLibVer: Retorna una cadena con la versión de la librería.
  • FastQRCode: Genera la imagen del código de barras QR con el texto a codificar.
  • FullQRCode: Igual que el método anterior, pero con mayor control en la generación de la imagen del código QR.
La API de Google genera códigos QR  a través de una llamada POST a una URL:
  • Requiere conexión a internet.
  • Soporta cadenas de mas de 255 caracteres.

Métodos de FoxBarcodeQR

FoxBarcodeQR encapsula las funciones de las librerías BarCodeLibrary.dll, QRCodeLib.dll y la API de Google, en métodos propios de la clase para compatibilidad con las versiones anteriores y poder seleccionar la librería a utilizar .

Los métodos de la clase FoxBarcodeQR son: 

  • QRBarcodeImage() que utiliza la librería BarCodeLibrary.dll y que recibe los siguientes parámetros:
    • tcText: Texto para codificar
    • tcFile: Nombre del archivo de imagen que desea generar. Si no se especifica ninguno, se genera un nombre de archivo aleatorio en la carpeta de archivos temporales de Windows.
    • tnSize: El tamaño de la imagen generada. Recibe un número entero entre 2 y 12
      • 2 = 66 x 66 (en píxeles)
      • 3 = 99 x 99
      • 4 = 132 x 132
      • 5 = 165 x 165
      • 6 = 198 x 198
      • 7 = 231 x 231
      • 8 = 264 x 264
      • 9 = 297 x 297
      • 10 = 330 x 330
      • 11 = 363 x 363
      • 12 = 396 x 396
    •  tnType: El tipo de archivo de imagen generado. Recibe un número entero entre 0 y 2.
      • 0 = BMP
      • 1 = JPG
      • 2 = PNG

A partir de la versión 2.0 de FoxBarcodeQR, los nuevos métodos añadidos utilizan la librería QRCodeLib.dll v.01b (www.validacfd.com)

  • FullQRCodeImage() que recibe los mismos parámetros que QRBarcodeImage()
    •  tcText: Texto para codificar
    • tcFile: Nombre del archivo de imagen que desea generar. Si no se especifica ninguno, se genera un nombre de archivo aleatorio en la carpeta de archivos temporales de Windows.
    • tnSize: El ancho y alto en pixeles de la imagen generada
    • tnType: (solo por compatibilidad) La librería solo genera archivo de imagen tipo 0 = BMP

Para configurar las otras opciones se utilizan las siguientes propiedades:

    • lAutoConfigurate: .T. para seleccionar una versión de código QR más grande si la cantidad de datos lo requiere.
    • lAutoFit: Trabaja conjuntamente con lAutoConfigurate
    • nBackColor: Color del fondo del código QR
    • nBarColor: Color de las barras del código QR
    • nCorrectionLevel: Nivel de corrección  de errores :
      • 0 = Nivel L ( 7 % ) 
      • 1 = Nivel M  ( 15 % ) 
      • 2 = Nivel Q ( 25% ) 
      • 3= Nivel H ( 30% )  
    • nEncoding: Algoritmo de codificación:
      • 0 = Alfabético: Codifica caracteres alfanuméricos  (digitos 0-9;  mayúsculas A-Z;  otros nueve caracteres: Espacio $ % * + – . / : )
      • 1 = Byte = 1: Codifica valores binarios ( 8-bit data) 
      • 2 = Numérico: Codifica unicamente valores numéricos (digitos 0-9) 
      • 3 = Kanji: Codifica caracteres Kanji. Los caracteres Kanji en Código QR pueden tener valores 8140-9FFC y E040-EBBF 
      • 4 = Auto:  Selección automática del algoritmo de codificación. (Recomendado)
    • nMarginPixels: Margen en pixeles
    • nModuleWidth: Tamaño de los módulos en pixeles
    • nHeight: Alto de la imagen en pixeles
    • nWidth: Ancho de la imagen en pixeles
  • FastQRCodeImage() es igual que el método FullQRCodeImage() y solo se pasa el texto a codificar. El resto se configura automáticamente, sin ningún control del usuario. 
    •  tcText: Texto para codificar
    •  tcFile: Nombre del archivo de imagen que desea generar. Si no se especifica ninguno, se genera un nombre de archivo aleatorio en la carpeta de archivos temporales de Windows.
  • GooQRCodeImage()  recibe los mismos parámetros que los métodos anteriores para uniformar la clase:
    •  tcText: Texto para codificar
    •  tcFile: Nombre del archivo de imagen que desea generar. Si no se especifica ninguno, se genera un nombre de archivo aleatorio en la carpeta de archivos temporales de Windows.
    •  tnSize: El ancho y alto en pixeles de la imagen generada
    • tnType: (solo por compatibilidad) La API solo genera archivo de imagen tipo 2 = PNG

        Esta API nos permite ajustar algunas otras propiedades como:

    •     nCorrectionLevel: Nivel de corrección  de errores :
      • 0 = Nivel L ( 7 % ) 
      • 1 = Nivel M  ( 15 % ) 
      • 2 = Nivel Q ( 25% ) 
      • 3= Nivel H ( 30% )  
    • nMarginPixels: Margen en columnas

  • SvrQRCodeImage()  recibe los mismos parámetros que los métodos anteriores para uniformar la clase:
    •  tcText: Texto para codificar
    •  tcFile: Nombre del archivo de imagen que desea generar. Si no se especifica ninguno, se genera un nombre de archivo aleatorio en la carpeta de archivos temporales de Windows.
    •  tnSize: El ancho y alto en pixeles de la imagen generada
    • tnType: Tipo de la imagen generada:  [png, gif, jpeg, jpg, svg, eps]

Todos estos métodos retornan la ruta y el nombre del archivo de la imagen generada con el código QR.

Ejemplos

En el siguiente ejemplo, se crean dos imágenes de Código QR, la primera con el método QRBarcodeImage() y la segunda con el método FullQRCodeImage():


SET PROCEDURE TO LOCFILE("FoxBarcodeQR.prg") ADITIVE
*--- Crear un objeto FoxBarcodeQR
LOCAL loFbc, lcQRImage
loFbc = CREATEOBJECT("FoxBarcodeQR")

*-- Utilizando la librería BarCodeLibrary.dll
lcQRImage1 = loFbc.QRBarcodeImage("http://vfpx.codeplex.com/wikipage?title=FoxBarcode",,6,0)

*-- Utilizando la librería QRCodeLib.dll (www.validacfd.com)
loFbc.nBackColor = RGB(0,255,255) && Yelow
loFbc.nBarColor = RGB(0,0,128) && Blue
loFbc.nCorrectionLevel = 2 && Q 25%
lcQRImage2 = loFbc.FullQRCodeImage("http://vfpx.codeplex.com/wikipage?title=FoxBarcode",,200,0)


Con BarCodeLibrary.dll

 


Con QRCodeLib.dll con mas opciones para configurar


A partir de ésta nueva versión 2.0 de FoxBarcodeQR se pueden codificar cadenas de caracteres mayores a 255 caracteres con la librería QRCodeLib.dll, y a partir de la versión 2.10 con la API de Google también. Ejemplo:

SET PROCEDURE TO LOCFILE("FoxBarcodeQR.prg") ADITIVE
*--- Create a FoxBarcodeQR object
LOCAL loFbc, lcQRImage
loFbc = CREATEOBJECT("FoxBarcodeQR")


m.lcString = ""
m.lnI = 0
DO WHILE LEN(m.lcString) < 512
  m.lnI = m.lnI + 1
  m.lcString = m.lcString + TRANSFORM(m.lnI) + ". - FoxbarcodeQR - "
ENDDO


*-- Using the QRCodeLib.dll library)
lcQRImage = loFbc.FullQRCodeImage(lcString,,330)

*-- Using the QR Server API
lcQRImage = loFbc.SvrQRCodeImage(lcString,,330))



Con QRCodeLib.dll

Con la API de QR Server


Para incluir un código de barras QR en un informe, se debe insertar un objeto Image y establecer la propiedad "ControlSource" con una llamada al método QRBarcodeImage(), FullQRCodeImage() o GooQRCodeImage(). Se recomienda ajustar "Escala de contenidos, mantener la forma" si el tamaño de la imagen difiere de la estructura.


Código QR en informes

Importante: Antes de ejecutar el informe y crear el objeto FoxBarcodeQR, se debe declarar la variable como PRIVATE de forma que ésta tenga alcance en el informe:

*--- Crear un objeto FoxBarcodeQR privado
PRIVATE poFbc
m.poFbc = CREATEOBJECT("FoxBarcodeQR")
... 
REPORT FORM FoxBarcodeQR PREVIEW


Distribución

Los únicos archivos necesarios para ser distribuidos para que FoxBarcodeQR funcione correctamente son:

Notas sobre la distribución e instalación del archivo BarCodeLibrary.dll y QRCodeLib.dll:

  • No se registran los archivos BarCodeLibrary.dll y QRCodeLib.dll. Debe estar ambos en la misma carpeta de la aplicación o en la carpeta del sistema de Windows.
  • BarCodeLibrary.dll y QRCodeLib.dll fueron probados y funcionan en Windows XP, 7, 8 y 10 (32 y 64 bits)

12 de noviembre de 2017

Calcular el dígito de verificación para Rapipago y Pagofacil (Argentina)

En Argentina existen al menos dos redes de cobranzas extrabancarias (Rapipago y Pagofacil) que permiten el pago de facturas, servicios, etc. a través de formularios con códigos de barras que se emiten con una estructura particular para cada caso.

En primer lugar, a la cadena a codificar se le deben agregan 1 ó 2 dígitos de verificación al final. El algoritmo (en código VFP) para la generación de estos dígitos es el siguiente:

CLEAR 

lc = "1234567890123456789012345678901234567890"
? "Sin dígito de verificación...: " + lc
? "Con 1 dígito de verificación.: " + GenerarDigitoVerificador(lc, 1)
? "Con 2 dígitos de verificación: " + GenerarDigitoVerificador(lc, 2)

FUNCTION GenerarDigitoVerificador(tcCadena, tn)
  *---
  * Parámetros
  *   tcCadena = Cadena a generar el/los dígito/s de verificación
  *   tn = Cantidad de dígito/s de verificación (1 ó 2)
  * Retorno:
  *   Caracter: La cadena mas el/los dígito/s de verificación
  *---

  IF EMPTY(tn) OR NOT INLIST(tn, 1, 2)
    tn = 1
  ENDIF

  tcCadena = ALLTRIM(tcCadena)

  LOCAL lnLen, lnIni, lnSum, lcSeq, lcRet
  lnLen = LEN(tcCadena)
  lcSeq = "1" + REPLICATE("3579", CEILING(lnLen/4))
  lnSum = 0
  FOR lnIni = 1 TO lnLen
    lnSum = lnSum + VAL(SUBSTR(tcCadena, lnIni, 1)) * VAL(SUBSTR(lcSeq, lnIni, 1))
  ENDFOR
  lcRet = tcCadena + TRANSFORM(MOD(INT(lnSum / 2), 10))
  IF tn = 2
    tcCadena = ALLTRIM(lcRet)
    lnLen = LEN(tcCadena)
    lcSeq = "1" + REPLICATE("3579", CEILING(lnLen/4))
    lnSum = 0
    FOR lnIni = 1 TO lnLen
      lnSum = lnSum + VAL(SUBSTR(tcCadena, lnIni, 1)) * VAL(SUBSTR(lcSeq, lnIni, 1))
    ENDFOR
    lcRet = tcCadena + TRANSFORM(MOD(INT(lnSum / 2), 10))
  ENDIF
  RETURN lcRet
ENDFUNC

Luego de añadir los dígitos de verificación, ya se puede generar el código de barra Interleved 2 of 5 (I2of5) o Código 128 C, que son los que utilizan ambas empresas.

Si desean realizar toda la tarea con Visual FoxPro, pueden utilizar la clase FoxBarcode que soporta ambas simbologías de códigos de barra. Si utilizan el código I2of5 se debe configurar la propiedad lAddCheckDigit que no genere el dígito de control: (lAddCheckDigit = .F.)

Luis María Guayán

8 de septiembre de 2013

Documentación de FoxBarcode

FoxBarcode es una clase 100% Visual FoxPro que ofrece una herramienta para la generación de imágenes con distintas simbologías de códigos de barras, para ser usadas en informes y formularios de VFP, o exportadas a otras aplicaciones. Su uso y distribución es libre para toda la Comunidad de Visual FoxPro.

Sitio oficial de FoxBarcode: https://github.com/VFPX/FoxBarCode

Nuevo -> Última versión: 1.19 lanzada el 21/05/2019

Sitio de Descarga: https://github.com/VFPX/FoxBarCode

Características

FoxBarcode soporta las siguientes 18 simbologías lineales de códigos de barras: Código 128, Código 39, Código 39 Extendido (Full ASCII), Código 93, Código 93 Extendido (Full ASCII), Standard 2 de 5, Interleaved 2 de 5, EAN-8, EAN-13, UPC-A, UPC-E (EAN y UPC con suplementos de 2 y 5 dígitos), ITF-14, GS1/EAN/UCC-128, Codabar, Código 11, MSI / Plessey, Telepen, PostNet, RM4SCC, KIX-Code, One Track Pharmacode y Two Track Pharmacode.

FoxBarcode soporta los siguientes tipos de imagenes: JPG, BMP, GIF, PNG y TIFF

FoxBarcode genera las imágenes con la clase gpImage2 (http://sites.google.com/site/gpimage2) de Alexander Golovlev (Rusia) y Cesar Ch. (Brasil), basada en GDI+ y requiere gdiplus.dll.

FoxBarcode permite un gran control en la generación de la imagen del código de barras al poder personalizar las siguientes propiedades:
  • nImageHeight: Altura en pixeles de la imagen.
  • nImageWidth: Ancho en pixeles de la imagen. Ahora se puede configurar el ancho
  • nAlignBarcode: Alineación del código de barra con respecto a la imagen. [0=Izquierda, 1=Centro y 2=Derecha]
  • nResolution: Resolución de la imagén en DPI.  
  • nRotation: Rotación de la imagen. [0=0°, 1=90°, 2=180°, 3=270°]
  • cImageType: Tipo de la imagen generada ["JPG", "GIF", "PNG", "BMP", "TIF"]
  • cImageFile: Nombre del archivo de imagen generado. Si no se especifica, se genera un nombre de archivo aleatorio en la carpeta de archivos temporales de Windows.
  • cText: Texto a codificar.
  • nAlignText: Alineación del texto de la lectura humana. [0=Izquierda, 1=Centro, 2=Derecha]
  • lShowHumanReadableText: .T. si se muestra la lectura humana.
  • lShowCheckDigit: .T. si se muestra el dígito de control en la lectura humana.
  • lShowStartStopChars: .T. si se muestra los caracteres de inicio y final en la lectura humana.
  • cFontName: Nombre de la fuente de la lectura humana.
  • lFontBold: .T. si la fuente de la lectura humana es Negrita.
  • lFontItalic: .T. si la fuente de la lectura humana es Cursiva.
  • nFontSize: Tamaño de la letra de la lectura humana. [Recomendado = 8 ó 9]
  • nFontColor: Color de la fuente de la lectura humana. [Recomendado = Negro = RGB(0,0,0)].
  • nBackColor: Color de fondo de la imagen [Recomendado = Blanco = RGB(255,255,255)].
  • nBarsColor: Color de las barras [Recomendado = Negro = RGB(0,0,0)].
  • nBarcodeType: Tipo de la simbología de código de barra. Vea la lista de codigos de barra soportados y su Id.
  • cSet128 Set: Juego del Código 128. ["A", "B", "C" y "*" (Auto)]
  • cSupplementalText: Texto suplementario en códigos EAN y UPC.
  • lAddCheckDigit: .T. si se calcula el dígito de control. En las simbologías en donde el dígito de control es obligatorio, no se tiene en cuenta esta propiedad.
  • nBearerBar: Tipo del marco portante, solo en la simbología ITF-14.  [0=Ninguno, 1=Rectángulo, 2=Superior e inferior]
  • lUseAppId:  .T. para que FoxBarcode interprete en el código GS1/EAN/UCC-128 a los Identificadores de Aplicación (encerrados entre paréntesis).
  • nFactor: Factor de magnificación del código de barras. [1..9]
  • nMargin: Margen alrededor del código de barras. 
  • nRatio: Relación entre las barras angostas y las barras anchas en las simbologías que lo permiten.
  • lDeleteTempFiles: Permite elegir si borra o no la carpeta temporal con las imágenes temporales.
Para la generación de la imagen, solo se debe llamar al método BarcodeImage() que genera la imagen del código de barras y retorna la ruta y nombre de archivo generado.

Ahora se puede validar previamente la cadena a codificar con el método BarcodeTest()

FoxBarcode es compatible con todas las versiones de Visual FoxPro a partir de la versión 6.0

Lenguajes

Gracias a la Comunidad Mundial de VFP, se tradujeron los mensajes de FoxBarcode a los siguientes lenguajes:
  • Inglés
  • Español por VFPEncoding
  • Checo por Martin Krivka
  • Holandés por Koen Piller
  • Alemán por Stefan Wuebbe
  • Indonesio por Samir H.
  • Portugués por Cesar Ch.
  • Turco por Ugur Yilmaz
  • Filipino por Glenn Gevero
  • Francés por Samir H.
  • Serbio por Michael Kopljan
  • Italiano por Roberto Saccomanno
Ejemplos

El siguiente es un ejemplo de código para generar una imagen tipo "PNG" del código de barras "Código 128 C" con una altura de "100" pixeles y un factor de magnificación de "2":
*-- Crear el objeto
loFbc = CREATEOBJECT("FoxBarcode")

*-- Configurar las propiedades
WITH loFBC
  .cImageType = "PNG"
  .nBarcodeType = 110 && Code 128
  .cSet128 = "C" && Set 128 C
  .nImageHeight = 100
  .nFactor = 2
ENDWITH

*-- Generar la imagen 
lcImagen = loFbc.BarcodeImage("123456789012")
Desde la versión 0.11 se agregó un 3er. parámetro al método BarcodeImage() que permite configurar varias propiedades, separadas por comas. El mismo ejemplo de arriba, con el uso del 3er. parámetro.
*-- Creo el objeto
loFbc = CREATEOBJECT("FoxBarcode")
*-- Genero la imagen con sus propiedades
lcImagen = loFbc.BarcodeImage("","",[cText="123456789012", cImageType="PNG", ;
           nBarcodeType=110, cSet128="C", nImageHeight=100, nFactor=2])

La imagen generada se muestra a continuación


Otras imágenes de ejemplo cambiando solo algunas propiedades de la clase FoxBarcode





Ahora FoxBarcode soporta el código EAN/UCC/GS1 128


Para incluir un código de barras en un formulario, se debe insertar un objeto Image. Como la imagen del código de barras no existe en tiempo de diseño, la propiedad Picture tomará el nombre de la imagen cuando se llame al método BarcodeImage(), por ejemplo desde el método Refresh de Formulario, como se muestra en la siguiente figura:



Para incluir un código de barras en un Informe, se debe insertar un objeto Image y configurar la propiedad ControlSource con un llamado al método BarcodeImage() y se recomienda configurar "Scale contents, retain shape" si la imagen difiere de tamaño con el cuadro.



NOTA: Antes de ejecutar el informe y crear el objeto FoxBarcode, se debe declarar la variable como PRIVATE para que ésta tenga alcance en el informe, como se muestra a continuación:
PRIVATE poFbc
poFbc = CREATEOBJECT("FoxBarcode")
...
REPORT FORM MyReport
Distribución

Los únicos archivos necesarios que se deben distribuir para que FoxBarcode funcione correctamente son:
  • FoxBarcode.prg
  • gpImage2.prg
Estos archivos se encuentran en la carpeta \Source incluída en el archivo de la descarga.

Antes de instanciar la clase FoxBarcode, se deben ejecutar las siguientes sentencias:
SET PROCEDURE TO LOCFILE("FoxBarcode.prg"), LOCFILE("gpImage2.prg") ADDITIVE

Demo

En los archivos de la descarga, está incluido un proyecto completo de una aplicación Demo que utiliza FoxBarcode. La siguiente es una captura de pantalla de la aplicación.



La aplicación permite:
  • Configurar todas las propiedades de la clase FoxBarcode y muestrar la imagen generada automáticamente.
  • Copiar al portapapeles la imagen generada.
  • Guardar en un archivo la imagen.
  • Imprimir el código de barras.
  • Ejecutar diversos informes y formularios de ejemplo.
  • Construir un Script con el código en Visual FoxPro.
En la aplicación también se muestra una breve descripción de cada simbología de códigos de barras, según se seleccione en la lista desplegable de las simbologías.

Puede leer mas sobre este demo en: Generando códigos de barras con FoxBarcode



¿Quiénes somos?

VFPEncoding es un grupo de desarrolladores pertenecientes a la Comunidad Hispana de Visual FoxPro que creo FoxBarcode. Los miembros de VFPEncoding son:
  • Guillermo Carrero [QEPD] (Barcelona, España)
  • Luis María Guayán (Tucumán, Argentina)
Agradecimientos
  • A nuestras familias.
  • A Cesar Ch. por sus continuas ideas y colaboraciones con sus clases gpImage2 y FoxyPreviewer.

17 de febrero de 2013

Ahora FoxBarcode soporta Codigo QR

Se lanzó un complemento de FoxBarcode llamado FoxBarcodeQR para generar códigos de barra QR desde Visual FoxPro.

FoxBarcodeQR v.1.00 es un complemento de la clase FoxBarcode para generar solamente códigos de barra QR a través de la librería BarCodeLibrary.DLL de Darío Álvarez Aranda (México).

FoxBarcodeQR encapsula las funciones de la librería BarCodeLibrary y brinda una solución alternativa para todos los desarrolladores que solicitaron el soporte de FoxBarcode para el Código QR​.

Mas información sobre FoxBarcodeQR y enlaces para su descarga en los sitios oficiales de la clase en:

-- FoxBarcodeQR en Español --
https://sites.google.com/site/foxbarcode/foxbarcodeqr

-- FoxBarcodeQR en Inglés --
https://github.com/VFPX/FoxBarcodeQR

30 de julio de 2012

Códigos de Barras QR sin utilizar la API de Google.

Que tal Compañeros. Navegando por la web, encontré una dll para la generación de códigos de barra de dos dimensiones QR.

Esta Dll tiene una función llamada GenerateFile con la que de una manera simple, podemos generar el Código QR sin tantas complicaciones.

Código para generar un archivo QR:
*--------------------------------------
DECLARE INTEGER GenerateFile ;
   IN BarCodeLibrary.dll ;
   STRING cData, ;
   STRING cFileName

*- GenerateFile(Texto a codificar, Archivo a generar)
GenerateFile("href="http://comunidadvfp.blogspot.com","potalfoxQR.bmp")

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

Nota del editor:

La librería tiene también otra función que permite configurar el tamaño del código y el tipo de la imagen generada. Puede no invocarse, pero si desea cambiar los valores por omisión debe invocarla antes que la función GenerateFile
*--------------------------------------
DECLARE INTEGER SetConfiguration ;
   IN BarCodeLibrary.dll ;
   INTEGER nSize, ;           && [2..12] (Default 4)
   INTEGER nImageType         && 0=BMP, 1=JPG, 2=PNG (Default 0)

*- SetConfiguration(Tamaño, Tipo de imagen)
SetConfiguration(6,2)

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

El archivo dll y un código de ejemplo lo pueden descargar desde aquí

Solo basta recordarles que existe otro artículo sobre el tema de QR:


Hasta la próxima!!

Baltazar Moreno, Guadalajara, Jalisco, México

3 de junio de 2012

Nueva versión 1.10 de Foxbarcode

FoxBarcode es una clase 100% Visual FoxPro que ofrece una herramienta para la generación de imágenes con distintas simbologías de códigos de barras, para ser usadas en informes y formularios de VFP, o exportadas a otras aplicaciones. Su uso y distribución es libre para toda la Comunidad de Visual FoxPro.

FoxBarcode soporta las simbologías: Código 128, Código 39, Código 39 Extendido (Full ASCII), Código 93, Código 93 Extendido (Full ASCII), Standard 2 de 5, Interleaved 2 de 5, EAN-8, EAN-13, UPC-A, UPC-E (EAN y UPC con suplementos de 2 y 5 dígitos), ITF-14, GS1/EAN/UCC-128, Codabar, Código 11, MSI / Plessey, Telepen, PostNet, RM4SCC, KIX-Code, One Track Pharmacode y Two Track Pharmacode.

FoxBarcode soporta los tipos de imagenes: JPG, BMP, GIF, PNG y TIFF

Pueden descargar la nueva versión desde la página de FoxBarcode:
http://sites.google.com/site/foxbarcode

¿Que hay de nuevo?
  • Nuevo lenguaje: ITALIANO por Roberto Saccomanno
  • Cambio en la propiedad nImageWidth: Ahora se puede configurar el ancho de la imagen
  • Nueva propiedad nAlignBarcode: Permite alinear el código de barras a la izquierda, centro o derecha de la imagen.
  • Corrección de pequeños errores.

22 de junio de 2011

Decodificar QR usando ZBar

Anteriormente, publiqué un artículo para crear un código QR usando la Api de Google.

Ahora intento ejemplificar la Lectura de un QR usando la aplicación ZBar que es Open Source, y contiene unos ejecutables dentro de la carpeta BIN que en particular utilizo para este ejemplo el zbarimg.exe

Para este ejemplo, se supone que previamente se tiene "copiada" en portapapeles el QR a decodificar, usando GDI+ lo almaceno en un archivo temporal para decodificarlo.

El código es el siguiente:
SET DEFAULT TO SYS(5)+ADDBS(SYS(2003))

* --- Creamos una imagen desde el portapapeles para validar el QR ---
* --- Código de Luis María Guayan, Gracias por tus aportaciones. ---
Do System.App
loBmp = _Screen.System.Drawing.Bitmap.FromClipboard()
IF ISNULL(loBmp)
  MESSAGEBOX("Debe copiar antes la imagen del CBB al portapapeles!!",16,"Lector QR")
  RETURN
ENDIF 
uidImagen = ADDBS(SYS(2023)) + SYS(2015)+".png"
loBmp.Save(uidImagen, _Screen.System.Drawing.Imaging.ImageFormat.Png)

* --- Creamos el comando de DOS para ejecutar ZBar excelente herramienta open source ---
* --- http://zbar.sourceforge.net/  ---
lpComando = SYS(5)+ADDBS(SYS(2003))+"ZBar\zbarimg.exe -D "+uidImagen+ " > "+uidImagen+".txt"
TEXT TO xBAT NOSHOW ADDITIVE TEXTMERGE PRETEXT 7
echo off
<<lpComando>>
ENDTEXT
uidBat = ADDBS(SYS(2023)) + SYS(2015) + [.bat]
STRTOFILE(xBAT,uidBat)
zCommando = uidBat
Ejecuta(zCommando, 0)
BorraArchivo(uidBat)

* --- Ahora cargamos el contenido del QR ---
cContenidoQR = "" 
IF FILE(uidImagen+".txt")
  cContenidoQR = FILETOSTR(uidImagen+".txt")
ENDIF 
BorraArchivo(uidImagen)
BorraArchivo(uidImagen+".txt")

* --- Lo mostramos a pantalla ---
Messagebox(IIF(EMPTY(cContenidoQR),"ERROR: No se pudo leer el QR",cContenidoQR),64,"Lector QR")

*---------------------------------------------------
FUNCTION BorraArchivo(pFile)
*---------------------------------------------------
* Esta funcion elimina el archivo indicado como parametro
* si es que existe en Disco
*---------------------------------------------------
  IF FILE(pFile)
    DELETE FILE (pFile)
  ENDIF 
ENDFUNC 
*---------------------------------------------------

*---------------------------------------------------
FUNCTION Ejecuta(cComando, iStatus)
*---------------------------------------------------
*!* Esta funcion ejecuta un comando de DOS indicado
*!* como primer parámetro, el segundo es el estilo
*!* de la ventana a utilizar, ver el sig. listado
*!* entEstiloVentana Descripción
*!* 0 Oculta la ventana y activa otra.
*!* 1 Activa y muestra una ventana. Si la ventana está minimizada o maximizada, el sistema la restaura con su posición y tamaño originales. 
*!*             Una aplicación debe especificar este indicador cuando muestre la ventana por primera vez.
*!* 2 Activa la ventana y la muestra minimizada.
*!* 3 Activa la ventana y la muestra maximizada.
*!* 4 Muestra una ventana con su tamaño y posición más recientes. La ventana activa permanece activa.
*!* 5 Activa la ventana y la muestra con su tamaño y posición actuales.
*!* 6 Minimiza la ventana especificada y activa la siguiente ventana de mayor nivel en orden Z.
*!* 7 Muestra la ventana minimizada. La ventana activa permanece activa.
*!* 8 Muestra la ventana en su estado actual. La ventana activa permanece activa.
*!* 9 Activa y muestra la ventana. Si la ventana está minimizada o maximizada, el sistema la restaura con su posición y tamaño originales. 
*!*             Una aplicación debe especificar este indicador cuando se restaure una ventana minimizada.
*!* 10 Establece el estado de presentación a partir del estado del programa que inició la aplicación.
*----------------------------------------------------
  TRY 
    oShell = createobject("WScript.Shell") 
    oShell.Run(cComando,iStatus,.T.) 
  CATCH TO xEcepcion
    lsErrorEcepcion = "No se pudo ejecutar: "+cComando+ " RS:"+TRANSFORM(xEcepcion.ErrorNo) + CHR(13)+CHR(10)+  "Mensaje: " + xEcepcion.Message
    Messagebox(lsErrorEcepcion,16,"Lector QR")
  FINALLY
    *  
  ENDTRY   
ENDFUNC
*----------------------------------------------------

Pueden descargar el ejemplo completo, con librerias y ejecutables adicionales desde aqui

Baltazar Moreno

13 de enero de 2011

Códigos de Barras QR usando la API de Google

Un pequeño ejemplo de como utilizar la API de Google para generar códigos de barras de dos dimensiones de tipo QR:

** Este seria el contenido de informacion del QR
lcDato =[?re=XAXX010101000%26rr=XAXX010101000%26tt=1234567890.123456] + ;
  [%26id=ad662d33-6934-459c-a128-BDf0393f0f44]
** Ancho x Alto
lcDimensiones = '300x300'
** Donde quieren guardar la imagen, ojo, es PNG
lcImagen = PUTFILE('QRCode','QRCode','png')

IF EMPTY(lcImagen)
  RETURN
ENDIF

IF GoogleQR(lcDato,lcDimensiones,lcImagen) == 0
  MESSAGEBOX('Descarga Exitosa',0+64,'GoogleQR')
ELSE
  MESSAGEBOX('Error en la generacion del Codigo QR',0+16,'GoogleQR')
ENDIF

FUNCTION GoogleQR(pDato,pDimensiones,pImagen)
  WAIT WINDOW "Generando y descargando Código QR, espere por favor..." NOWAIT
  DECLARE LONG URLDownloadToFile IN "urlmon";
    LONG pCaller,;
    STRING szURL,;
    STRING szFileName,;
    LONG dwReserved,;
    LONG lpfnCB
  sURL ="https://chart.googleapis.com/chart?cht=qr&chs=" + ;
    pDimensiones + "&chld=Q&chl=" + STRTRAN(pDato,'&','%26')
  nRetVal = URLDownloadToFile (0, sURL, pImagen, 0, 0)
  WAIT CLEAR
  RETURN nRetVal
ENDFUNC
Más información:
Google API
Gracias a Luis María Guayán por el tip de esta API de Google
Baltazar Moreno

6 de diciembre de 2010

Liberada la versión Beta de FoxBarcode

Se liberó la versión 0.10 de FoxBarcode, una clase 100% Visual FoxPro que ofrece una herramienta para la generación de imágenes con distintas simbologías de códigos de barras, para ser usadas en informes y formularios de VFP, o exportadas a otras aplicaciones.

Sitio oficial de FoxBarcode: https://github.com/VFPX/FoxBarCode

Nuevo -> Última versión: 1.19 lanzada el 21/05/2019

Sitio de Descarga: https://github.com/VFPX/FoxBarCode

Características

FoxBarcode soporta las siguientes 18 simbologías lineales de códigos de barras: Código 128, Código 39, Código 39 Extendido (Full ASCII), Código 93, Código 93 Extendido (Full ASCII), Standard 2 de 5, Interleaved 2 de 5, EAN-8, EAN-13, UPC-A, UPC-E (EAN y UPC con suplementos de 2 y 5 dígitos), ITF-14, GS1/EAN/UCC-128, Codabar, Código 11, MSI / Plessey, Telepen, PostNet, RM4SCC, KIX-Code, One Track Pharmacode y Two Track Pharmacode.

FoxBarcode soporta los siguientes tipos de imagenes: JPG, BMP, GIF, PNG y TIFF

FoxBarcode genera las imágenes con la clase gpImage2 (http://sites.google.com/site/gpimage2) de Alexander Golovlev (Rusia) y Cesar Ch. (Brasil), basada en GDI+ y requiere gdiplus.dll.

FoxBarcode permite un gran control en la generación de la imagen del código de barras al poder personalizar las siguientes propiedades:
  • nImageHeight: Altura en pixeles de la imagen.
  • nImageWidth: Ancho en pixeles de la imagen. Ahora se puede configurar el ancho
  • nAlignBarcode: Alineación del código de barra con respecto a la imagen. [0=Izquierda, 1=Centro y 2=Derecha]
  • nResolution: Resolución de la imagén en DPI.  
  • nRotation: Rotación de la imagen. [0=0°, 1=90°, 2=180°, 3=270°]
  • cImageType: Tipo de la imagen generada ["JPG", "GIF", "PNG", "BMP", "TIF"]
  • cImageFile: Nombre del archivo de imagen generado. Si no se especifica, se genera un nombre de archivo aleatorio en la carpeta de archivos temporales de Windows.
  • cText: Texto a codificar.
  • nAlignText: Alineación del texto de la lectura humana. [0=Izquierda, 1=Centro, 2=Derecha]
  • lShowHumanReadableText: .T. si se muestra la lectura humana.
  • lShowCheckDigit: .T. si se muestra el dígito de control en la lectura humana.
  • lShowStartStopChars: .T. si se muestra los caracteres de inicio y final en la lectura humana.
  • cFontName: Nombre de la fuente de la lectura humana.
  • lFontBold: .T. si la fuente de la lectura humana es Negrita.
  • lFontItalic: .T. si la fuente de la lectura humana es Cursiva.
  • nFontSize: Tamaño de la letra de la lectura humana. [Recomendado = 8 ó 9]
  • nFontColor: Color de la fuente de la lectura humana. [Recomendado = Negro = RGB(0,0,0)].
  • nBackColor: Color de fondo de la imagen [Recomendado = Blanco = RGB(255,255,255)].
  • nBarsColor: Color de las barras [Recomendado = Negro = RGB(0,0,0)].
  • nBarcodeType: Tipo de la simbología de código de barra. Vea la lista de codigos de barra soportados y su Id.
  • cSet128 Set: Juego del Código 128. ["A", "B", "C" y "*" (Auto)]
  • cSupplementalText: Texto suplementario en códigos EAN y UPC.
  • lAddCheckDigit: .T. si se calcula el dígito de control. En las simbologías en donde el dígito de control es obligatorio, no se tiene en cuenta esta propiedad.
  • nBearerBar: Tipo del marco portante, solo en la simbología ITF-14.  [0=Ninguno, 1=Rectángulo, 2=Superior e inferior]
  • lUseAppId:  .T. para que FoxBarcode interprete en el código GS1/EAN/UCC-128 a los Identificadores de Aplicación (encerrados entre paréntesis).
  • nFactor: Factor de magnificación del código de barras. [1..9]
  • nMargin: Margen alrededor del código de barras. 
  • nRatio: Relación entre las barras angostas y las barras anchas en las simbologías que lo permiten.
  • lDeleteTempFiles: Permite elegir si borra o no la carpeta temporal con las imágenes temporales.
Para la generación de la imagen, solo se debe llamar al método BarcodeImage() que genera la imagen del código de barras y retorna la ruta y nombre de archivo generado.

Ahora se puede validar previamente la cadena a codificar con el método BarcodeTest()

FoxBarcode es compatible con todas las versiones de Visual FoxPro a partir de la versión 6.0

Lenguajes

Gracias a la Comunidad Mundial de VFP, se tradujeron los mensajes de FoxBarcode a los siguientes lenguajes:
  • Inglés
  • Español por VFPEncoding
  • Checo por Martin Krivka
  • Holandés por Koen Piller
  • Alemán por Stefan Wuebbe
  • Indonesio por Samir H.
  • Portugués por Cesar Ch.
  • Turco por Ugur Yilmaz
  • Filipino por Glenn Gevero
  • Francés por Samir H.
  • Serbio por Michael Kopljan
  • Italiano por Roberto Saccomanno
Ejemplos

El siguiente es un ejemplo de código para generar una imagen tipo "PNG" del código de barras "Código 128 C" con una altura de "100" pixeles y un factor de magnificación de "2":
*-- Crear el objeto
loFbc = CREATEOBJECT("FoxBarcode")

*-- Configurar las propiedades
WITH loFBC
  .cImageType = "PNG"
  .nBarcodeType = 110 && Code 128
  .cSet128 = "C" && Set 128 C
  .nImageHeight = 100
  .nFactor = 2
ENDWITH

*-- Generar la imagen 
lcImagen = loFbc.BarcodeImage("123456789012")
Desde la versión 0.11 se agregó un 3er. parámetro al método BarcodeImage() que permite configurar varias propiedades, separadas por comas. El mismo ejemplo de arriba, con el uso del 3er. parámetro.
*-- Creo el objeto
loFbc = CREATEOBJECT("FoxBarcode")
*-- Genero la imagen con sus propiedades
lcImagen = loFbc.BarcodeImage("","",[cText="123456789012", cImageType="PNG", ;
           nBarcodeType=110, cSet128="C", nImageHeight=100, nFactor=2])

La imagen generada se muestra a continuación


Otras imágenes de ejemplo cambiando solo algunas propiedades de la clase FoxBarcode





Ahora FoxBarcode soporta el código EAN/UCC/GS1 128


Para incluir un código de barras en un formulario, se debe insertar un objeto Image. Como la imagen del código de barras no existe en tiempo de diseño, la propiedad Picture tomará el nombre de la imagen cuando se llame al método BarcodeImage(), por ejemplo desde el método Refresh de Formulario, como se muestra en la siguiente figura:



Para incluir un código de barras en un Informe, se debe insertar un objeto Image y configurar la propiedad ControlSource con un llamado al método BarcodeImage() y se recomienda configurar "Scale contents, retain shape" si la imagen difiere de tamaño con el cuadro.



NOTA: Antes de ejecutar el informe y crear el objeto FoxBarcode, se debe declarar la variable como PRIVATE para que ésta tenga alcance en el informe, como se muestra a continuación:
PRIVATE poFbc
poFbc = CREATEOBJECT("FoxBarcode")
...
REPORT FORM MyReport
Distribución

Los únicos archivos necesarios que se deben distribuir para que FoxBarcode funcione correctamente son:
  • FoxBarcode.prg
  • gpImage2.prg
Estos archivos se encuentran en la carpeta \Source incluída en el archivo de la descarga.

Antes de instanciar la clase FoxBarcode, se deben ejecutar las siguientes sentencias:
SET PROCEDURE TO LOCFILE("FoxBarcode.prg"), LOCFILE("gpImage2.prg") ADDITIVE

Demo

En los archivos de la descarga, está incluido un proyecto completo de una aplicación Demo que utiliza FoxBarcode. La siguiente es una captura de pantalla de la aplicación.



La aplicación permite:
  • Configurar todas las propiedades de la clase FoxBarcode y muestrar la imagen generada automáticamente.
  • Copiar al portapapeles la imagen generada.
  • Guardar en un archivo la imagen.
  • Imprimir el código de barras.
  • Ejecutar diversos informes y formularios de ejemplo.
  • Construir un Script con el código en Visual FoxPro.
En la aplicación también se muestra una breve descripción de cada simbología de códigos de barras, según se seleccione en la lista desplegable de las simbologías.

Descargas

Para descargar la última versión de FoxBarcode, visite la página de Descargas de FoxBarcode haciendo clic aquí.

Feedback

FoxBarcode se encuentra en fase Beta, por lo que cualquier comentario será bienvenido. Los comentarios, como así también los reportes de incidencias usando la clase FoxBarcode se deben enviar por correo electrónico a vfpencoding@gmail.com

¿Quiénes somos?

VFPEncoding es un grupo de desarrolladores pertenecientes a la Comunidad Hispana de Visual FoxPro que creo FoxBarcode. Los miembros de VFPEncoding son:
  • Guillermo Carrero (Barcelona, España) (Q.E.P.D)
  • Luis María Guayán (Tucumán, Argentina)
Agradecimientos
  • A nuestras familias.
  • Cesar Ch. por sus continuas ideas y colaboraciones con sus clases gpImage2 y FoxyPreviewer.

28 de abril de 2008

Bar codes on Visual FoxPro reports

Traducción al inglés de Ricardo Aráoz, del artículo "Códigos de barras en informes de Visual FoxPro" publicado en español en PortalFox, para la comunidad de habla inglesa.


Bar codes on Visual FoxPro reports

NEW: Download freely the new FoxBarcode class to generate barcodes from Visual FoxPro, by clicking the following link: http://sites.google.com/site/foxbarcode

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)
  CheckDigit = sum % 103
Code 128 is composed of :
Start + InputText + CheckDigit + 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 FontFileSize
PF Barcode 39PF_C39.ttf20 ó 22
PF Barcode 128PF_C128.ttf22, 24, 26 ó 28
PF EAN P36PF_EAN_P36.ttf36
PF EAN P72PF_EAN_P72.ttf72
PF Interleaved 2 of 5PF_I2OF5.ttf36 ó 48
PF Interleaved 2 of 5 WidePF_I2OF5_W.ttf28 ó 36
PF Interleavev 2 of 5 TextPF_I2OF5_Text.ttf28 ó 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 chara
  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:
lcTexto = "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 Interleavev 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:

Código 39


Codigo 128 A


Código 128 B


Código 128 C


Código EAN 13


Código EAN 8


Código I 2de5 (ancho)


Código Interleaved 2de5


Código I 2de5 (lectura humana)


DOWNLOADS
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.

Up to the next time!

Luis María Guayán

31 de julio de 2007

Codigo de barra EAN 128 en FoxPro

Una clase para descargar del sitio de José Guillermo Ortiz Hernández, que permite incluir código EAN 128 en aplicaciones Visual FoxPro.

En el sitio Tortuga Productiva dedicado a Visual FoxPro, está publicado el siguiente artículo con código fuente incluido que permite incluir códigos de barra EAN 128 en aplicaciones Visual FoxPro.

-- El EAN 128, Uso e implementación en FoxPro --
http://www.tortugaproductiva.galeon.com/docs/ean128/index.html



3 de marzo de 2006

Códigos de barra 128 con lectura humana

En este artículo vamos a presentar unas funciones para imprimir códigos de barras del tipo 128 con diversas fuentes TrueType que nos permitirán lograr distintas alturas de códigos de barras y también la impresión de la cadena para lectura humana.

Los códigos 128

Como ya vimos en el artículo "Códigos de barras en reportes de Visual FoxPro", los códigos de barras 128 se dividen en 3 subconjutos:
  • 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 muy buena densidad de impresión.
Los códigos 128 se forman de la siguiente manera:
CaracterInicial + CadenaTexto + DigitoControl + CaracterFinal 
Las funciones descritas al final del artículo calculan el dígito de control y añaden los caracteres de inicio y final de cada tipo de código de barra 128, a la cadena de texto.

Las fuentes TrueType

Las siguientes son una descripción de las fuentes disponibles en este artículo:
  • Code 128AB (Bc128ab.ttf): Código 128 A y B Normal
  • Code 128AB Short (Bc128abs.ttf): Código 128 A y B Bajo
  • Code 128AB Tall (Bc128abt.ttf): Código 128 A y B Alto
  • Code 128AB HR (Bh128ab.ttf): Código 128 A y B Normal con Lectura Humana
  • Code 128AB Short HR (Bh128abs.ttf): Código 128 A y B Bajo con Lectura Humana
  • Code 128AB Tall HR (Bh128ab.ttf): Código 128 A y B Alto con Lectura Humana
  • Code 128C (Bc128c.ttf): Código 128 C Normal
  • Code 128C Short (Bc128cs.ttf): Código 128 C Bajo
  • Code 128C Tall (Bc128ct.ttf): Código 128 C Alto
  • Code 128C HR (Bh128c.ttf): Código 128 C Normal con Lectura Humana
  • Code 128C HR Short (Bh128cs.ttf): Código 128 C Bajo con Lectura Humana
  • Code 128C HR Tall (Bh128ct.ttf): Código 128 C Alto con Lectura Humana
  • Codigo de barras CyT (codigo_barras_cyt.ttf): Código 128 A y B Alto
Estas fuentes TrueType se corresponden adecuadamente al tamaño de fuente mínimo recomendado por Correos de España que es 24 y de un ancho máximo de 105 mm.

Los requisitos para los envíos a Correos de España son:
  • Código 128 A
  • Densidad entre 0,38 mm. y 0,63 mm.
  • Composición del código:
    • Tipo de producto en 2 posiciones: Consultar con Correos los tipos admitidos
    • Código de cliente en 8 posiciones: Solicitar el código a Correos
    • Número de envío en 13 posiciones: No puede repetirse antes de 5 años. Puede incluir el año como las 4 primeras posiciones
La fuente que mejor se adapta a estos requisitos es la "Code 128AB Tall HR" con un tamaño de 28 puntos.

Independientemente de lo expresado anteriormente, estas fuentes TrueType se pueden adaptar a cualquier necesidad de impresión de códigos de barras 128, por las diversas combinaciones posibles entre tipo, tamaño e impresión de la cadena para la lectura humana.

Las funciones en VFP

Las funciones en Visual FoxPro para cada uno de los tres tipo de código de barra 128 son las siguientes:
FUNCTION Codigo128A
  LPARAMETERS m.cadena
  *** Convierte una cadena para ser impresa en un
  *** código de barras de tipo 128 A
  *** Fuentes True Type válidas:
  *** "Code 128AB", "Code 128AB HR",
  *** "Code 128AB Short", "Code 128AB Short HR",
  *** "Code 128AB Tall", "Code 128AB Tall HR"  y
  *** "Codigo de barras CyT"
  IF PCOUNT() = 0
    RETURN ""
  ENDIF
  IF TYPE("m.cadena") = "N"
    m.cadena = TRANSFORM(m.cadena)
  ENDIF
  IF TYPE("m.cadena") != "C"
    RETURN ""
  ENDIF
  m.cadena = ALLTRIM(m.cadena)
  LOCAL m.vuelta, m.suma, m.caracterinicial, m.co, m.letra, ;
    m.valorascii, m.checksum, m.caracterfinal
  m.suma = 103
  m.caracterinicial = CHR(123)
  m.vuelta = m.caracterinicial
  m.caracterfinal = CHR(126)
  FOR m.co = 1 TO LEN(m.cadena)
    m.letra = SUBSTR(m.cadena, m.co, 1)
    m.valorascii = ASC(m.letra)
    m.valorascii = m.valorascii - IIF(m.valorascii < 123, 32, 70)
    m.suma = m.suma + (m.valorascii * m.co)
    m.vuelta = m.vuelta + IIF(m.letra = " ", CHR(174), m.letra)
  NEXT m.co
  m.checksum = MAX(MOD(m.suma, 103), 0)
  m.checksum = m.checksum + IIF(m.checksum > 90, 70, IIF(m.checksum = 0, 174, 32))
  m.checksum = CHR(m.checksum)
  m.vuelta = m.vuelta + m.checksum + m.caracterfinal
  RETURN m.vuelta
ENDFUNC
FUNCTION Codigo128B
  LPARAMETERS m.cadena
  *** Convierte una cadena para ser impresa en un
  *** código de barras de tipo 128 B
  *** Fuentes True Type válidas:
  *** "Code 128AB", "Code 128AB HR",
  *** "Code 128AB Short", "Code 128AB Short HR",
  *** "Code 128AB Tall", "Code 128AB Tall HR"  y
  *** "Codigo de barras CyT"
  IF PCOUNT() = 0
    RETURN ""
  ENDIF
  IF TYPE("m.cadena") = "N"
    m.cadena = TRANSFORM(m.cadena)
  ENDIF
  IF TYPE("m.cadena") != "C"
    RETURN ""
  ENDIF
  m.cadena = ALLTRIM(m.cadena)
  LOCAL m.vuelta, m.suma, m.caracterinicial, m.co, m.letra, m.valorascii, ;
    m.checksum, m.caracterfinal
  m.suma = 104
  m.caracterinicial = CHR(124)
  m.vuelta = m.caracterinicial
  m.caracterfinal = CHR(126)
  FOR m.co = 1 TO LEN(m.cadena)
    m.letra = SUBSTR(m.cadena, m.co, 1)
    m.valorascii = ASC(m.letra)
    m.valorascii = m.valorascii - IIF(m.valorascii < 123, 32, 70)
    m.suma = m.suma + (m.valorascii * m.co)
    m.vuelta = m.vuelta + IIF(m.letra = " ", CHR(174), m.letra)
  NEXT m.co
  m.checksum = MAX(MOD(m.suma, 103), 0)
  m.checksum = m.checksum + IIF(m.checksum > 90, 70, IIF(m.checksum = 0, 174, 32))
  m.checksum = CHR(m.checksum)
  m.vuelta = m.vuelta + m.checksum + m.caracterfinal
  RETURN m.vuelta
ENDFUNC
FUNCTION Codigo128C
  LPARAMETERS m.cadena
  *** Convierte una cadena para ser impresa en un
  *** código de barras de tipo 128 C
  *** Fuentes True Type válidas:
  *** "Code 128C", "Code 128C HR",
  *** "Code 128C Short", "Code 128C HR Short",
  *** "Code 128C Tall", "Code 128C HR Tall"
  IF PCOUNT() = 0
    RETURN ""
  ENDIF
  IF TYPE("m.cadena") = "N"
    m.cadena = TRANSFORM(m.cadena)
  ENDIF
  IF TYPE("m.cadena") != "C"
    RETURN ""
  ENDIF
  m.cadena = ALLTRIM(m.cadena)
  LOCAL m.vuelta, m.suma, m.caracterinicial, m.co, m.letra, ;
    m.valorascii, m.valorreal, m.checksum, m.caracterfinal
  m.suma = 105
  m.caracterinicial = CHR(125)
  m.vuelta = m.caracterinicial
  m.caracterfinal = CHR(126)
  IF LEN(m.cadena) % 2 # 0
    m.cadena = "0" + m.Cadena
  ENDIF
  FOR m.co = 1 TO LEN(m.cadena) STEP 2
    m.letra = SUBSTR(m.cadena, m.co, 2)
    m.valorreal = VAL(m.letra)
    m.valorascii = m.valorreal + IIF(m.valorreal < 90, 33, 71)
    m.suma = m.suma + (m.valorreal * CEILING(m.co/2))
    m.vuelta = m.vuelta + CHR(m.valorascii)
  NEXT m.co
  m.checksum = MAX(MOD(m.suma, 103), 0)
  m.checksum = m.checksum + IIF(m.checksum < 90, 33, 71)
  m.checksum = CHR(m.checksum)
  *-- Reemplazo CheckSum
  m.checksum = CHRTRAN(m.checksum, ;
    CHR(171)+CHR(172)+CHR(173), CHR(176)+CHR(177)+CHR(178))
  m.vuelta = m.vuelta + m.checksum + m.caracterfinal
  RETURN m.vuelta
ENDFUNC

Nota importante: Estas funciones solo se corresponden con las fuentes TrueType de este artículo. Las funciones de los artículos "Códigos de barras en reportes de Visual FoxPro" y "Resolución General 1702 de la AFIP (Argentina)" se corresponden a las fuentes disponibles para descarga de cada artículo. Cada fuente tiene su función asociada para la correcta generación de los distintas simbologías de códigos de barras.

Ejemplos

Para utilizar las funciones se debe pasar como parámetro la cadena a codificar:
lc128A = Codigo128A("CODIGO128A")
lc128B = Codigo128B("codigo128b")
lc128C = Codigo128C("16886271")
Para la impresión se debe seleccionar la fuente correspondiente a cada función:
CLEAR
? Codigo128A("CODIGO128A") FONT "Code 128AB Short HR",36
? Codigo128B("codigo128b") FONT "Code 128AB Tall HR",36
? Codigo128C("16886271") FONT "Code 128C HR",60
?
? Codigo128A("PortalFox") FONT "Codigo de barras CyT",48



Descargas

Estos son los enlaces para las descargas disponibles de este artículo:
  • Para descargar un proyecto de ejemplo haga clic aquí. (ejemplo128.zip 6,6 KB)
  • Hasta la próxima.

    Carlos Yohn Zubiria (España) y Luis María Guayán (Argentina)


    15 de febrero de 2001

    Códigos de barra en informes de Visual FoxPro

    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
    • 2014/09/21 - Publicado en este Blog y actualización de enlaces
    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.

    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

    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 = 0
    Por 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 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 Interleaved 2 of 5 se forman de la siguiente manera:
    Start + Cadena + Check_Digit + End

    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 TypeArchivoTamaño
    PF Barcode 39PF_C39.ttf20 ó 22
    PF Barcode 128PF_C128.ttf22, 24, 26 ó 28
    PF EAN P36PF_EAN_P36.ttf36
    PF EAN P72PF_EAN_P72.ttf72
    PF Interleaved 2 of 5PF_I2OF5.ttf36 ó 48
    PF Interleaved 2 of 5 WidePF_I2OF5_W.ttf28 ó 36
    PF Interleavev 2 of 5 TextPF_I2OF5_Text.ttf28 ó 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: funciones.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 lcRet
    ENDFUNC
    *------------------------------------------------------
    * 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
    *------------------------------------------------------
    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 lcRet
    ENDFUNC
    *------------------------------------------------------
    * 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 lcRet
    ENDFUNC
    *------------------------------------------------------
    * FUNCTION _StrTo128C(tcString) * CODIGO 128C
    *------------------------------------------------------
    * 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 lcRet
    ENDFUNC
    *------------------------------------------------------
    * 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
      *--- 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 lcCod
    ENDFUNC
    *------------------------------------------------------
    * FUNCTION _StrToEan8(tcString,.T.) * CODIGO EAN-8
    *------------------------------------------------------
    * Convierte un string para ser impreso con
    * fuente True Type "PF EAN P36" ó "PF EAN P72"
    * 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 lcCod
    ENDFUNC
    *------------------------------------------------------
    * 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, ;
        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 lcRet
    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)
    ? 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
    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


    Código EAN 13


    Código EAN 8


    Código I 2de5 (ancho)


    Código Interleaved 2de5


    Código I 2de5 (lectura humana)



    Descargas
    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.

    Luis María Guayán