Dica - Validar código GTIN

Delphi

26/11/2013

Pessoal, tive necessidade esses dias de criar uma rotina que valide códigos GTIN. Como não achei nada parecido, decidi criar a minha própria e postar aqui, caso alguém mais precise. E claro, críticas, correções e sugestões são muito bem vindas!


P.S.: Pra quem não sabe o código GTIN é o famoso código de barras, também conhecido com EAN. O código GTIN é aceito no SPED se tiver 8, 12, 13 ou 14 posições. Nos meus testes eu utilizei códigos GTIN-13 (maioria no Brasil). Segue o código:

function ValidaGTIN(AGTIN: string): boolean;
var
  i, soma, resultado, base10: integer;
begin
  //Verifica se todos os caracteres de AGTIN são números
  for i:= 1 to Length(AGTIN) do
    if not (AGTIN[i] in ['0'..'9']) then
    begin
      Result:= False;
      Exit;
    end;
  //Verifica se AGTIN tem o tamanho necessário
  if Length(AGTIN) in [8,12,13,14] then
  begin
    soma:= 0;
    for i:= 1 to (Length(AGTIN) -1) do
    begin
      //Se for par, multiplica por 3. Se ímpar, por 1
      if Odd(i) then
        soma:= soma + (strtoint(AGTIN[i]) * 1)
      else
        soma:= soma + (strtoint(AGTIN[i]) * 3);
    end;
    base10:= soma;
    //Verifica se base10 é múltiplo de 10
    if not (base10 mod 10 = 0) then
    begin
      while not (base10 mod 10 = 0) do
      begin
        base10:= base10 + 1;
      end;
    end;
    resultado:= base10 - soma;
    //Verifica se o resultado encontrado é igual ao caractere de controle
    if resultado = strtoint(AGTIN[Length(AGTIN)]) then
      Result:= True
    else
      Result:= False;
  end
  else
    Result:= False;
end;


A título de informação, minha fonte para o cálculo do GTIN foi este site: [url]http://www.gs1.org/barcodes/support/check_digit_calculator[/url]

Um abraço a todos!
Jonathan Lazaro

Jonathan Lazaro

Curtidas 2

Melhor post

Jonathan Lazaro

Jonathan Lazaro

26/11/2013

Agora que percebi que tinha cometido um erro... Apenas no GTIN-13 os números das posições ímpares são multiplicados por 1 e os pares por 3. Em todos os outros ocorre o inverso.


Portanto, segue agora o código (certo, espero eu!):

class function TValida.ValidaGTIN(AGTIN: string): boolean;
var
  i, soma, resultado, base10: integer;
begin
  //Verifica se todos os caracteres de AGTIN são números
  for i:= 1 to Length(AGTIN) do
    if not (AGTIN[i] in ['0'..'9']) then
    begin
      Result:= False;
      Exit;
    end;
  //Verifica se AGTIN tem o tamanho necessário
  if Length(AGTIN) in [8,12,13,14] then
  begin
    soma:= 0;
    for i:= 1 to (Length(AGTIN) -1) do
    begin
      if Length(AGTIN) = 13 then
      begin
        if Odd(i) then
          soma:= soma + (strtoint(AGTIN[i]) * 1)
        else
          soma:= soma + (strtoint(AGTIN[i]) * 3);
      end
      else
      begin
        if Odd(i) then
          soma:= soma + (strtoint(AGTIN[i]) * 3)
        else
          soma:= soma + (strtoint(AGTIN[i]) * 1);
      end;
    end;
    base10:= soma;
    //Verifica se base10 é múltiplo de 10
    if not (base10 mod 10 = 0) then
    begin
      while not (base10 mod 10 = 0) do
      begin
        base10:= base10 + 1;
      end;
    end;
    resultado:= base10 - soma;
    //Verifica se o resultado encontrado é igual ao caractere de controle
    if resultado = strtoint(AGTIN[Length(AGTIN)]) then
      Result:= True
    else
      Result:= False;
  end
  else
    Result:= False;
end;
GOSTEI 3

Mais Respostas

João Batista

João Batista

26/11/2013

Rapaz, funcionou que é uma beleza, obrigado pela inciativa de compartilhar o código. Grande abraço,
GOSTEI 1
Jonatas Alves

Jonatas Alves

26/11/2013

Olá,

Muito obrigado Jonathan por compartilhar esta function.

grato!
GOSTEI 0
Rodrigo Menin

Rodrigo Menin

26/11/2013

Sou novo por aqui, e achei interessante seu código;
desculpe minha ignorância, pois poderia mostrar como se aplica pra obter o resultado?
GOSTEI 0
Jonathan Lazaro

Jonathan Lazaro

26/11/2013

Sou novo por aqui, e achei interessante seu código;
desculpe minha ignorância, pois poderia mostrar como se aplica pra obter o resultado?


Boa tarde, Rodrigo!

Então, eu tenho que te falar que não mexo com Delphi há bastante tempo... Porém, se a sua dúvida é "como utilizar esse código dentro de uma aplicação Delphi", tem várias maneiras de se fazer isso.

No caso específico que me motivou a escrever este código, ele era um método estático (por isso "class function") que estava dentro de uma classe chamada TValida, onde pelo nome já dá pra sacar que eu tinha diversas validações. O método retorna um booleano, ou seja, bastaria um jogo de if..else pra fazer a checagem.

if TValida.ValidaGTIN(txtCodBarras.Text) then
ShowMessage('Código de barras ok!');
else
ShowMessage('Código de barras inválido!');
end


Lembrando que isso é só um exemplo. A forma de tratar o fluxo da condição depende de como você pretende utilizar o código.
Se ficar alguma dúvida, só falar! Abraço!
GOSTEI 0
Claudio

Claudio

26/11/2013

Parabéns pela iniciativa!!!
GOSTEI 0
POSTAR