Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Validar Nif (https://www.clubdelphi.com/foros/showthread.php?t=31447)

Colgueit 08-05-2006 18:08:10

Validar Nif
 
Hola,

He estado buscando por internet alguna función que valide si el NIF introducido es correcto, pero no encuentro nada. Bueno, he encontrado una función en la pagina http://www.rinconcitodelphi.com/trucos/Util1.htm que comprueba tanto el Cif como el Nif lo cual me resultaría aun más util pero en el código que se proporciona faltan 2 funciones (EsNumero y EsNif).

¿alguien sabe alguna funcion que verifique el NIF? o ¿Alguien tiene hechas estos 2 funciones?.

Gracias de antemano, Un Saludo

delphi.com.ar 08-05-2006 20:08:01

La entidad que lo regula/provee/creo... ¿No publica el algoritmo?

Colgueit 08-05-2006 20:28:36

Ahí no aparece, y les he escrito y no me responden.
Pero bueno tiene que haber más codigos hechos para validar los NIF, aunque no paro de buscar y no encuentro nada.
Bueno pues a ver si lo encuentro , si no a ver si alguien sabe lo sabe y me lo dice ;) .

Chauuu

seoane 08-05-2006 20:32:03

La letra del NIF (supongo que estamos hablando de España) se calcula utilizando el resto de la division del numero entre 23. Con ese valor vamos a la siguiente lista de letras y usamos la que corresponda:

Código:

TRWAGMYFPDXBNJZSQVHLCKET
Por si no me explico muy bien, aqui te dejo un codigo de ejemplo:
Código Delphi [-]
function Letra(Numero: Integer): string;
begin
  Result:= copy('TRWAGMYFPDXBNJZSQVHLCKET',1 + (numero mod 23),1);
end;

Colgueit 08-05-2006 20:38:23

Ah bien gracias, ya solo lo que me falta sería comprobar que los ocho primeros digistos son numero y con el último hacer lo que dices. Pero no se bien manejar cadenas de caracteres.
Entonces ¿como haría la comprobación completa de que los 8 primeros digitos sean numeros y que el noveno sea un caracter que valida a esos ocho digitos?

Gracias otra vez

seoane 08-05-2006 20:49:08

Ya puestos vamos a hacer el trabajo completo ;)

Código Delphi [-]
function Letra(Numero: Integer): string;
begin
  Result:= copy('TRWAGMYFPDXBNJZSQVHLCKET',1 + numero mod 23,1);
end;

function EsCorrecto(NIF: String): Boolean;
var
  Numero: Integer;
begin
  Result:= FALSE;
  // ¿Puede haber NIF de mas de 9 caracteres? de menos seguro que no
  if Length(NIF) >= 9 then
    if TryStrToInt(Copy(NIF,1,Length(NIF)-1),Numero) then
      Result:= Uppercase(Copy(NIF,Length(NIF),1)) = Letra(Numero);
end;


// Ejemplo de como usar la funcion
if EsCorrecto('12345678Z') then
    ShowMessage('Correcto')
  else
   ShowMessage('Incorrecto');

Colgueit 08-05-2006 21:28:43

Conseguido
 
Perfecto! Ya lo he probado y todo OK.
Muchas Gracias Seoane!

gluglu 08-05-2006 23:42:44

Y pregunto yo ?

No puede haber cifras del DNI que sean menor de 10.000.000, y con ello la longitud ser menor de 9 ?

Yo creo recordar DNI's con cifras menores de esos Diez Millones (que me perdonen, pero supongo que de gente bastante mayor ...).

Por ello creo que deberías reconsiderar entonces la comprobación de la longitud. El método para calcular la letra sigue siendo perfectamente válido.

Si sirve como indicación adicional, dicho método también se puede aplicar a las Tarjetas de Residentes emitidas en España. En este caso, siempre empezaría por una 'X', seguido de 7 cifras y la letra final según el método descrito.

Saludos

Colgueit 09-05-2006 00:48:08

Que yo sepa todos los Nif son de 8 numeros y la letra, estoy casi seguro vaya, eso si para Nif españoles.

En Nif extranjeros cambia la cosa y es un problema que me establa planteando ya que usando esta funcion para comprobar los Nif no puedo introducir un Nif que no sea español, que aunque no es muy común se puede dar el caso y el usuario no podría insertar en la base de datos a un cliente extranjero, con lo cual no se que hacer al respecto...

Chauu

seoane 09-05-2006 01:19:32

La longitud fue mas una suposicion que una certeza, no había visto nunca ningun documento menor de 10.000.000, pero siempre se aprenden cosas nuevas. El caso es que probando con el programa PADRE, no me deja introducir un nif de menos de 9 letras ni de mas, no se si los de hacienda saben algo que yo ignoro pero sus razones tendran.

De todas formas no cuesta nada poner como requisito que se deben rellenar con ceros a la izquierda los numeros que no alcancen las nueve cifras. En algunos impresos oficiales ya te lo piden.

O simplemente podemos comprobar que la longitud esta entre 8 y 10
Código Delphi [-]
function LetraNIF(Numero: Integer): string;
begin
  Result:= copy('TRWAGMYFPDXBNJZSQVHLCKET',1 + numero mod 23,1);
end;

function EsNIFCorrecto(NIF: String): Boolean;
var
  Numero: Integer;
