Saturday, August 26, 2006

[ACCESS] Calculando la edad de una persona

En la generación de reportes, si éste muestra la información de personas, es común que se necesite mostrar su edad en años, el inconveniente aquí es que las bases de dato no contienen una función nativa que nos permita realizar esta tarea (p.ej: CalculaEdad(parámetros)).

Ahora, las funciones que nos proporciona MS Access para trabajar con los tipos de dato DateTime (Fecha/Hora) nos serán de utilidad:

DatePart(...,CampoFecha) nos devuelve un elemento del CampoFecha, reemplazando en '...' por 'd' para obtener el día, 'm' para los meses, 'yyyy' para los años, etc.

DateDiff(...,CampoFechaMenor,FechaReporte) nos devuelve un entero que representa la diferencia entre las fechas indicadas como parámetro de acuerdo a lo indicado en el primer parámetro, es decir, si usamos 'd' nos devolverá la diferencia de días entre ambas fechas, 'm' devolverá la diferencia de meses, etc.

El problema aquí es que si trabajamos a nivel de meses o años, el valor que retornará DateDiff() será la resta exacta de los valores de esos campos en las fechas, por ejemplo:




Fecha de Nacimiento: 29/08/1982
Fecha de Reporte : 01/01/2006
Resultado de DateDiff a nivel de años: 24


Pero si notamos realmente, la persona no tiene aún 24 años, tiene 23, la función ha devuelto (2006 - 1982)=24.

Si trabajamos a nivel de meses encontraremos un problema similar
Fecha de Nacimiento: 29/08/1982
Fecha de Reporte : 01/01/2006
Resultado de DateDiff a nivel de meses: 281

Si tomamos los 281 meses y los dividimos entre 12 para obtener la edad en años tendremos: 23.41, si piensas truncar el número a 23 observa el siguiente caso:
Fecha de Nacimiento: 29/08/1982
Fecha de Reporte : 01/08/2006
Resultado de DateDiif a nivel de meses: 288

Si tomamos los 288 y los dividimos entre 12 tendremos 24, pero la persona aún no tiene 24 años, por lo que no se podría truncar siempre al nivel de enteros el número obtenido.

Entonces usaremos la idea lógica, si a la persona del último caso se le preguntara cuántos años tiene, respondería 23 y en 28 días más tendría 24, entonces tendremos que bajar al nivel de días cuando sea necesario, es decir:

Edad = (Diferencia de meses / 12) y de ser el caso que el mes de nacimiento es el mismo mes sobre el cual se quiere obtener la edad, verificar los días, restando en uno la edad si aún no se ha llegado en el mes al día de su cumpleaños.

Traduciendo la idea a SQL con funciones de MS Access (y utilizando la tabla del ejemplo):

SELECT
P.NOMBRE, P.FECNAC,
DATEDIFF('m', P.FECNAC, NOW)/12
+
IIF(DATEPART('m',P.FECNAC)=DATEPART('m',NOW),
IIF(DATEPART('d',P.FECNAC)>DATEPART('d',NOW),-1,0)
, 0) AS EDAD FROM PERSONA P
WHERE P.FECNAC
Donde NOW es una función de MS Access que devuelve la fecha actual (se cambiaría por la fecha de generación del reporte o fecha de corte), IIF( , , ) es la selección condicional IIF(Evaluación,acción si evaluación es verdadera, acción si evaluación es falsa).

Notar que es importante la sección WHERE para asegurarnos que la persona exista antes de la fecha de corte y no obtener valores negativos.

3 Comments:

At 5:45 AM, Anonymous Anonymous said...

muchas gracias, DATEDIFF es justo la función que estaba buscando para controlar un registro de entrada de documentación.

 
At 9:37 AM, Blogger Unknown said...

Muy buena acotacion Ing. Cayetano, deberia sacar un manual con tips para access, ya que es un programa muy util, pero que la mayoria no sabemos manejar muy bien.

 
At 2:48 AM, Anonymous Anonymous said...

Genial brief and this mail helped me alot in my college assignement. Thank you on your information.

 

Post a Comment

<< Home