Como gerar código de barras 2of5 Interlaved
Para quem precisa gerar código de barras em seus sistemas sabe como é difícil ter adaptar os
componentes existentes em seu projeto, além do valor que se paga por um componente não free!
Uma solução que se adota na maioria das vezes é a utilização de fontes que geram esses códigos, que
tem que ser enviadas para os clientes para serem instaladas em suas máquinas.
Vamos ver aqui, um exemplo bem simples de como gerar o código de barras via código delphi, neste
caso usei o 2of5 Interlaved, que é uma fonte mais difícil de se encontrar e principalmente de se usar, devido as
características deste código.
Este exemplo simplesmente gera o código digitado em Edit1, em um componente TquickRep, na
posição determinada pelos Edit2 e Edit3.
Este exemplo pode ser adaptado para qualquer outro modelo de código de barras, bastando para isto
estudar a definição do código e aplicar seus conceitos na codificação.
Tentei simplificar ao máximo este código, não utilizando comandos pouco conhecidos, para que
qualquer um possa entender o código, que tem por objetivo de apenas dar uma idéia inicial de como as barras
são montadas, cabe ao leitor agora adaptá-lo para suas necessidades, não implementei aqui, por exemplo,
checagem dos valores para validá-los, evitando possíveis erros, além disso, estou gerando as barras para 6
dígitos, o código deve ser alterado para aceitar qualquer outra quantidade...
Antes de iniciar a parte prática, vamos ver um pouco da teoria aplicada aqui, que é essencial para que se
possa adaptar esse código para seus sistemas.
Tomando o 2of5I como exemplo, a primeira coisa a se fazer é buscar sua especificação, o que não é
difícil de se encontrar, basta digitar em qualquer bom site de busca o termo “Interleaved 2 of 5 Specification”
e aparecem vários sites muito bons... sugiro aqui alguns que são bem interessantes:
http://209.249.179.251/pub/russadam/i25code.html
http://www.barcodeman.com/info/c2of5.php
http://www.aimglobal.org/aimstore/linearsymbologies.htm
http://www.idautomation.com/itffaq.html
http://www.barcodeisland.com/2of5.phtml
Com a especificação na mão, vamos verificar que a característica deste código é que cada dígito é
formado por 5 barras, e são utilizados os espaços para gerar um dígito também, intercalando barras e espaços,
por exemplo:
O código de barras para o número 010129 é:
Ele é formado por um cabeçalho, que são as primeiras 2 barras e os primeiros 2 espaços, considerando
barras pretas e espaços (barra curta, espaço curto, barra curta, espaço curto), depois deste cabeçalho começamos
a ver a codificação para os números. Você pode ver que há 15 barras e 15 espaços, cada grupo de 5 forma um
número intercalando o código inicial nas barras e espaços, assim, para o código 010129, as 15 barras formam os
números 002 e os 15 espaços, são os números 119. Depois disto, vemos o rodapé do código, formado por 2
barras e 1 espaço (barra larga, espaço curto, barra curta).
Então, cada número recebe uma codificação, como se segue:
0 CCLLC
1 LCCCL
2 CLCCL
3 LLCCC
4 CCLCL
5 LCLCC
6 CLLCC
7 CCCLL
8 LCCLC
9 CLCLC
Onde C é uma barra ou espaço curto e L é uma barra ou espaço longo. Vale lembrar que o código 2of5I
só aceita números.
Assim, temos:
Cab eça lho
01
01
29
Ro d a p é
Se considerarmos que cada barra curta preta recebe o código de P, as barras longas pretas o G, as curtas
brancas o Q e as longas brancas o H, temos que:
•
•
•
•
•
O cabeçalho é formado por: PQPQ
O conjunto 01, por: PHPQGQGQPH
O segundo 01, por: PHPQGQGQPH
O 29, por: PQGHPQPHGQ
E, por último, o rodapé: GQP
Esta vai ser a codificação que vamos utilizar para gerar nosso código de barras.
Desta forma, vemos que ao entendermos a especificação do código de barras que queremos desenhar,
fica fácil criar um código em qualquer linguagem de programação para gerar este código.
Neste exemplo, usei o objeto TQRShape para gerar as barras, alternando suas propriedades de tamanho
e cor de acordo com o tipo de barra (se largo branco, largo preto, curto longo e curto preto).
Para ficar mais claro, vamos ao código! Vou comentar os blocos em separado e no final do artigo você
verá o código completo:
Antes de mais nada, crie um novo projeto, e insira no formulário 3 componentes TEdit, 1 TButton e 1
TquickRep:
Ao clicar no Button1, vamos pegar o valor digitado no Edit1 e para cada número, saber qual é a
seqüência de barras que o formam. Como o primeiro número vai ser formado por barras, o segundo por espaços
e assim por diante, precisamos também controlar esta intercalação.
No evento OnClick do Button1, insira o seguinte código:
procedure TForm1.Button1Click(Sender: TObject);
const
quant = 3;
var
m, p, k : integer;
BarraP, BarraB : array [1..quant] of string[5];
codigo, codebar, codetemp : string;
valor : integer;
shape : TQRShape;
pos : integer;
begin
codigo := Edit1.text;
for m := 0 to quant do
begin
BarraB[m] := '';
BarraP[m] := '';
end;
p := 1;
k := 1;
for m := 1 to length(codigo) do
begin
valor := strtoint(codigo[m]);
if Par(m) then
begin
BarraB[k] := GeraBarCode25(valor, 2);
inc(k);
end
else
begin
BarraP[p] := GeraBarCode25(valor, 1);
//neste exemplo, estou criando um código que aceita números
//de 6 dígitos...
//armazenando 3 em BarraP (as barras pretas), e 3 em BarraB
//(as barras brancas)
//primeiro, pegamos o valor a ser codificado...
//e limpamos o array que vai armazenar a sequencia de barras
//agora, para cada número,
//vamos verificar a posição dele utilizando uma função
//para descobrir se a posição é par ou impar...
//assim podemos armazenar em BarraB, a seqüência de barras
//brancas, utilizando a função GeraBarCode25, que vamos
//detalhar logo abaixo
//e em BarraP a seqüência de barras pretas
inc(p);
end;
end;
for m := 1 to quant do
for p := 1 to 5 do
CodeTemp := CodeTemp + BarraP[m][p] +
BarraB[m][p];
CodeBar := 'PQPQ' + CodeTemp + 'GQP';
pos := strtoint(Edit3.text);
for m := 0 to length(CodeBar) do
begin
Shape := tQRShape.create(QuickRep1);
shape.Parent := QuickRep1;
shape.top := strtoint(Edit2.text);
shape.left := pos;
Shape.Height := 80;
//agora, vamos intercalar as barras brancas e pretas,
// armazenadas em BarraP e BarraB
//e por ultimo, acrescentamos o cabeçalho e o rodapé de nosso
//código...
//agora, é só desenhar as barras, de acordo com a codificação
//armazenada em CodeBar, começamos por definir a posição
//inicial, que foi digitado em Edit3
//criamos um Shape…
//definimos a propriedade Top...
//a posição inicial...
//e sua altura
if CodeBar[m] = 'P' then
begin
Shape.Width := 5;
Shape.Brush.color := clBlack;
shape.Pen.color := clBlack;
//e aqui, para cada valor de CodeBar, vamos gerar sua barra
//correspondente
//se for uma barra preta curta, atribuímos a largura como 5,
//e as cores para preto
pos := pos + 5;
end
else if CodeBar[m] = 'G' then
begin
Shape.Width := 10;
Shape.Brush.color := clBlack;
shape.Pen.color := clBlack;
//e atualizamos a variável pos paraa posição da próxima barra
pos := pos + 10;
end
else if CodeBar[m] = 'Q' then
begin
Shape.Width := 5;
Shape.Brush.color := clWhite;
shape.Pen.color := clWhite;
pos := pos + 5;
end
else if CodeBar[m] = 'H' then
begin
Shape.Width := 10;
Shape.Brush.color := clWhite;
shape.Pen.color := clWhite;
//o mesmo para a barra longa preta,
//atribuindo 10 para sua largura
//para a barra branca curta
//e por ultimo se for a barra longa branca!
pos := pos + 10;
end;
end;
end;
E agora, vamos ver a função GeraBarCode25, podemos considerá-la como o núcleo do projeto, o que
ela faz é retornar, para cada dígito uma seqüência de letras que determina qual barra deve ser desenhada, sendo
P para a barra preta curta, G para a barra preta longa, Q para a barra curta branca e por último H para a barra
longa branca:
function TForm1.GeraBarCode25(Valor, pos:
integer): string;
Var
Barra : string[5];
Begin
if pos = 1 then
Begin
case Valor of
0 : barra := 'PPGGP';
1 : barra := 'GPPPG';
2 : barra := 'PGPPG';
3 : barra := 'GGPPP';
4 : barra := 'PPGPG';
5 : barra := 'GPGPP';
6 : barra := 'PGGPP';
7 : barra := 'PPPGG';
8 : barra := 'GPPGP';
9 : barra := 'PGPGP';
end;
End
Else
Begin
case Valor of
0 : barra := 'QQHHQ';
1 : barra := 'HQQQH';
2 : barra := 'QHQQH';
3 : barra := 'HHQQQ';
4 : barra := 'QQHQH';
5 : barra := 'HQHQQ';
6 : barra := 'QHHQQ';
7 : barra := 'QQQHH';
8 : barra := 'HQQHQ';
9 : barra := 'QHQHQ';
end;
end;
//de acordo com a posição do número...
//vamos desenhar barras pretas…
//ou brancas!
//respeitando a codificação definida pela especificação
//do 2of5I
E, por ultimo, a função que verifica, se a posição do dígito é par ou ímpar, para determinarmos se ele vai
ser gerado com barras pretas ou brancas:
function TForm1.Par(numb: Integer): boolean;
begin
if (numb div 2) = (numb/2) then
result := True
else
result := False;
end;
É isso aí... o principal objetivo desse exemplo não foi criar um componente totalmente funcional, mas
principalmente mostrar que entendendo o conceito da especificação dos códigos de barras, fica fácil gerá-los
utilizando qualquer linguagem de programação. Agora é só e colocar a mão na massa!
Resultado final:
Código fonte completo:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, QuickRpt, Qrctrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
QuickRep1: TQuickRep;
Edit2: TEdit;
Edit3: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
function GeraBarCode25(Valor, pos: integer): string;
function Par(numb: Integer): boolean;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function TForm1.GeraBarCode25(Valor, pos: integer): string;
var
Barra : string[5];
begin
if pos = 1 then
begin
case Valor of
0 : barra := 'PPGGP';
1 : barra := 'GPPPG';
2 : barra := 'PGPPG';
3 : barra := 'GGPPP';
4 : barra := 'PPGPG';
5 : barra := 'GPGPP';
6 : barra := 'PGGPP';
7 : barra := 'PPPGG';
8 : barra := 'GPPGP';
9 : barra := 'PGPGP';
end;
end
else
begin
case Valor of
0 : barra := 'QQHHQ';
1 : barra := 'HQQQH';
2 : barra := 'QHQQH';
3 : barra := 'HHQQQ';
4 : barra := 'QQHQH';
5 : barra := 'HQHQQ';
6 : barra := 'QHHQQ';
7 : barra := 'QQQHH';
8 : barra := 'HQQHQ';
9 : barra := 'QHQHQ';
end;
end;
result := barra;
end;
function TForm1.Par(numb: Integer): boolean;
begin
if (numb div 2) = (numb/2) then
result := True
else
result := False;
end;
procedure TForm1.Button1Click(Sender: TObject);
const
quant = 3;
4var
m, p, k : integer;
BarraP, BarraB : array [1..quant] of string[5];
codigo, codebar, codetemp : string;
valor : integer;
shape : TQRShape;
pos : integer;
begin
codigo := Edit1.text;
for m := 0 to quant do
begin
BarraB[m] := '';
BarraP[m] := '';
end;
p := 1;
k := 1;
for m := 1 to length(codigo) do
begin
valor := strtoint(codigo[m]);
if Par(m) then
begin
BarraB[k] := GeraBarCode25(valor, 2);
inc(k);
end
else
begin
BarraP[p] := GeraBarCode25(valor, 1);
inc(p);
end;
end;
for m := 1 to quant do
for p := 1 to 5 do
CodeTemp := CodeTemp + BarraP[m][p] + BarraB[m][p];
CodeBar := 'PQPQ' + CodeTemp + 'GQP';
pos := strtoint(Edit3.text);
for m := 0 to length(CodeBar) do
begin
Shape := tQRShape.create(QuickRep1);
shape.Parent := QuickRep1;
shape.top := strtoint(Edit2.text);
shape.left := pos;
Shape.Height := 80;
if CodeBar[m] = 'P' then
begin
Shape.Width := 5;
Shape.Brush.color := clBlack;
shape.Pen.color := clBlack;
pos := pos + 5;
end
else if CodeBar[m] = 'G' then
begin
Shape.Width := 10;
Shape.Brush.color := clBlack;
shape.Pen.color := clBlack;
pos := pos + 10;
end
else if CodeBar[m] = 'Q' then
begin
Shape.Width := 5;
Shape.Brush.color := clWhite;
shape.Pen.color := clWhite;
pos := pos + 5;
end
else if CodeBar[m] = 'H' then
begin
Shape.Width := 10;
Shape.Brush.color := clWhite;
shape.Pen.color := clWhite;
pos := pos + 10;
end;
end;
end;
end.