El código GS1-128, antes llamado EAN-128, es un sistema para la identificación que se utiliza para el entorno logístico.
Una etiqueta con un código GS1-128 tiene un aspecto parecido a este:

El código de barras esta compuesto por varios registros cada uno encabezado por un identificador (AI) que nos indica que significa ese dato y que formato tiene, es decir, nos dice si es peso, longitud, numero de lote, etc ... así como cuantos decimales tiene o en que unidades de medida esta expresado. Estos identificadores son estándar, de este modo una empresa puede leer las etiquetas generadas por otra sin previamente haberse puesto de acuerdo en el formato, lo que simplifica muchísimo el trabajo.
Un código GS1-128 visto más de cerca:

Este código leído por el escaner tiene este aspecto ("^]" se corresponde con el carácter 1Dh) :
011942112345001110101234^]15991231
El problema para leer estos códigos es reconocer el AI y separar cada uno de los registros, sobre todo los que tiene longitud variable. El siguiente código lee la mayoría de los código fijos (prácticamente todos) y alguno de los variables (lote, numero de serie, etc ..). El problema con los campos variables es que algunos escaner no envían el carácter separador 1Dh, así que no hay forma de saber donde acaban, aunque para evitar ese problema la mayoría de los fabricantes ponen solo un campo variable al final del código de tal forma que podemos saber donde acaba, aun sin carácter separador.
El código es el siguiente (es una aplicación de consola):
program GS1; {$APPTYPE CONSOLE} uses Windows, SysUtils, Classes; type TRegTipo = (rtTexto, rtNumero, rtFecha, rtEAN13); TRegUnidades = (ruNinguna, ruKg, ruMetros, ruMetros2, ruMetros3, ruLitros, ruLibras, ruPulgadas, ruPulgadas2, ruPulgadas3, ruPies, ruPies2, ruPies3, ruYardas, ruYardas2, ruYardas3, ruOnzas, ruQuarts, ruGalones); TRegistro = record AI: String; Tipo: TRegTipo; Valor: String; Decimales: Integer; Unidades: TRegUnidades; Descripcion: String; end; function LeerRegistro(var Codigo: String): TRegistro; var C: Char; begin if Copy(Codigo,1,2) = '00' then with Result do begin AI:= '00'; Valor:= Copy(Codigo,3,18); Tipo:= rtNumero; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Serial Shipping Container'; Delete(Codigo,1,20); end else if Copy(Codigo,1,2) = '01' then with Result do begin AI:= '01'; Valor:= Copy(Codigo,3,14); Tipo:= rtNumero; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Shipping Container Code'; Delete(Codigo,1,16); end else if Copy(Codigo,1,2) = '02' then with Result do begin AI:= '02'; Valor:= Copy(Codigo,3,14); Tipo:= rtNumero; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Number of containers'; Delete(Codigo,1,16); end else if Copy(Codigo,1,2) = '10' then with Result do begin AI:= '10'; Tipo:= rtTexto; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Batch Number'; Delete(Codigo,1,2); Valor:= EmptyStr; while Length(Codigo) > 0 do begin C:= Codigo[1]; Delete(Codigo,1,1); if C = #$1D then break else Valor:= Valor + C; end; end else if Copy(Codigo,1,2) = '11' then with Result do begin AI:= '11'; Valor:= Copy(Codigo,3,6); Tipo:= rtFecha; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Production Date'; Delete(Codigo,1,8); end else if Copy(Codigo,1,2) = '13' then with Result do begin AI:= '13'; Valor:= Copy(Codigo,3,6); Tipo:= rtFecha; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Packaging Date'; Delete(Codigo,1,8); end else if Copy(Codigo,1,2) = '15' then with Result do begin AI:= '15'; Valor:= Copy(Codigo,3,6); Tipo:= rtFecha; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Sell by Date'; Delete(Codigo,1,8); end else if Copy(Codigo,1,2) = '17' then with Result do begin AI:= '17'; Valor:= Copy(Codigo,3,6); Tipo:= rtFecha; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Expiration Date'; Delete(Codigo,1,8); end else if Copy(Codigo,1,2) = '20' then with Result do begin AI:= '20'; Valor:= Copy(Codigo,3,2); Tipo:= rtNumero; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Product Variant'; Delete(Codigo,1,4); end else if Copy(Codigo,1,2) = '21' then with Result do begin AI:= '21'; Tipo:= rtTexto; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Serial Number'; Delete(Codigo,1,2); Valor:= EmptyStr; while Length(Codigo) > 0 do begin C:= Codigo[1]; Delete(Codigo,1,1); if C = #$1D then break else Valor:= Valor + C; end; end else if Copy(Codigo,1,3) = '310' then with Result do begin AI:= '310'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruKg; Descripcion:= 'Product Net Weight'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '311' then with Result do begin AI:= '311'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruMetros; Descripcion:= 'Product Length/1st Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '312' then with Result do begin AI:= '312'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruMetros; Descripcion:= 'Product Width/Diameter/2nd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '313' then with Result do begin AI:= '313'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruMetros; Descripcion:= 'Product Depth/Thickness/3rd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '314' then with Result do begin AI:= '314'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruMetros2; Descripcion:= 'Product Area'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '315' then with Result do begin AI:= '315'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruLitros; Descripcion:= 'Product Volume'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '316' then with Result do begin AI:= '316'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruMetros3; Descripcion:= 'Product Volume'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '320' then with Result do begin AI:= '320'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruLibras; Descripcion:= 'Product Net Weight'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '321' then with Result do begin AI:= '321'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPulgadas; Descripcion:= 'Product Length/1st Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '322' then with Result do begin AI:= '322'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPies; Descripcion:= 'Product Length/1st Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '323' then with Result do begin AI:= '323'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruYardas; Descripcion:= 'Product Length/1st Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '324' then with Result do begin AI:= '324'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPulgadas; Descripcion:= 'Product Width/Diameter/2nd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '325' then with Result do begin AI:= '325'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPies; Descripcion:= 'Product Width/Diameter/2nd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '326' then with Result do begin AI:= '326'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruYardas; Descripcion:= 'Product Width/Diameter/2nd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '327' then with Result do begin AI:= '327'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPulgadas; Descripcion:= 'Product Depth/Thickness/3rd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '328' then with Result do begin AI:= '328'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPies; Descripcion:= 'Product Depth/Thickness/3rd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '329' then with Result do begin AI:= '329'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruYardas; Descripcion:= 'Product Depth/Thickness/3rd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '330' then with Result do begin AI:= '330'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruKg; Descripcion:= 'Container Gross Weight'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '331' then with Result do begin AI:= '331'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruMetros; Descripcion:= 'Container Length/1st Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '332' then with Result do begin AI:= '332'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruMetros; Descripcion:= 'Container Width/Diameter/2nd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '333' then with Result do begin AI:= '333'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruMetros; Descripcion:= 'Container Depth/Thickness/3rd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '334' then with Result do begin AI:= '334'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruMetros2; Descripcion:= 'Container Area'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '335' then with Result do begin AI:= '335'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruLitros; Descripcion:= 'Container Gross Volume'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '336' then with Result do begin AI:= '336'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruMetros3; Descripcion:= 'Container Gross Volume'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '340' then with Result do begin AI:= '340'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruLibras; Descripcion:= 'Container Gross Weight'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '341' then with Result do begin AI:= '341'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPulgadas; Descripcion:= 'Container Length/1st Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '342' then with Result do begin AI:= '342'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPies; Descripcion:= 'Container Length/1st Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '343' then with Result do begin AI:= '343'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruYardas; Descripcion:= 'Container Length/1st Dimension in'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '343' then with Result do begin AI:= '343'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruYardas; Descripcion:= 'Container Length/1st Dimension in'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '344' then with Result do begin AI:= '344'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPulgadas; Descripcion:= 'Container Width/Diamater/2nd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '345' then with Result do begin AI:= '345'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPies; Descripcion:= 'Container Width/Diameter/2nd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '346' then with Result do begin AI:= '346'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruYardas; Descripcion:= 'Container Width/Diameter/2nd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '347' then with Result do begin AI:= '347'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPulgadas; Descripcion:= 'Container Depth/Thickness/Height/3rd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '348' then with Result do begin AI:= '348'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPies; Descripcion:= 'Container Depth/Thickness/Height/3rd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '349' then with Result do begin AI:= '349'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruYardas; Descripcion:= 'Container Depth/Thickness/Height/3rd Dimension'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '350' then with Result do begin AI:= '350'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPulgadas2; Descripcion:= 'Product Area'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '351' then with Result do begin AI:= '351'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPies2; Descripcion:= 'Product Area'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '352' then with Result do begin AI:= '352'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruYardas2; Descripcion:= 'Product Area'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '353' then with Result do begin AI:= '353'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPulgadas2; Descripcion:= 'Container Area'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '354' then with Result do begin AI:= '354'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPies2; Descripcion:= 'Container Area'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '355' then with Result do begin AI:= '355'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruYardas2; Descripcion:= 'Container Area'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '356' then with Result do begin AI:= '356'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruOnzas; Descripcion:= 'Net Weight'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '360' then with Result do begin AI:= '360'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruQuarts; Descripcion:= 'Product Volume'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '361' then with Result do begin AI:= '361'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruGalones; Descripcion:= 'Product Volume'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '362' then with Result do begin AI:= '362'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruQuarts; Descripcion:= 'Container Gross Volume'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '363' then with Result do begin AI:= '363'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruGalones; Descripcion:= 'Container Gross Volume'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '364' then with Result do begin AI:= '364'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPulgadas3; Descripcion:= 'Product Volume'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '365' then with Result do begin AI:= '365'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPies3; Descripcion:= 'Product Volume'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '366' then with Result do begin AI:= '366'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruYardas3; Descripcion:= 'Product Volume'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '367' then with Result do begin AI:= '364'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPulgadas3; Descripcion:= 'Container Gross Volume'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '368' then with Result do begin AI:= '365'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruPies3; Descripcion:= 'Container Gross Volume'; Delete(Codigo,1,10); end else if Copy(Codigo,1,3) = '369' then with Result do begin AI:= '366'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= StrToInt(Copy(Codigo,4,1)); Unidades:= ruYardas3; Descripcion:= 'Container Gross Volume'; Delete(Codigo,1,10); end else if Copy(Codigo,1,2) = '37' then with Result do begin AI:= '37'; Tipo:= rtNumero; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Number of Units Contained'; Delete(Codigo,1,2); Valor:= EmptyStr; while Length(Codigo) > 0 do begin C:= Codigo[1]; Delete(Codigo,1,1); if C = #$1D then break else Valor:= Valor + C; end; end else if Copy(Codigo,1,2) = '400' then with Result do begin AI:= '400'; Tipo:= rtTexto; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Customer Purchase Order Number'; Delete(Codigo,1,3); Valor:= EmptyStr; while Length(Codigo) > 0 do begin C:= Codigo[1]; Delete(Codigo,1,1); if C = #$1D then break else Valor:= Valor + C; end; end else if Copy(Codigo,1,2) = '410' then with Result do begin AI:= '410'; Valor:= Copy(Codigo,4,13); Tipo:= rtEAN13; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Ship To/Deliver To Location Code'; Delete(Codigo,1,16); end else if Copy(Codigo,1,2) = '411' then with Result do begin AI:= '411'; Valor:= Copy(Codigo,4,13); Tipo:= rtEAN13; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Bill To/Invoice Location Code'; Delete(Codigo,1,16); end else if Copy(Codigo,1,2) = '412' then with Result do begin AI:= '412'; Valor:= Copy(Codigo,4,13); Tipo:= rtEAN13; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Purchase From Location Code'; Delete(Codigo,1,16); end else if Copy(Codigo,1,2) = '8001' then with Result do begin AI:= '8001'; Valor:= Copy(Codigo,5,14); Tipo:= rtNumero; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Roll Products - Width/Length/Core Diameter'; Delete(Codigo,1,18); end else if Copy(Codigo,1,2) = '8004' then with Result do begin AI:= '8004'; Tipo:= rtTexto; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'UPC/EAN Serial Identification'; Delete(Codigo,1,4); Valor:= EmptyStr; while Length(Codigo) > 0 do begin C:= Codigo[1]; Delete(Codigo,1,1); if C = #$1D then break else Valor:= Valor + C; end; end else if Copy(Codigo,1,2) = '8005' then with Result do begin AI:= '8005'; Valor:= Copy(Codigo,5,6); Tipo:= rtNumero; Decimales:= 0; Unidades:= ruNinguna; Descripcion:= 'Price per Unit of Measure'; Delete(Codigo,1,10); end else raise Exception.Create('AI desconocido'); end; function UnidToStr(Unidad: TRegUnidades): String; begin case Unidad of ruNinguna: Result:= EmptyStr; ruKg: Result:= 'Kilogramos'; ruMetros: Result:= 'Metros'; ruMetros2: Result:= 'Metros cuadrados'; ruMetros3: Result:= 'Metros cubicos'; ruLitros: Result:= 'Litros'; ruLibras: Result:= 'Libras'; ruPulgadas: Result:= 'Pulgadas'; ruPulgadas2: Result:= 'Pulgadas cuadradas'; ruPulgadas3: Result:= 'Pulgadas cubicas'; ruPies: Result:= 'Pies'; ruPies2: Result:= 'Pies cuadrados'; ruPies3: Result:= 'Pies cubicos'; ruYardas: Result:= 'Yardas'; ruYardas2: Result:= 'Yardas cuadradas'; ruYardas3: Result:= 'Yardas cubicas'; ruOnzas: Result:= 'Onzas'; ruQuarts: Result:= 'Quarts'; ruGalones: Result:= 'Galones'; end; end; var Str: String; i: Integer; d: Double; Registro: TRegistro; begin while TRUE do try Readln(Str); while Str <> EmptyStr do begin Writeln; Registro:= LeerRegistro(Str); Writeln('AI: ' + Registro.AI); Writeln('Descr: ' + Registro.Descripcion); Writeln('Valor: ' + Registro.Valor); case Registro.Tipo of rtTexto: Writeln('Tipo: Texto'); rtNumero: begin Writeln('Tipo: Numero'); Writeln('Decimales: ' + IntToStr(Registro.Decimales)); Writeln('Unidades: ' + UnidToStr(Registro.Unidades)); d:= StrToFloat(Registro.Valor); i:= Registro.Decimales; while i>0 do begin d:= d / 10; dec(i); end; Writeln('Valor: ' + FloatToStr(d)); end; rtFecha: begin Writeln('Tipo: Fecha'); with Registro do Writeln('Fecha: ' + Copy(Valor,5,2) + '/' + Copy(Valor,3,2) + '/' + Copy(Valor,1,2)); end; rtEAN13: Writeln('Tipo: EAN13'); end; end; Writeln; except On E: Exception do begin Writeln; Writeln('Error al leer codigo'); Writeln; end; end; end.
Al ejecutarlo, el programa se queda esperando a que le pasemos el código, si nuestro escaner es de teclado podemos usarlo.
Por ejemplo, para el código de la imagen tenemos el siguiente resultado:
011942112345001110101234^]15991231 AI: 01 Descr: Shipping Container Code Valor: 19421123450011 Tipo: Numero Decimales: 0 Unidades: Valor: 19421123450011 AI: 10 Descr: Batch Number Valor: 101234 Tipo: Texto AI: 15 Descr: Sell by Date Valor: 991231 Tipo: Fecha Fecha: 31/12/99
Para una etiqueta que incluye peso:
019843701118208431030070001723041210CA180412 AI: 01 Descr: Shipping Container Code Valor: 98437011182084 Tipo: Numero Decimales: 0 Unidades: Valor: 98437011182084 AI: 310 Descr: Product Net Weight Valor: 007000 Tipo: Numero Decimales: 3 Unidades: Kilogramos Valor: 7 AI: 17 Descr: Expiration Date Valor: 230412 Tipo: Fecha Fecha: 12/04/23 AI: 10 Descr: Batch Number Valor: CA180412 Tipo: Texto
El código fuente y el programa ya compilado se puede bajar de aquí
Para saber más:
http://en.wikipedia.org/wiki/GS1-128
http://www.gs1-128.info/ai-values/
http://www.barcodeisland.com/uccean128.phtml
Comentarios
Un artículo muy trabajado,
Un artículo muy trabajado, muchas gracias, me ha sido de gran ayuda.