Con ALT + F11 nos dirigimos al editor de
VBA, e insertamos un nuevo módulo; haremos esta labor mediante una
UDF (user define function, o función definida por el usuario).
Antes de codificar veamos los pasos a seguir, con las 5 variables y 2 constantes arriba mencionadas. Nuestra función requerirá un solo argumento: el año sobre el cual se desea averiguar la fecha de Pascuas.
1) A es el resto de la división: Año mod 19
2) B es el resto de la división: B = (Año mod 4)
3) C es el resto de la división:: C = (Año mod 7)
4) D es el resto de la división: D = (19.A + M) / 30
5) E es el resto de la división: E = (2.B + 4.C + 6.D + N) / 7
Luego de efectuar los cálculos matemáticos, se presentan dos condiciones a tener en cuenta:
1) Si (D + E) < 10, la Pascua se festejará el día (D + E + 22) de Marzo.
2) Si (D + E) > 9, la Pascua se festejará el día (D + E - 9) de Abril.
Y, como todo en esta vida, presenta sus excepciones:
Si la fecha resultante es 26 de abril, Pascua será el 19 de abril.
Si la fecha resultante es 25 de abril, con: D=28, E=6 y A>10, Pascua será el 18 de abril.
Ja, buen lío esto de calcular anualmente la festividad. Es lo que hay y nos ajustaremos a ello.
Elegí realizar esta labor mediante una
UDF para que luego les sea factible colocar en el código un "punto de interrupción" y así ir observando "paso a paso" (con
F8) como se van obteniendo los valores. Igual podrían armar una pequeña tabla en la planilla y hacer todo esto con funciones comunes (acción que llevo a cabo en la siguiente imagen).
Sigamos. Luego del merengue que supone todo esto, y antes de pasar al código en sí, realizaremos un cálculo "a mano", con el año actual:
2011.
M y
N (dado el período de tiempo en el cual nos encontramos) tendrán los valores constantes:
24 y
5, respectivamente.
En D1 ingresamos el año actual:
Vamos x parte:
1) Los primeros 5 cálculos, utilizando la funcion
RESTO(número; número_divisor)
2) Sumamos
D+E
3) Las condiciones que nos impone el cálculo: si la suma del punto anterior es menor a 10 o bien es mayor o igual a 10.
4) Dejo en una celda aparte, para facilitar la compresión, el mes en que caerá la Pascua.
5) Excepciones: si es 26 de abril, entonces se festeja el 19. Si es 25 de abril, y: e=6, a>10, entonces se festeja el 18. Si no sucede nada de lo anterior, coloco el día calculado previamente (en este caso, el 24)
6) final: con
FECHA(año, mes, día), armo la fecha en la cual se celebra la Pascua, incorporando en esos tres argumentos requeridos los distintos resultados que fuí obteniendo.
En el archivo que les dejo se encuentra el ejercicio en cuestión.
Todas las funciones vistas podrían anidarse, pero les dejo esa tarea, la cual con un poco de paciencia la llevarán a cabo sin problemas. Creo que si ahora me largo a "juntar" funciones esto se haría un lío difícil de comprender.
Volquemos todo lo anterior a una
UDF. Encontrarán dentro de este código algunas variaciones, como por ejemplo un bloque de If...Else...., encargado de calcular los valores de M y N (si, para eso también hay un protocolo), que varía de acuerdo al año pasado como argumento. En el ejemplo de la planilla sólo sirve para un determinado período de tiempo (del año 1900 al 2099, mas que suficiente para cualquiera que esté leyendo estas líneas), pero en
VBA lo incluyo por dos motivos: 1) es mas sencillo y 2) siempre alguien necesita conocer las fechas pasadas o futuras, para aplicarlas a trabajos específicos.... o por simple curiosidad.
Public Function Pascuas(Año)
'las variables
Dim A, B, C, D, E, M, N, Dia, Mes
'primero chequeamos que el argumento
'requerido sea numérico:
If Not IsNumeric(Año) Then
Pascuas = "error"
Exit Function
ElseIf Año = "" Then
Pascuas = "error"
Exit Function
ElseIf Año < 1583 Then
Pascuas = "error"
Exit Function
ElseIf Año > 2299 Then
Pascuas = "error"
Exit Function
Else
'condicionales que le dan valores válidos a
'M y N, de acuerdo al año de Pascua que nece
'sitamos calcular:
If Año >= 1583 And Año <= 1699 Then
M = 22
N = 2
ElseIf Año >= 1700 And Año <= 1799 Then
M = 23
N = 3
ElseIf Año >= 1800 And Año <= 1899 Then
M = 23
N = 4
ElseIf Año >= 1900 And Año <= 2099 Then
M = 24
N = 5
ElseIf Año >= 2100 And Año <= 2199 Then
M = 24
N = 26
ElseIf Año >= 2200 And Año <= 2299 Then
M = 25
N = 0
End If
'los primeros 5 resultados:
A = Año Mod 19
B = Año Mod 4
C = Año Mod 7
D = (19 * A + 24) Mod 30
E = (2 * B + 4 * C + 6 * D + N) Mod 7
'=====================================
'sobre la base de los datos obtenidos
'ahora calculo el día y mes:
If (D + E) < 10 Then
Dia = (D + E + 22)
Mes = 3
ElseIf (D + E) > 9 Then
Dia = (D + E - 9)
Mes = 4
End If
'=====================================
'las excepciones:
If (Dia = 26) And (Mes = 4) Then
Dia = 19
ElseIf (Dia = 25) And (Mes = 4) And (D = 28) And (E = 6) And (A > 10) Then
Dia = 18
End If
'y aquí retorno un valor: con DateSerial() armo la fecha
'de Pascuas (idem a la función FECHA() )
Pascuas = DateSerial(Año, Mes, Dia)
End If
End Function
Los resultados:
las dos últimas funciones, a propósito, generan un error: como argumento paso una cadena de texto (sdfasfadfs) y un dato vacío.
Bien gente, Felices Pascuas.
(
link al archivo)
Este comentario ha sido eliminado por un administrador del blog.
ResponderEliminar