Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Ayuda con esta Función (https://www.clubdelphi.com/foros/showthread.php?t=67674)

Ledian_Fdez 29-04-2010 21:16:35

Ayuda con esta Función
 
Hola amigos de este foro:
Estoy haciendo una aplicación donde necesito validar el numero de carnet de identidad.

Nota:
Soy cubano y el número de carnet tiene la sguiente estructura:

- Contiene 11 dígitos.
- año de nacimiento
- mes de nacimiento
- dia de nacimiento

ejemplo: 81123105227 (año, mes, día, ...)

Hasta el momento lo que he implementado es validar que tenga 11 dígitos y que sea una fecha de nacimiento valida y especificar si es un mes valido. Pero me gustaría especificar aun mas, por ejemplo cuando un día este incorrecto.

ejemplo 75023012345 día incorrecto.
ejemplo 75043112345 día incorrecto.

Gracias de antemano ... ;)

Saludos,
Ledian.

PD: El código esta en la respuesta de abajo.

Ledian_Fdez 29-04-2010 21:20:06

Código
 
Código Delphi [-]
Function ValidaCI(CI : String) : Boolean;
var
 flat : Boolean;
 fecha : TDateTime;
begin
 flat := True;
 if (Length(CI) <> 11) then
   begin
    flat := False;
    Application.MessageBox('No. Carnet de Identidad incompleto.' + #13 + 'Rectifique por favor.','SAF', MB_ICONERROR);
   end
 else if StrToInt(Copy(CI,3,2)) > 12 then
   begin
    flat := False;
    Application.MessageBox('Error en el mes del Carnet de Identidad.' + #13 + 'Rectifique por favor.','SAF', MB_ICONERROR);
   end
 else
   begin
    try
     fecha := StrToDate(Copy(CI,5,2)+ '/' + Copy(CI,3,2) + '/' + Copy(CI,1,2));
    except
     flat := False;
     Application.MessageBox('La fecha de nacimiento no es válida.' + #13 + 'Rectifique por favor.','SAF', MB_ICONERROR);
    end;
   end;
 Result := flat;
end;

Lord Delfos 29-04-2010 22:00:41

Bueno, usando la función IsValidDate:

Código Delphi [-]
uses DateUtils;

function IsValidDate(Anio, Mes, Dia): Boolean;

Así que yo haría algo así:

Código Delphi [-]
function CIEsValido(const CI: string): Boolean;
begin
  Result:= (Length(CI) = 11) and
           IsValidDate(StrToInt(Copy(CI, 0, 2)), StrToInt(Copy(CI, 2, 2)), StrToInt(Copy(CI, 4, 2))) and
           LosUltimosDigitosSonValidos;
end;

Por supuesto, habría que estar atento a cómo hace IsValidDate para manejar años con dos cifras.

Saludongos.

EDIT: Dado que siempre que se le pida al usuario ingresar números, éste va a ingresar LETRAS (el 100% de las veces :)), también sería conveniente validad antes de hacer los StrToInt.

Ledian_Fdez 29-04-2010 22:26:24

Mensajes?
 
Eso esta buenísimo, pero ...¿Cómo le digo al usuario donde esta el error? Si en el día, el mes o la cantidad de dígitos. :confused:


Salu2,
Ledian.

Lord Delfos 29-04-2010 23:01:00

Bueno, en ese caso estás jodido, porque que yo sepa no hay una función de Delphi que haga eso.

Se me ocurre que se podría hacer algo así:

Código Delphi [-]
procedure ValidarFecha(Anio, Mes, Dia: Integer; out Error: Integer);
begin
  if Anio <= 0 then //Ó Anio < 0 si es año con dos dígitos.
    Error:= 1
  else if not (Mes in [1..12]) then
    Error:= 2
  else if (Dia > MonthDays[IsLeapYear(Anio), Mes]) then
    Error:= 3
  else
    Error:= 0;
end;

var Error: Integer;

begin
  ValidarFecha(2010, 2, 29, Error);
  case Error of
     0: ShowMessage('La fecha es válida.');
     1: ShowMessage('Año incorrecto.');
     2: ShowMessage('Mes incorrecto.');
     3: ShowMessage('Día incorrecto.');
  end;
end;

Mystery 30-04-2010 14:29:22

Hola Ledian_Fdez bueno ahora re pongo tu misma funcion un poco modificada...
primero el CI aparte de la fecha de nacimiento te brinda el sexo pues el penultimo numero del CI si es par es hombre y si es impar bueno tu sabes...
por ejemplo te pongo un grupo de funciones y luego la tuya... OK...
esta funcion es del truco 389 de trucomania
Código Delphi [-]
function DiasMes(fecha: TDateTime): integer;
var
   PrimerDiaMes, PrimerDiaMesSiguiente : TDateTime;
   anyo, mes, dia: Word;
begin
   DecodeDate( fecha, anyo, mes, dia );
   primerDiaMes := EncodeDate(anyo, mes, 1);
   primerDiaMesSiguiente := IncMonth(primerDiaMes, 1);
   result := Round(primerDiaMesSiguiente - primerDiaMes);
end;

esta me brinda el sexo.
Código Delphi [-]
function sexo(a:integer):boolean;
begin
  Result:=False;
  if (a mod 2)=0 then
    result:=True;
end;
y esta es la ultima... te especifico que a esta ultima le pasas el numero de CI completo no solo la fecha sino completo para que te devuelva el sexo en una variable global OK...
Código Delphi [-]
Function ValidaCI(CI : String) : Boolean;
var
  dia, mes, anio:Word;
  sex:Integer;
  fecha : TDateTime;
begin
  result:=True;
  if Length(CI)<>11 then
  begin
    Result := False;
    Application.MessageBox('No. Carnet de Identidad incompleto.' + #13 + 'Rectifique por favor.','SAF', MB_ICONERROR);
  end;
  anio:=StrToInt(Copy(CI,0,2));
  mes:=StrToInt(Copy(CI,3,2));
  dia:=StrToInt(Copy(CI,5,2));
  sex:=StrToInt(CI[Length(CI)-1]);
  try
    fecha:=EncodeDate(anio, mes, dia);
  except
  end;
  if DiasMes(fecha)then
  begin
    Application.MessageBox('Error en la cantidad de dias.' + #13 + 'Rectifique por favor.','SAF', MB_ICONERROR);
    result:=False;
    Exit;
  end;
  if not IsValidDate(anio, mes, dia) then
  begin
    Application.MessageBox('Error en la cantidad de dias.' + #13 + 'Rectifique por favor.','SAF', MB_ICONERROR);
    Result:=False;
    exit;
  end;
  if sexo(sex)then
    ShowMessage('Es macho')
  else
    ShowMessage('Es jebita');
end;


bueno a lo mejor se puede optimizar un poco mas pero bueno eso es todo... espero te sirva... OK chaooo

sin mas
Mystery

PD: todo esto es con un form un boton y un Edit, en el onclick llamas a la funcion pasandole el CI OK chaooo

Ledian_Fdez 30-04-2010 15:22:04

Mira esto !!
 
Hola Mystery la funcion DiasMes me devuelve un entero en el if con que lo comparo ???

Código Delphi [-]
if DiasMes(fecha)then  //devuelve un Integer no Boolean
  begin
    Application.MessageBox('Error en la cantidad de dias.' + #13 + 'Rectifique por favor.','SAF', MB_ICONERROR);
    result:=False;
    Exit;
  end;

Salu2,
Ledian.

Ledian_Fdez 30-04-2010 15:47:04

Trucomania
 
Cita:

Empezado por Mystery (Mensaje 362352)
esta funcion es del truco 389 de trucomania

Como pudieras facilitarme el Trucomania?
Si de algo le sirve este es mi correo: joseledian@yahoo.es
o simplemente un link donde descargarlo.

Gracias de antemano,

Salu2,
Ledian

cloayza 30-04-2010 16:17:14

Cita:

Empezado por Ledian_Fdez (Mensaje 362271)
...
Nota:
Soy cubano y el número de carnet tiene la sguiente estructura:

- Contiene 11 dígitos.
- año de nacimiento
- mes de nacimiento
- dia de nacimiento

ejemplo: 81123105227 (año, mes, día, ...)

Hasta el momento lo que he implementado es validar que tenga 11 dígitos y que sea una fecha de nacimiento valida y especificar si es un mes valido. Pero me gustaría especificar aun mas, por ejemplo cuando un día este incorrecto.

ejemplo 75023012345 día incorrecto.
ejemplo 75043112345 día incorrecto.

Podrias colocar el significado de los demas digitos que conformar el Rut y cual es la logica de validacion completa.

Saludos

Ledian_Fdez 30-04-2010 16:28:45

Función OK !!!
 
Creo que con esta implementación gracias a la ayuda de todos ustedes la función cumple con mis especificidades.

Ahí se las dejo.

Código Delphi [-]
Function CIEsValido(CI : String) : Boolean;
var
  dia, mes, anio : Word;
begin
  Result:=True;
  if Length(CI)<>11 then
    begin
     Application.MessageBox('No. de Carnet de Identidad incompleto.' + #13 + 'Rectifique por favor.','SAF', MB_ICONERROR);
     Result := False;
     Exit;
    end;
  anio := StrToInt(Copy(CI,0,2));
  mes := StrToInt(Copy(CI,3,2));
  dia := StrToInt(Copy(CI,5,2));
  if (mes > 12) or (mes < 1) then
    begin
     Application.MessageBox('Error en el mes del Carnet de Identidad.' + #13 + 'Rectifique por favor.','SAF', MB_ICONERROR);
     Result := False;
     Exit;
    end;
  if not IsValidDate(anio, mes, dia) then
    begin
     Application.MessageBox('Error en la cantidad de dias.' + #13 + 'Rectifique por favor.','SAF', MB_ICONERROR);
     Result := False;
     Exit;
    end;


De todos modos si alguien cree que se le pudiera agregar algo mas ...

Muchas gracias :D

Salu2,
Ledian.

cloayza 30-04-2010 16:59:49

Y los demas digitos que funcion cumplen dentro del Rut...

Solo estan para completar los 11?

Saludos.

Lord Delfos 30-04-2010 18:03:45

Cita:

Empezado por Ledian_Fdez (Mensaje 362374)
De todos modos si alguien cree que se le pudiera agregar algo mas ...

Bueno, ya que preguntás... :)

Te digo de onda, no es para criticar, simplemente me parece interesante, ya que estamos:

[1] A mí me parece que deberías validar antes de hacer los StrToInt... Porque si el usuario llega a poner algo que no es número... ¡pum! Se te rompe todo el programa.

[2] Tampoco pondría los MessageDialogs adentro de la función. Siempre es una buena idea que las funciones sean "independientes", es decir que no dependan de cómo trabaja el programa que las usa. Así, si mañana quiero usar la función en un programa que en vez de usar MessageDialogs para dar errores, usa otra cosa; la función me sirve igual.

[3] Eso de andar poniendo Exit por ahí... Hmmm... No es una buena práctica, hay ocasiones en las que es necesario, pero para mí en este caso sería mejor que saques los exit y unas los dos if con un else. Después de todo si el mes es incorrecto, no querés ni fijarte si el día está bien o mal.

Código Delphi [-]

---MAL---

if Mes_mal then
  begin
  Algo;
  Exit;
  end;
if Dia_mal then
  begin
  Algo;
  Exit;
  end;

--MEJOR--

if Mes_mal then
  Algo
else if Dia_mal then
  Algo;

Y, como dice el amigo cloayza, habría que ver qué hacen los otros números y si hay que agregar alguna validación más.

En fin. Saludongos.


La franja horaria es GMT +2. Ahora son las 14:11:36.

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