begin
  Result:= FALSE;
  // Eliminamos espacios y separadores
  while (pos(' ',NIF)>0) do
    delete(NIF,pos(' ',NIF),1);
  while (pos('-',NIF)>0) do
    delete(NIF,pos('-',NIF),1);
  while (pos('/',NIF)>0) do
    delete(NIF,pos('/',NIF),1);
  // La longitud entre 8 y 10 deberia de valer
  if Length(NIF) in [8..10] then
    if TryStrToInt(Copy(NIF,1,Length(NIF)-1),Numero) then
      Result:= Uppercase(Copy(NIF,Length(NIF),1)) = LetraNIF(Numero);
end;

identsoft 09-05-2006 07:47:12

oficialmente si el cif/nif tiene menos de 9 dígitos, hay que rellenar esos huecos con 0

Colgueit 09-05-2006 13:18:30

Lo conseguí
 
Cogiendo lo que habeis escrito, un ejemplo de trucomania, con algunas cosas que he añadido y con varias horas de trabajo he hecho un código que comprueba tanto si es un Nif, Cif o Nif Extrangero, creo que he contemplado casi todas las posiblilidades.
Lo he probado y parece que funciona bien pero siempre puede haber errores, si veis algo mal comentadlo please.
Pues nada aquí dejo el código para quien lo quiera ;) .

Código Delphi [-]
function Letra(Numero: Integer): string;
begin
  Result:= copy('TRWAGMYFPDXBNJZSQVHLCKET',1 + numero mod 23,1);
end;

function EsNif(NIF: String): Boolean;
var
  Numero: Integer;
begin
   Result:= FALSE;
   if TryStrToInt(Copy(NIF,1,Length(NIF)-1),Numero) then
      Result:= Uppercase(Copy(NIF,Length(NIF),1)) = Letra(Numero);
end;

function EsNumero(Num: Char): Boolean;
begin
  try
    StrToInt(Num);
    Result:=True;
  Except
    result:=False;
  end;
end;

{Eliminamos espacios y separadores}
function CadLimpiaCar(NIF: String): String;
 begin
 Result:= NIF;
  while (pos(' ',NIF)>0) do
    delete(NIF,pos(' ',NIF),1);
  while (pos('-',NIF)>0) do
    delete(NIF,pos('-',NIF),1);
  while (pos('/',NIF)>0) do
    delete(NIF,pos('/',NIF),1);
  Result:=NIF;
end;


{ Validar si un CIF introducido es correcto}
function ValidaCif(Cif : String) : Boolean;
 var
    Suma, Control : Integer;
    n             : Byte;
 begin
   Result := False;

   {Se pasa todo a mayúsculas limpio de espacios y de caracteres especiales}
   Cif := UpperCase(Trim(Cif));

   {Se limpia de los caracteres '-' y '/'. }
   Cif := CadLimpiaCar(Cif);

   {El cif debe ser de 9 cifras}
   if Length(Cif) = 9 then
   begin
     {Comprobamos que sea un NIF}
     if EsNumero(Cif[1]) then
       Result := EsNif(Cif)
     else
       {Se comprueba que la letra que designa el tipo de cif sea correcta}
       if (Pos(Cif[1], 'ABCDEFGHPQSKLMX') = 0) then
         Result := False
       else
         {Se comprueba si es un extranjero,
          en ese caso se calcula el nif, cambiando la X, por 0}
         if Cif[1] = 'X' then
           Result := EsNif('0'+Copy(Cif,2,8))
         else
         begin
          if EsNumero(Cif[9]) then
          begin
           Suma:= StrToInt(Cif[3])+StrToInt(Cif[5])+StrToInt(Cif[7]);
           for n := 1 to 4 do
             Suma := Suma + ((2*StrToInt(Cif[2*n])) mod 10)+((2*StrToInt(Cif[2*n])) div 10);
           Control := 10 - (Suma mod 10);
           {Se comprueba si es de tipo 'P' o 'S', es decir,
            Corporaciones Locales (Ayuntamientos, etc.)
            y Organismos públicos.}
           if Pos(Cif[1],'PS')<>0 then
             {Control tipo letra}
             Result := (Cif[9] = Chr(64+Control))
           else
           {Resto de tipos de CIF}
           begin
             {Control tipo número}
             if Control = 10 then
               Control := 0;
             Result:= ( StrToInt(Cif[9]) = Control);
           end;
          end
          else
           Result:=False;
         end;
   end;
end;

Y para usarlo un ejemplo sería este: (yo lo compruebo al salir del Edit)
Código Delphi [-]
procedure TFormX.DBEditNifExit(Sender: TObject);
begin
 DBEditNif.text:= CadLimpiaCar(DBEditNif.text); //esto solo si quiero borrar los caracteres especiales
 //compruebo que es valido
 if not ValidaCif(DBEditNif.text) then
 begin
  MessageDlg('El Cif introducido es incorrecto',mtError, [MBOK],0);
  DBEditNif.Clear;
 end;
end;

Gracias a todos, Saludos.

manuelgomez 10-05-2006 02:50:28

Me comprometo a poner la letra
 
Hola a todos:

Me comprometo a poner para averiguar la letra

Un Saludo


La franja horaria es GMT +2. Ahora son las 22:17:50.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi