Sei sulla pagina 1di 34

CURSO ELEMENTAL DE FECHAS TAL

COMO SE USAN EN ACCESS

Autor: César de Miguel - Aloa Informática S.L. -


cesar@aloa.info

(aplicable en otros entornos relacionales, salvando las


distancias)

Parte 1ª: Fechas


(Tempus fugit: Así pasan los días)
En esta parte sólo hablaremos de fechas. Posteriormente
hablaremos de horas (junto con las fechas).
Para empezar, entendamos algo que es básico.
Si alguien no lo entiende, que se lo crea. ¡Es una orden
para seguir el curso!

Una fecha (un día concreto) en Access es un nº entero.


Una fecha en Access No es una combinación de palabras, letras,
números y separadores, ni de palabras ni de formatos.
Insisto. Un día cualquiera es un número entero, y Hoy (el día
en que esto escribo es) = 37940.
Hoy, día 15 de Noviembre del Año de Gracia de 2003, sábado
es, para Access, el día 37940 (y así se almacena).
Lo pongas en el formato que quieras (un montón de posibles
combinaciones), internamente es el 37940.
Ayer fue el 37939 y mañana será 37941. Y dentro de mil días
será el 38940.
Ahora bien, para enseñarlo o hablar de hoy no decimos el día
37940, porque sería un rollo, sino que decimos o ponemos,
entre otros formatos:

15 de Noviembre del Año de Gracia de 2003, sábado, ó


15-11-03, ó
15/11/2003, ó
15/XI/2003, ó
11/15/2003, ó
2003/15/11, ó
15 nov 2003, ó
15/2003/11/, ó
Simplemente hoy ó... (más de tropecientas combinaciones sin
contar las versiones del calendario musulmán, ni judío, ni
chino, ni japonés tradicional).

Todos hablamos del mismo hecho, día, pero lo expresamos de


distinta forma.
Así que, ¿son iguales todas ellas?. En expresión, no; pero en
contenido, sí.

Lo podemos probar diciéndole a cualquiera que esto es una


fecha (y aquí le das cualquiera de las versiones) y, por muy
enrevesada que esté expresada, sabrá que se refiere al día de
hoy. Es decir al 37940.

La idea es buena y simple: almacenamos el número y lo


narramos como nos convenga.
El problema viene de que ciertos 'mensajes' son equívocos.

Por ejemplo, la fecha 2003/12/25, seguro que, incluso para el


estadounidense medio de la América más profunda, será el
Christmas que del año 2003, aunque le choque un poco porque
no es esa su forma acostumbrada de expresarlo.

Pero si le dices 7/4/2004 no tendrá dudas de que es su fiesta


nacional del año 2004, su cuatro de julio, mientras que para el
menda, o sea César, es el día en que tengo que preparar el
semillero de calabazas, porque ya es el siete de abril. ¿Veis lo
equívoco del continente o formato del mensaje?

Así pues, al meter fechas en la base de datos no importa cómo


la introduzcas, siempre que y cuando no sea equívoca. (De aquí
sale un consejo: si lo metes en forma de número entero no
habrá equivocaciones, o como aconseja Frank Rivera en OSI:
aaaa/mm/dd).

Por lo tanto las fechas no se meten en la base de datos en


formato de fecha corta, larga, semilarga, fusa o semifusa: las
fechas se meten en formato fecha (entendiendo por ello
cualquiera que entienda el sistema) siempre que no sea
confusa.

Para que se entienda mejor, el hecho de variar el color de la


fecha y ponerla en color rojo no afecta al valor de la fecha.

Es lo mismo 23/11/2006 que 23/11/2006 que 23/11/2006 que


23/11/2006 que ... ¿o es que se almacena de distinta forma?
Pues también es lo mismo 23/11/2006 que 11/23/2006, ó que
23/2006/11, ó que 2006/23/11, ó que .........Lo que sí sucede
es que se presenta en cada circunstancia en el formato que
convenga: rojo, letra bastardilla (con perdón), Times, 12 pt,
aa/mmm/dddd, ...

Cuándo es equívoca (cuidado con la configuración regional y


con la diferencia entre el ámbito español del Access -consultas,
formularios, informes- y al ámbito inglés -VBA y SQL-) es
cuando vienen los líos, y eso es lo que hay que evitar.
Fin de esta parte.

Preguntas a esta parte:


1.- ¿Se puede acceder a ese número interno de fecha?.
¿Cómo?.
Variable = clng(MiFecha)
Ej. ?clng(date()) nos devuelve 37942
Respuesta sólo válida para el día en que hoy (devuelto por la
función date())era el 37942.

2.- ¿Se puede, una vez conocido ese número, pasarlo al


formato que queramos?. ¡Siempre!. ¿Cómo?.
Por fuera, ámbito español: NúmeroVistoComoFecha =
CDate(Número;"dd/mm/aaaa"). Usado en ámbito español, es
decir en tablas, consultas, formularios e informes
Por dentro, ámbito inglés: NúmeroVistoComoFecha =
CDate(Número,"mm/dd/yyyy"). En ámbito inglés, es decir en
SQL y VBA .

3.- ¿Existe alguna manera de crear una fecha en access


que diga exactamente" 3 de febrero de 2005"; y no como
me sale con la fecha larga:"jueves, 3 de febrero de
2005"?
Crear lo que se dice crear, NO si quieres que sea un campo de
tipo Fecha/hora, pero si le puedes dar el formato que pides:

Format(Date,"dd"" de ""mmmm"" de ""yyyy"), si es en Visual


Basic
ó con
dd" de "mmmm" de "aaaa, si es consulta, formulario, ...

4.- ¿Sucede lo mismo en otras Bases de Datos?


En Access, en Oracle, en SQL Server y en la inmensa mayoría
de las BD actuales (no conozco ninguna excepción) un campo
de tipo Date, ó DateTime, ó (como se llame en cada sitio) ...,
es internamente una cifra entera.

Cada Sistema de Gestión de Base de Datos (SGBD) lleva un


calendario continuo, un día tras otro, desde el origen que han
querido poner. Tan simple y claro, como que hoy es ayer + 1, y
pasado mañana será mañana + 1 ú hoy + 2 ó ayer + 3, ..., y
no importa que en medio se cambie de año, mes, semana, siglo
ó milenio.

Del formato, que si juliano, que si gregoriano, que si ISO, que


si OSI, que si EuroDate, que si DateBush (o que te den igual
mejor), que si FoxFate, que si ..., son formas externas de ese
nº. Son máscaras, por decirlo así, de presentación del mismo
hecho.

Eso sí, cada SGBD ha tenido libertad para fijar su propio origen,
y así como nuestro calendario occidental contemporáneo difiere
en el origen del chino, del musulmán, judío, romano antiguo, el
de Access también puede diferir de los otros sistemas, y
teniendo en cuenta los ajustes provocados voluntariamente a
cada calendario (¿Sabes, p. ej., que Stª Teresa murió un 4 de
octubre y fue enterrada al día siguiente, 15 de octubre?. Pues,
sí, le pilló una reforma de calendario.)

Parte 2ª: Consolidación del concepto de fechas


en Access

Resumen/repaso de lo publicado (explícita o implícitamente):


En Access, una fecha (un día concreto) es un nº entero.

No importa el formato (tamaño, color, tipo de letra, d-m-


aa, dd-mmm) en que se exprese.

El lío viene al introducirla en la base de datos, ya que varios de


los formatos anteriores -valóralo tu mismo- no sirven para, de
forma clara e inequívoca, decirle al ordenador/computadora a
qué fecha nos referimos.
El problema más habitual es el del cambio de mes por el día y
viceversa, porque 7/4/2003 no es la mismo para un americano
de Los Estardos Unidos de Norteamérica, que para un hispano.
(Por cierto, no sé si nuestras amigos mexicanos usan el formato
mm/dd/aaaa, como estándar) Como sabéis, para uno es el 4 de
julio y para el otro el 7 de abril.

Y este lío lo lleva Access, con no muy buen semblante, porque


por fuera quiere ser hispano y por dentro americano. Y habla
Espánglish ó Inglisñol a su manera. Entonces dependiendo de
qué ambiente uses, Access te entenderá lo uno o lo otro y te
armará líos a poco que te descuides.

Si trabajas en el ámbito externo, es decir, tablas, consultas,


formularios, macros e informes lo entiende como siete de abril.
Este ámbito se caracteriza por el hecho de que si usas
inglés/americano para expresar conceptos, Access lo traduce.
(Ej.: Escribes Not null, y, entonces, va Access y pone la
turbadora traducción de Negado Nulo).

En cambio si estás en el ámbito más interno del producto, SQL


y Visual Basic, allí el idioma de trabajo y el ámbito cultural es el
inglés. Allí no puedes decir 35,24 euros, porque la coma no es
el separador decimal (aunque hace esfuerzos a veces por
traducirlo lo cual complica más las cosas) y si dices
cdate("7/4/2004") te entenderá que es la fiesta nacional de
E.E.U.U. de Norteamérica.

Y es de aquí de donde viene el embrollo, al cual yo no os voy a


dar ninguna solución porque tampoco tengo una vía infalible
(aunque tengo claro que si pusiéramos un sólo número entero
nunca habría problemas). Pero creo que cada uno se buscará la
más adecuada.

No obstante una cosa sabida de las manías de Access, es que si


la fecha se la das en formato aaaammdd nunca confundirá el
día con el mes, ni viceversa. En cuanto detecta que ese es el
formato, no importa el ambiente hispano o anglo, ¡lo entiende
bien!. P. ej. 20030407, es sin duda el siete de abril del año
2003.

Consecuencias:
Averiguar cuántos días han transcurrido entre dos fechas es,
nada más fácil, restarlas:
Clng(date()-MiFcNacimiento) -y a mí me sale la barbaridad
de 20939
(Ejercicio: ¿cuándo nació esta criatura?)

¿Qué día se cumplen los 10000 días de mi vida?:


CDate(FcNacimiento + 10000)
Os paso un montón de ensayos aprovechando las posibilidades
de ayuda, en depuración o en inmediato, de Access:
?FcNacimiento 28/05/1975 (que no es la mía)
?clng(FcNacimiento) 27542
?cdate(FcNacimiento) 28/05/1975
?cdate(clng(FcNacimiento)) 28/05/1975
?cdate(clng(FcNacimiento)+10000) 13/10/2002
?cdate(clng(FcNacimiento+10000)) 13/10/2002
?isdate(fcnacimiento) Verdadero
?isdate(27542) Falso
?#28/5/1975# 28/05/1975
?28/05/1975 2,835443E-03
?"28/05/1975" 28/05/1975
?isdate(28/05/1975) Falso
?isdate("28/05/1975") Verdadero
?clng(fcnacimiento)-date() 04/07/1871
?clng(date()-fcnacimiento) 10406
?clng(fcnacimiento-date()) -10406

Temas de la ayuda de Access.


Consejo: consultar los siguientes temas -especialmente los que
están en negrita- y practicarlos

Obtener la fecha o la hora actuales. Date, Now, Time


Realizar cálculos de fechas. DateAdd, DateDiff, DatePart
Devolver una fecha. DateSerial, DateValue
Devolver una hora. TimeSerial, TimeValue
Establecer la fecha o la hora. Date, Time
Medir el tiempo de un proceso. Timer
Convertir entre tipos de datos. CBool, CByte, CCur, CDate,
CDbl, CDec, CInt, CLng, CSng, CStr, CVar, CVErr, Fix, Int
Establecer tipos de datos intrínsecos. Boolean, Byte, Currency,
Date, Double, Integer, Long, Object, Single, String, Variant
(predeterminado)
Comprobar los tipos de datos. IsArray, IsDate, IsEmpty,
IsError, IsMissing, IsNull, IsNumeric, IsObject
Funciones Day, Month, Year, WeekDay,
Format(expresión[, formato[, primerdíadesemana[,
primerdíadeaño]]])
expresión Obligatorio. Cualquier expresión válida.
formato Opcional. Una expresión de formato definida por el
usuario o con nombre válida.
primerdíadesemana Opcional. Una constante que especifica el
primer día de la semana.
primerdíadeñao Opcional. Una constante que especifica la
primera semana del año.

Ejercicios:
¿En que fecha comienza el calendario de Access?. ¿Cuál
es día 1?
¿Tiene sentido una fecha negativa?
¿Cuál es la diferencia entre "25/12/2003", 25/12/2003
y #25/12/2003#

Para responder, probemos (en la depuración del Access 97 que


es el que más a mano tenía. ¡Ojo que es ambiente americano!):
?cdate(1): 31/12/1899
?cdate(-1): 29/12/1899 Veamos que lo considera algo más que
un número, si lo incluyes con intención de que sea una fecha.

Así por ejemplo, el día del descubrimiento de América se puede


averiguar, al derecho y al revés:
?clng(cdate("12/10/1492")) -148732 (Observar el signo
menos)
?clng(#10/12/1492#) -148732 . (Aquí se nota que hay que
poner mm/dd/aaaa, como ya se había advertido).

"25/12/2003", es un texto. Efectivamente. Y lo usaremos para


expresar una fecha cuando la función nos pide una cadena
(string) de caracteres o para convertirlo en fecha mediante
Cdate("25/12/2003").

25/12/2003, así al desnudo, tiene pinta de expresión aritmética


con dos divisiones. Por ejemplo ?25/12/2003 nos da
0,001040107 (1,040107 E-03, en coma flotante)

#25/12/2003#. Es formato fecha y el sistema intenta


interpretarlo como tal. Pero ¡cuidado! que depende del
ambiente americano o hispano. Aquí, como no existe el mes
'veinticinco-embre', pues no existen dudas, como ha sucedido
arriba, con #10/12/1492#..
Parte 3ª: Hablemos de horas.

¿Y que pasa con las fracciones de día: el mediodía, la


media tarde, la medianoche, el amaiketako, las cinco de
la tarde, las tres y media después de almorzar, las doce y
cuarto, media hora después de empezar el partido, un
cuarto hora de antes de la hora de salida, tres minutos
más tarde, ... ?

Resumen de lo publicado (explícita o implicitamente):

En Access, un día concreto es un nº entero, que se puede


tratar como eso:
un nº al que se pueden sumar o restar días para
trasladarnos en el tiempo ó
hacer semisumas para averiguar el momento
equidistante entre dos fechas, ó ...

Pues primera confesión: Os he mentido un poquito. Debo


precisar algo más.
En realidad un día concreto es la parte entera de un número
decimal, guardado como double-doble en Access.

Así que no es de extrañar que el mediodía del mencionado 15-


11-2003, día que internamente es el 37940, sea 37940,5 (En
americano 37940.5 -obsérvese el punto-).

Dicho de otra forma 37940,5 es en realidad 15-11-2003 12 h


Y con precisión de ferrocarril (al minuto), 37940 es 15-11-2003
00:00 y 37940,5 es 15-11-2003 12:00

Si se ha entendido esto, ya habéis entendido todo el rollo de las


horas, los minutos y los segundos.

Recordad aquellos problemas de secundaria de convertir grados


sexagesimales a centesimales y viceversa y horas, o bien
minutos y segundos a fracciones de día y tendréis una
aproximación muy clarita a lo que aquí se cuece. Veámoslo
haciendo unos ejercicios:

Ejercicios:
Si Jaimito entra al despacho de la directora a las once
menos cuarto y sale veinte minutos más tarde, ¿a qué
hora ha salido?

Pues, hagamos trabajar a la ventana de depuración (Access 97)


o a la inmediato (2000 y sucesivas):
?#10:45# + #00:20#, nos da 11:05:00

o bien dado que veinte minutos expresados en fracción de día


es 20/60/24 días
(20 minutos/60 que tiene la hora/24 horas que tiene el día):
?#10:45# + 20/60/24, pues también nos da lo mismo:
11:05:00

(Nota: 20/60/24 tiene formato de día. Si se me permite el


chiste, podría decir que es el día 20 de sexagesimiembre de
2024 -¿o quizá 1924?-. Esto nos hace reflexionar sobre el por
qué, habitualemente para Access, 12/04/2007 no es lo mismo
que #12/04/2007#. La primera expresión es una división y la
segunda una fecha.)

Otro problema:
El padre de Jaimito trabaja en turno de noche en la fábrica
de colchones ColcheX y entró a las 10 y media de la noche del
14/7/2003. El turno es de 7 horas y 33 minutos. ¿A qué hora
salió?
Hago lo mismo:

?#14/7/2003 22:30# + #7:33#, lo que nos da como respuesta


15/07/2003 6:03:00 , totalmente correcta.

Hubiera sido lo mismo plantearlo como


"A la hora de entrada le sumo la fracción de día que suponen
las 7h con 33m"
y nos debe dar lo mismo.Dado que dicha fracción puede
representarse como
7m 33s = 7/24 + 33/60/24 = 0,3145833 (en americano
0.3145833), no es de extrañar que

?#14/7/2003 22:30# + 0.3145833, también nos dé


15/07/2003 6:03:00

ó que

?#14/7/2003 22:30# + 7/24 (minutos reducidos a días) +


33/60/24 (segundos reducidos a días),

ó que

obtenga el mismo resultado 15/07/2003 6:03:00

ó que

?#14/7/2003 22:30# + ((7 + 33) / 60) / 24, pues lo mismo.

Otro problema:
El padre de Jaimito trabaja en turno de noche en la
fábrica de fibra de vidrio "La Coronita" y entra todas las
noches a las 10 y media. El turno es de 7 horas y 33
minutos. ¿A qué hora sale?

¡Esto está chupado!, nos decimos. Ponemos


?#22:30# + #7:33#,

y nos da la sorprendente (si lo esperábamos ya no es


sorpresa) respuesta de
31/12/1899 6:03:00
En la que observo que la hora de salida es correcta, pero la
fecha, ¿qué pasa con la fecha?

Pues nada; que al no poner día nos considera las diez y media
de la noche del día cero.
Recordemos que dicho día (el cero):

?format(cdate(0),"dd/mm/yyyy, ddd") es el 30/12/1899, sáb

Y como detrás del treinta viene el treinta y uno, pues no es de


extrañar que el día siguiente sea el día de San Silvestre (Año
Viejo) de 1899.
Pues no lo hagáis caso. En realidad yo solo quería saber a qué
hora salía, luego pido sólo la hora.
(No necesito el día: ya me se que es del día siguiente)

¿Como?.

Pues con el Format correspondiente (solo horas y minutos).


?format(#22:30# + #7:33#, "hh:nn" ), obteniendo lo que
cabía esperar: 06:03

Y otro:
¿Cual es el día que está entre el 30 de diciembre de 2003
y el 1 de Enero de 2004?

Pues la semisuma:
?format((#30/12/2003# + #1/1/2004#)/2, "d-m-yyyy") = 31-
12-2003

Si no pongo format: ?(#30/12/2003# + #1/1/2004#)/2


= 37986

Lo que es lo mismo, ya que ?format(37986, "d-m-yyyy") = 31-


12-2003

Otro más, un pelín paradójico, porque pide una respuesta,


digamos, rara:

¿Cual es el día que está entre el 30 de diciembre de 2003


y el San Silvestre de tal año o sea el 31de diciembre de
2003?

?format((#30/12/2003# + #31/12/2003#)/2, "d-m-yyyy") =


30-12-2003

¿Se ha confundido? No. Porque ha buscado el punto medio del


día 30 (cuando empieza) y el del 31 (en su comienzo). ¿Dónde
está dicho punto?. Pues en el mediodía del 30.
Veámoslo de otras formas:

(#30/12/2003# + #31/12/2003#) / 2 = 37985,5 (día 30 y


medio, podíamos decir).

Más claro:
?format((#30/12/2003# + #31/12/2003#)/2, "d-m-yyyy
h:n") = 30-12-2003 12:0, ó
?format((#30/12/2003# + #31/12/2003#)/2, "d-m-yyyy
h:nn") = 30-12-2003 12:00, ó
?format((#30/12/2003# + #31/12/2003#)/2, "d-m-yyyy
h:nn:ss") = 30-12-2003 12:00:00,

donde segundos y minutos no son significativos, porque no


existen, pero si dan idea de una mayor precisión.

Otro:
Quisiera sumar un minuto a la hora actual.
Respuesta:
Now() + (1/1440).
Ó Now() + (1 / 60 / 24)

En ambos casos la expresión entre paréntesis convierte el


minuto en una fracción de día. Pues el día es la unidad en que
se trabaja en esto de las fechas/horas

Más:
Dada una hora en un campo tipo date, llamado LaHora, ¿cómo
redondear al cuarto de hora siguiente?

Respuesta:
cdate(clng ((LaHora * 24 + 0.2499) * 4) / 4 / 24)

(El truco está en trasladar el momento a –casi- un cuarto de


hora más tarde y despreciar la fracción que sobre del cuarto de
hora).

Y otro:
Dada una hora en LaHora, un campo tipo date, ¿cómo
redondear al cuarto de hora más cercano?
Respuesta:

cdate(clng ((LaHora * 24 + 0.1249) * 4) / 4 / 24)

(En la misma línea que el anterior pero ahora traslado a la


mitad del cuarto de hora más tarde)
Convertir una hora en una fracción de día, es un
problema que admite varios enfoques en función de los
datos que tengas y cómo los tengas.

Casos habituales.
Tienes separados o puedes separarlos los componentes del
tiempo: horas, minutos y, quizá, segundos

Su fracción es:

(horas / 24 + minutos / (24 * 60) + segundos) / (24 * 60 *


60)

ó su equivalente

((horas * 60 + minutos) * 60 + segundos) / (24 * 60 * 60)

En el caso de la 8 y media, 8:30, 8,5 (que todos son lo mismo):

8 / 24 + 30 /(24 * 60) = 0.354166

La hora, los minutos y los segundo forman parte de un campo


de tipo fecha ó date:
Sabes que Access expresa un momento en el tiempo, como un
número con parte entera y parte decimal:

día , fracción_del_día

¿Como verlo de esta forma?.

Tomemos el momento actual ó ahora: now(), que mi caso me


da: now() =22/07/2004 8:04:11
(Si fuera un campo llamado momento, sería sustituir now() por
momento)
Pues, para ver sus partes, puede ser así:

cdbl(now()), lo que me da en este


momento: 38190,3374537037 (Hoy es el día 38190. Ahora es
la fracción 0,3374537037 de hoy)

Con lo que queda claro que la fracción del día en la que


estamos es su parte decimal: 0,3374537037

Si la quiero tener separadita, pues le quito la parte entera.


¿Cómo?. Pues

Si quiero verlo en forma de h:m:s:

cdbl(now()) - int(now()) = 8:04:11

Y si lo quiero ver en decimal

cdbl(cdbl(now()) - int(now())) = 0,3374537037

Anexos:
De Leonardo Henrnández Ferreiro

Función para calcular el Domingo de Pascua:


Function DomingoPascua(Año As Integer) As Date
' Esta función ha sido desarrollada por Leonardo Henrnández
Ferreiro lhf@coiim.es
' Particularmente para los usuarios de la lista soloaccess.
Puede utilizarse libremente
' cuantas veces se desee manteneniendo el origen de la
misma
Dim R1 As Integer, R2 As Integer, R3 As Integer, TFECHA As
Date
R1 = (19 * (Año - Int(Año / 19) * 19) + 24) - Int((19 * (Año
- Int(Año / 19) * 19) + 24) / 30) * 30
R2 = (2 * (Año - Int(Año / 4) * 4) + 4 * (Año - Int(Año / 7)
* 7) + 6 * R1 + 5) _
- Int((2 * (Año - Int(Año / 4) * 4) + 4 * (Año - Int(Año / 7)
* 7) + 6 * R1 + 5) / 7) * 7
R3 = R1 + R2
If R3 >= 10 Then TFECHA = (R3 - 9) & "/04/" & Año Else
TFECHA = (R3 + 22) & "/03/" & Año
DomingoPascua = TFECHA
End Function

'Sabiendo el Domingo de Pascua, ya podemos saber más datos,


en forma de diferencia de días:
'Miércoles de Ceniza (Inicio cuaresma) 46 días antes del
domingo de Pascua
'Domingo de Ramos 7 días antes del domingo de Pascua
'Domingo de Ascensión (antes jueves) 42 días después del
domingo de Pascua.
'Domingo de Pascua de Pentecostés 49 días después del
domingo de Pascua
'Domingo de Corpus Christi (antes jueves) 63 días después del
domingo de Pascua

De Francisco Rivera:

' Trabajando con días laborables en VBA


' Author: Ken Getz
' Traducción y Adap: Francisco Rivera (fzombie)

VBA y Access no proveen ningún soporte para trabajar con los


típocos días laborables el "VBA Developers Handbook" contiene
varias funciones que proveen información sobre los días
siguientes y los previos, y para encontrar el primero y el último
día laborable en un mes. Para trabajar con vacaciones, la
función original SkipHolidays acepta una referencia a un
recordset que contenga todas las fechas que quieres brincarte.
Para incrementar la flexibilidad y facilidad de uso, las funciones
originales han sido re-escritas para aceptar una array de
vacaciones, como la función en Excel.

' ********* Inicio del Código **************


‘----------------------------------------------------------------------
--------------------------------------
Public Function AñadeDiasLab(lngDias As Long, Optional
FechaIn As Date = 0, Optional ArrVacaciones As Variant) As
Date
' Añade el número especificado de día laborables a la fecha
indicada
' Entrada:
' lngDias: Número de días laborables que añadiremos a la
fecha inicial
' FechaIn: Fecha en la cual comenzamos a buscar. Se usa
la fecha actual no se especifica una
' ArrVacaciones (Opcional): Array que contiene las fechas
de vacaciones. Puedes ser un solo valor

' Salida:
' Valor de Retorno : La fecha de los días trabajados
tomando en cuenta fines de semana y vacaciones
' Ejemplo:
' AñadeDiasLab(10, #2/9/2000#, Array(#2/16/2000#,
#2/17/2000#))
' nos regresa #2/25/2000#, el cual es la fecha más 10 días
laborables

Dim lngConteo As Long


Dim dtmTemp As Date

If FechaIn = 0 Then FechaIn = Date

dtmTemp = FechaIn
For lngConteo = 1 To lngDias
dtmTemp = SigDiaLab(dtmTemp, ArrVacaciones)
Next lngConteo
AñadeDiasLab = dtmTemp
End Function

‘----------------------------------------------------------------------
--------------------------------------
Public Function SigDiaLab(Optional FechaIn As Date =
0,Optional ArrVacaciones As Variant = Empty) As Date

' Obtiene el siguiente día laborable después de la fecha


especificada.
' Requiere:
‘ SaltarVacaciones
' EsFindeSemana

' Entrada:
' FechaIn: Fecha en la cual comenzamos a buscar. Se usa
la fecha actual no se especifica una.
' ArrVacaciones (Opcional): Array que contiene las fechas
de vacaciones. Puedes ser un solo valor

' Salida:
' Valor de Retorno: La fecha del siguiente día laborable
tomando en cuenta fines de semana y vacaciones
' Ejemplo:
' FechaIn = SigDiaLab(#5/23/1997#, #5/26/97#)

If FechaIn = 0 Then FechaIn = Date

SigDiaLab = SaltarVacaciones(ArrVacaciones, FechaIn + 1,


1)
End Function

‘----------------------------------------------------------------------
--------------------------------------
Public Function AntDiaLab(Optional FechaIn As Date =
0,Optional ArrVacaciones As Variant = Empty) As Date

' Obtiene el anterior día laboral antes dela fecha


especificada.
' Requiere:
‘ SaltarVacaciones
' EsFindeSemana

' Entrada:
' FechaIn: Fecha en la cual comenzamos a buscar. Se usa
la fecha actual no se especifica una.
' ArrVacaciones (Optional): Array que contiene las fechas
de vacaciones. Puedes ser un solo valor
' Salida:
‘ Valor de Retorno: La fecha del anterior día laborable
tomando en cuenta vacaciones y fines de semana
' Ejemplo:
' FechaIn = AntDiaLab(#1/1/2000#, Array(#12/31/1999#,
#1/1/2000#))

If FechaIn = 0 Then FechaIn = Date

AntDiaLab = SaltarVacaciones(ArrVacaciones, FechaIn - 1,


-1)
End Function

‘----------------------------------------------------------------------
--------------------------------------
Public Function PrimerDiaLabMes(Optional FechaIn As Date =
0, Optional ArrVacaciones As Variant = Empty) As Date

' Obtiene el primero día laborable del mes especificado


' Requiere:
‘ SaltarVacaciones
' EsFindeSemana

' Entrada:
' FechaIn: Fecha del mes que nos interesa. Usa la actual si
no especificamos una
' ArrVacaciones (Opcional): Array que contiene las fechas
de vacaciones. Puedes ser un solo valor
' Salida:
‘ Valor de Retorno: La fecha del primer día laborable en el
mes, tomando en cuenta vacaciones y fines de semana
' Ejamplo:
' FechaIn = PrimerDiaLabMes(#1/1/1999#, #1/1/1999#)

Dim dtmTemp As Date


If FechaIn = 0 Then FechaIn = Date

dtmTemp = DateSerial(Year(FechaIn), Month(FechaIn), 1)


PrimerDiaLabMes = SaltarVacaciones(ArrVacaciones,
dtmTemp, 1)
End Function

‘----------------------------------------------------------------------
--------------------------------------
Public Function UltimoDiaLabMes( Optional FechaIn As Date =
0, Optional ArrVacaciones As Variant = Empty) As Date

' Obtiene el último día laboral en el mes especificado.


' Requiere:
‘ SaltarVacaciones
' EsFindeSemana

' Entrada:
' FechaIn: Fecha del mes que nos interesa
' ArrVacaciones (Opcional): Array que contiene las fechas
de vacaciones. Puedes ser un solo valor
' Salida:
‘ Valor de Retorno: La fecha del ultimo día laborable en el
mes, tomando en cuenta vacaciones y fines de semana
' Ejamplo:
' FechaIn = UltimoDiaLabMes(#12/1/1999#,
#12/31/1999#)

Dim dtmTemp As Date


If FechaIn = 0 Then FechaIn = Date

dtmTemp = DateSerial(Year(FechaIn), Month(FechaIn) + 1,


0)
UltimoDiaLabMes = SaltarVacaciones(ArrVacaciones,
dtmTemp, -1)
End Function

‘----------------------------------------------------------------------
--------------------------------------
Public Function ContarDiasLab(ByVal dtmInicio As Date, ByVal
dtmFin As Date, Optional ArrVacaciones As Variant = Empty) As
Integer
' Cuenta los días laborables (sin fines de semana ni
vacaciones en una rango de fechas )
' Requiere:
‘ SaltarVacaciones
' CountHolidays
' EsFindeSemana

' Entrada:
' dtmInicio: Fecha que especifica el inicio del rango
' dtmFin: Fecha que especifica el fin del rango
' ArrVacaciones (Opcional): Array que contiene las fechas
de vacaciones. Puedes ser un solo valor
' Salida:
‘ Valor de Retorno: Número de días laborables, sin contar
fines de semana y opcionalmente vacaciones
' Ejamplo:
' ContarDiasLab(#7/2/2000#, #7/5/2000#, )

Dim intDias As Integer, dtmTemp As Date, intExtrae As


Integer

If dtmFin < dtmInicio Then


dtmTemp = dtmInicio
dtmInicio = dtmFin
dtmFin = dtmTemp
End If

dtmInicio = SaltarVacaciones(ArrVacaciones, dtmInicio, 1)


dtmFin = SaltarVacaciones(ArrVacaciones, dtmFin, -1)
If dtmInicio > dtmFin Then
ContarDiasLab = 0
Else
intDias = dtmFin - dtmInicio + 1

intExtrae = (DateDiff("ww", dtmInicio, dtmFin) * 2)

intExtrae = intExtrae + _
ContarVacacionesA(ArrVacaciones, dtmInicio, dtmFin)

ContarDiasLab = intDias - intExtrae


End If
End Function

‘----------------------------------------------------------------------
--------------------------------------
Private Function ContarVacacionesA(ArrVacaciones As
Variant,dtmInicio As Date, dtmFin As Date) As Long
' Contamos las vacaciones entre dos fechas finales.
' Requerida por:
' ContarDiasLaborables
' Requiere:
' EsFindeSemana

Dim lngItem As Long


Dim lngConteo As Long
Dim blnEncontrado As Long
Dim dtmTemp As Date

On Error GoTo ManejoError


lngConteo = 0
Select Case VarType(ArrVacaciones)
Case vbArray + vbDate, vbArray + vbVariant
For lngItem = LBound(ArrVacaciones) To
UBound(ArrVacaciones)
dtmTemp = ArrVacaciones(lngItem)
If dtmTemp >= dtmInicio And dtmTemp <= dtmFin
Then
If Not EsFindeSemana(dtmTemp) Then
lngConteo = lngConteo + 1
End If
End If
Next lngItem
Case vbDate
If ArrVacaciones >= dtmInicio And ArrVacaciones <=
dtmFin Then
If Not EsFindeSemana(ArrVacaciones) Then
lngConteo = 1
End If
End If
End Select
ExitHere:
ContarVacacionesA = lngConteo
Exit Function

ManejoError:
Resume ExitHere
End Function
Private Function FindItemInArray(varItemToFind As Variant, _
avarItemsToSearch As Variant) As Boolean
Dim lngItem As Long

On Error GoTo ManejoError

For lngItem = LBound(avarItemsToSearch) To


UBound(avarItemsToSearch)
If avarItemsToSearch(lngItem) = varItemToFind Then
FindItemInArray = True
GoTo ExitHere
End If
Next lngItem

ExitHere:
Exit Function

ManejoError:
Resume ExitHere
End Function

‘----------------------------------------------------------------------
--------------------------------------
Private Function EsFindeSemana(dtmTemp As Variant) As
Boolean
' Si tus fines de semana no son Sábado (día7) ó Domingo
(Día 1) cambiamos la rutina para devolver
' True para cualquier días que uses como tus fines de
semana
' Requerida por:
‘ SaltarVacaciones
' PrimerDiaLabMes
' UltimoDiaLabMes
' SigDiaLab
' AntDiaLab
' ContarDiasLab

If VarType(dtmTemp) = vbDate Then


Select Case DiadeSemana(dtmTemp)
Case vbSaturday, vbSunday
EsFindeSemana = True
Case Else
EsFindeSemana = False
End Select
End If
End Function

‘----------------------------------------------------------------------
--------------------------------------
Private Function SaltarVacaciones( ArrVacaciones As Variant,
dtmTemp As Date, intIncrement As Integer) As Date
' Nos saltamos los fines de semana y vacaciones en un
arreglo referido como by ArrVacaciones.

' Requerida por:


' PrimerDiaLabMes
' UltDiaLabMes
' SigDiaLab
' AntDiaLab
' ContarDiasLab

' Requiere:
' EsFindeSemana

Dim strCriterio As String


Dim strNomCampo As String
Dim lngItem As Long
Dim blnEncontrado As Boolean

On Error GoTo ManejoError

Do
Do While EsFindeSemana(dtmTemp)
dtmTemp = dtmTemp + intIncrement
Loop
Select Case VarType(ArrVacaciones)
Case vbArray + vbDate, vbArray + vbVariant
Do
blnEncontrado = FindItemInArray(dtmTemp,
ArrVacaciones)
If blnEncontrado Then
dtmTemp = dtmTemp + intIncrement
End If
Loop Until Not blnEncontrado
Case vbDate
If dtmTemp = ArrVacaciones Then
dtmTemp = dtmTemp + intIncrement
End If
End Select
Loop Until Not EsFindeSemana(dtmTemp)

ExitHere:
SaltarVacaciones = dtmTemp
Exit Function

ManejoError:
Resume ExitHere
End Function

' ********* Fin del Código **************

' Tiempo, añadir y quitar, y hojas de tiempo.


' Author: Robin Stoddart-Stones
' Traducción y Adap: Francisco Rivera (fzombie)

Ha habido un reciente debate sobre como "Añadir tiempo",


"Convertir horas en minutos", y "Trabajar sobre las 24 horas", y
existen métodos interesantes Access 97/2000 tienes el campo
Fecha/Hora que tiene algunas propiedades interesantes.

Preparando el campo Fecha/Hora


Si especificamos el campo Fecha como Fecha/Hora, toma la
fecha y hora actual del sistema. Esto nos da un simple formato
de fecha pata aplicaciones de tiempo.

Vamos a usar la ventana Inmediato para probar esto


(suponiendo que saben manejar la ventana Inmediato)

Usar un botón para almacenar la Fecha y Hora en un campo


Fecha (o una variable de Fecha)
Esto sería:

Dim lsdt as Date (en el módulo) y en la ventana Inmediato (ó


ventana de depuración)
lsdt=Date + Time
? lsdt= "17/02/99 17:10:49" (correcto al momento de escribir)

Un campo fecha puede ser extraido de otro y el resultado sería


la fracción del día

Esto sería:
lsdt=#16:00#-#15:45#
?lsdt
1.04166666666666E-02

? (24*60)*1.04166666666666E-02
14.9999999999999 (aproximadamente 15 minutos para
n/1000ths de un segundo)

En otras palabras, extraer un tiempo de otro para obtener una


respuesta aritmética. Añadimos varias de esas fracciones juntas
y obtenemos el tiempo total.

?1.04166666666666E-02 +1.04166666666666E-02
2.08333333333332E-02
?(24*60)*2.08333333333332E-02
29.9999999999998 (Lo suficientemente cerca a 30 minutos)

Si el resultado está debajo de las 24 horas podemos mostrar el


total de manera muy simple sin usas matemáticas, usando
format (x, "Short Timer")
Esto sería:

?format(2.08333333333332E-02,"short time")
00:30
Lo cual es muy útil.
Por ejemplo si tus cobros son 11.50 por hora entonces tu
promedio diario es = 24*11.50 y el cargo para 30 minutos de
trabajo sería:

?24*11.50 * 2.08333333333332E-02
5.74999999999996

Así, en un campo fecha tienes almacenados el numero de las


horas trabajadas, y una opción de formato nos dice a los
usuarios de ese tiempo en un cálculo simple y podemos obtener
el costo aun debajo de 24 horas totales de trabajo

Pero que pasa si hemos trabajado más de 24 horas ?? Simple,


si añadimos incrementos pequeños. Veamos una demostración
de 47 medias horas a 49 medias horas

?47*2.08333333333332E-02
0.97916666666666
?24* 0.97916666666666
23.4999999999998 (47 medias horas son 23.5 horas)

?48*2.08333333333332E-02
0.999999999999994
?24*0.999999999999994
23.9999999999999 (24 horas)

?49*2.08333333333332E-02
1.02083333333333
?24*1.02083333333333
24.4999999999999 (24.5 Horas)

Ahora, si calculamos la duración podemos añadir esta duración


de 24.5 horas a una fecha y encontrar la fecha final

lsdt=#01-dic-99#
?lsdt
01/12/99
lsdt=lsdt+1.02083333333333
?lsdt
02/12/99 00:30:00

En otras palabras, la medianoche entre el 30/Nov/99 y el


1/Dic/99 + 24.5 horas es pasada la medianoche del 2 de
Diciembre. El único problema es que aqui no tenemos un
formato rápido para decir que número de días y horas tenemos
si hemos ido más allá de las 24.

?format(1.02083333333333,"short Time")
00:30

Pero no nos tomará mucho probar si el valor el mayor que uno


ó calcular la fracción de las 24 horas que restan

lsdt=1.020833333333
dias=Int(lsdt)
?dias
1

Horas=24*(lsdt-dias)
?horas
0.499999999991999

minutos=(horas-int(horas))*60
?minutos
29.99999999952

Y si trabajamos sobre la medianoche, entonces:

?#02-dic-99 00:30# - #01-dic-99 00:00#


1.02083333333576

Lo cual está lo suficientemente cerca para mi en este momento


(La diferencia es la precisión de la máquina cuando multiplica
49 veces)(y 49 medias horas se convierte en 1.0208333333)

Haciendo el proceso al revés:


Si estás trabajanod hojas de tiempo en dónde se escriben las
horas y los minutos en lugar de Tiempos, entonces:

minutos =mins/(24*60)

Horas=hrs/24

Tiempo=horas + minutos

?#07:30#-#00:00#
0.3125
minutos=30/(24*60)
horas=7/24
?horas+minutos
0.3125
Yo suelo tener definidas unas constates públicas que me lo
tienen preparado.

Const hora As Single = 1 / 24


Const minuto As Single = 1 / 24 / 60
Const segundo As Single = 1 / 24 / 60 / 60

Así que cuando quiero restar n minutos de un campo


Fecha/hora llamado, p.ej. instante,
resultado = instante - n * minuto

' Cuantos domingos hay entre dos fechas


' Author: Michel Walsh
' Traducción y Adap: Francisco Rivera (fzombie)

Por una observación inicial hecha por Lyle Fairfield, aqui hay
una solución para obtener el número de, digamos, miércoles
entre dos fechas indicadas:

Public Function CuantosD(FechaIni As Date,FechaFin As


Date,WD As Long)
' Puedes usar el manejo de errores como quieras.
CuantosD = DateDiff("ww", FechaIni, FechaFin, WD)- Int(WD
= WeekDay(FechaIni))
End Function

De la misma forma, alguien puede fácilmente obtener el


número de días de la semana (excluyendo fines de semana)
simplemente quitando el número de sábados y domingos:

Public Function CuantosDSem(FechaIni As Date,FechaFin As


Date,Optional FechaFinesIncluida As Boolean = True)
CuantosDSem = DateDiff("d", FechaIni, FechaFin) -
FechaFinesIncluida - CuantosD(FechaIni, FechaFin, vbSunday) -
CuantosD(FechaIni, FechaFin, vbSaturday)
End Function

FUNCION DIAS LABORABLES


Function Dias_Lab (FechaIni As Variant, FechaFin As Variant)
As Integer
'Esta función no trabaja con vacaciones
Dim Semanas As Variant
Dim DateCnt As Variant
Dim DiasFin As Integer
FechaIni = DateValue(FechaIni)
FechaFin = DateValue(FechaFin)
Semanas = DateDiff("w", FechaIni, FechaFin)
DateCnt = DateAdd("ww", Semanas, FechaIni)
DiasFin = 0
Do While DateCnt < FechaFin
If Format(DateCnt, "ddd") <> "Sun" And _
Format(DateCnt, "ddd") <> "Sat" Then
DiasFin = DiasFin + 1
End If
DateCnt = DateAdd("d", 1, DateCnt)
Loop
Dias_Lab = Semanas * 5 + DiasFin
End Function

' Como manejar la medianoche en los cálculos de tiempo


' Author: Robin Stoddard-Stones
' Traducción: Francisco Rivera (fzombie)

Si quieres incluir a la medianoche en tus cálculos de tiepo, una


manera sencilla
es incluir el operador de medianoche (1)

Sería: #23.45# -1 = 00:15:00

Si necesitas ir más allá de la medianoche entonces necesitas


incluir el operador
(y formatear el resultador para poder entenderlo)

#23:45# - 1-#00.15# = -2.08333333333333E-02

pero

format(#23:45#-1-#00:15#,"short time") = 00:30

format(-2.08333333333333E-02, "short time")= 00:30"

FUNCIONES VARIAS PARA EL MANEJO DE FECHAS


'*************************** Inicio de Código
*******************************
'Este código fué originalmente escrito por Lewis Moseley.
'Eres libre de usarlo en tus aplicaciones, 'siempre y cuando se
quede este copyright.

' Adaptado por Francisco Rivera (fzombie)


'Código cortesía de Lewis Moseley
'
Function PrimeroMes(LaFecha As Date)
' Obtiene la fecha que es el primer dia del mes de la fecha
indicada
Dim D As Integer, M As Integer, Y As Integer
If IsNull(LaFecha) Then
PrimeroMes = Null
Else
D = Day(LaFecha)
M = Month(LaFecha)
Y = Year(LaFecha)
PrimeroMes = DateSerial(Y, M, 1)
End If
End Function

Function UltimoMes(LaFecha As Date)


' Obtiene la fecha que es el último día del mes, de la fecha
indicada
Dim D As Integer, M As Integer, Y As Integer

If IsNull(LaFecha) Then
UltimoMes = Null
Else
D = Day(LaFecha)
M = Month(LaFecha)
Y = Year(LaFecha)
' Encontramos el primer día del siguiente mes y
regresamos un día
UltimoMes = DateAdd("m", 1, DateSerial(Y, M, 1)) - 1
End If
End Function

Function MesSig(LaFecha As Date)


' Obtiene una fecha con un mes más adelantado a partir de la
fecha indicada
MesSig = DateAdd("m", 1, LaFecha)
End Function

Function MesPas(LaFecha As Date)


' Obtiene una fecha con un mes de retraso a partir de la fecha
indicada
MesPas = DateAdd("m", -1, LaFecha)
End Function

Function DiadelMes(LaFecha As Date, DiaEsp As Integer)


' Obtiene la fecha que es el día especificado del mes y año
indicado
Dim M As Integer, Y As Integer
If IsNull(LaFecha) Then
DiadelMes = Null
Else
M = Month(LaFecha)
Y = Year(LaFecha)
DiadelMes = DateSerial(Y, M, DiaEsp)
End If
End Function
'*************************** Fin Código
*******************************

‘ Obtener una fecha en el futuro con una fecha determinana


‘ Author: Dev Ashish
‘ Traducción y Adap: Francisco Rivera (fzombie)

(P) ¿ Como puedo tomar una fecha y obtener la misma


fecha con una año de adelanto ?
tmpFecha = #1/Ene/97#
NuevaFecha= DateSerial(year(tmpFecha)+1,
month(tmpFecha), day(tmpFecha))

Deberíamos obtener un valor de 1/Ene/98para la variable


NuevaFecha.
También podemos usar la función function forde esta manera:

NuevaFecha = DateAdd( 1, "yyyy", tmpFecha)


‘Calcular la edad de una persona
‘Author: Dev Ashish, Michel Walsh & Tim Walters
‘ Traducción y Adap: Francisco Rivera (fzombie)

(P) Como puedo calcular la edad de una persona


conociendo su fecha de nacimiento?

Asumimos que el campo de la fecha de nacimiento se llama


[FechaNac] y es del tipo Fecha, podemos usar el siguiente
cálculo:

Edad=DateDiff("yyyy", [FechaNac], Now())


+Int( Format(now(), "mmdd") < Format( [FechaNac], "mmdd")
)

Alternativa: Puedes usar esta función para calcular la edad

Function Edad(FechaIni, FechaHoy) As Integer


If Month(FechaHoy) < Month(FechaIni) Or
(Month(FechaHoy) = Month(FechaIni) And Day(FechaHoy) <
Day(FechaIni)) Then
Edad = Year(FechaHoy) - Year(FechaIni) - 1
Else
Edad = Year(FechaHoy) - Year(FechaIni)
End If
End Function

Esta es otra función para edad, más detallada

Public Sub CalcEdad(vFecha1 As Date, vFecha2 As Date, ByRef


vYears As Integer, ByRef vMeses As Integer, ByRef vDias As
Integer)
' Calcula la edad en Años, Meses y Días
vMeses = DateDiff("m", vFecha1, vFecha2)
vDias = DateDiff("d", DateAdd("m", vMeses, vFecha1),
vFecha2)
If vDias < 0 Then
vMeses = vMeses - 1
vDias = DateDiff("d", DateAdd("m", vMeses, vFecha1),
vFecha2)
End If
vYears = vMeses \ 12
vMeses = vMeses Mod 12
End Sub
P.- ¿Qué formato aplicar al 1/1/2004 para que salga como “1
de Enero de 2004”?
R.- Prueba con el siguiente formato: d" de "mmmm" de "aaaa

P. Necesito saber cómo generar el día juliano mediante una


fecha, ya sea con una consulta o en un campo calculado en un
formulario.
R. No sé qué entiendes por día juliano.

En mis tiempos de Cobol (¡qué tiempos aquellos!) significaba el


nº de día consecutivo a partir del 1 de enero de ese año.

Si es así, la cosa es una simple resta de fechas.

DíaJuliano = Fecha - cdate("1/1/" & year(Fecha)) + 1, donde


Fecha es aquella para la que quieres el día juliano.

Nosotros llamábamos Fecha Juliana, en contraposición a la


Fecha Gregoriana, a la que se de daba en formato
aajjj ó aaaajjj,

donde a es el año en dos o cuatro cifras y jjj el día juliano


anteriormente definido.

FechaJuliana = format(Fecha, "yy") & format(DíaJuliano,"000")


ó format(Fecha, "yyyy") & format(DíaJuliano,"000") , si es en
ámbito interno ó
FechaJuliana = format(Fecha;"aa") & format(DíaJuliano;"000")
ó format(Fecha; "aaaa") & format(DíaJuliano;"000") , si lo es
en el externo

P. Quiero pasar un numérico a un tipo fecha/hora. Por


ejemplo pasar 120 minutos a un formato hora, es decir, 2:00
horas para luego almacenar esas 2:00 horas en campo
fecha/hora.
R. Access almacena un determinado momento del tiempo como
un nº, el cual
en su parte entera nos habla del día
(es un nº consecutivo desde el 1, referido al día (cdate(1)=)
31/12/1899, en que comienza el calendario de Access), y
en su parte decimal de la fracción del día que corresponda.
Así, por ejemplo, el instante señalado como

el segundo nº 14 del minuto 30 de las 3 de la tarde del 17 de


Mayo del año de gracia de 2002, es para Access el nº

37393,6459953704

El que lo veamos como 17/5/2002 15:30:14 es puro


maquillaje. Eso lo hace el formato que se aplica.

Si pides, port ejemplo,

cdate(37393.6459953704) (entre otras formas), tienes la


respuesta en tu formato regional para fechas y horas. Yo
obtengo: 17/05/2002 15:30:14

Así pues, para transformar cualquier concepto de tiempo al


formato Fecha/Hora debes convertirlo en días.

Si tu número entero habla de minutos, tendrás que dividirlo


entre (24 X 60 =) 1440 minutos que tiene el día y así lo
tendrás con el valor justo.

Ej. tiempo = minutos / 1440


(donde tiempo es un campo Fecha/hora y minutos es el campo
numérico que comentabas)
segundos, habría que dividirlo entre 86400 (24 X 60 X 60)

milisegundos, entre 8640000 que es el resultado de 24 X 60 X


60 X 1000 horas, 24 semanas, habría que multiplicarlo por 7 y
así sucesivamente.

P- Averiguar el nº de días de la semana escogido que hay


entre dos fechas dadas.

Function Pasados(Inicio As Date, Fin As Date, DíaSemana As


Byte) As Integer
''Calcula el número de días de la semana prefijados (lunes,
martes, ...)
'' pasados entre dos fechas puras, inclusive ambas
''Es decir, de un lunes al siguiente lunes, devolvería 2
''DíaSemana: 1 si es Domingo, 2 si Lunes, ... (El estándar de
que el Domingo sea 1, puede cambiarse en el programa)

Dim Semanas As Integer, Quedan As Byte, OtroMás As Byte,


ElInicioEs As Integer, ElÚltimoEs As Byte
If Int(Fin) < Int(Inicio) Then MsgBox "Las fechas deben estar
en orden. Sin embargo " & Inicio & " es posterior a " & Fin: Exit
Function
If DíaSemana < 1 Or DíaSemana > 7 Then MsgBox "El día de la
semana ha de estar entre 1 y 7": Exit Function

Semanas = Int((Fin - Inicio) / 7): Quedan = (Int(Fin) -


Int(Inicio)) - (7 * Semanas)
ElInicioEs = Weekday(Inicio): ElÚltimoEs =
Weekday(DateAdd("D", Quedan, Inicio))
If ElÚltimoEs < ElInicioEs Then
OtroMás = Abs(DíaSemana >= ElInicioEs) + Abs(DíaSemana
<= ElÚltimoEs)
Else
OtroMás = Abs(DíaSemana >= ElInicioEs And DíaSemana <=
ElÚltimoEs)
End If
Pasados = Semanas + OtroMás
End Function

Calcular en minutos el retraso de entrada de una persona

Como no tengo tu modelo de datos, cosa que cuando se pide


ayuda es muy interesante incluir, vamos a ver como calcularía
el retraso en minutos de un señor que teniendo que entrar a las
7:55 entra a la hora que indica su ficha de Marcaje.

Llamo MarcaEntrada al now() del marcaje de la ficha en un día


determinado.
Supongo, pues, que este marcaje incluye el día y la hora.

No me voy a fijar en el día (supongo por muy retrasado que


entre los hará en el mismo día. Si fuera turno de noche que
empieza a las 23:55 y el empleado entra a las 00:17,
estaríamos en otro caso).

HoraDeEntrar = 7/24 + 55/24/60 '<<No


hacemos caso del día
HoraDeEntrada = MarcaEntrada - int(MarcaEntrada)
'<<No hacemos caso del día, y nos quedamos con su fracción

if HoraDeEntrar < HoraDeEntrada then


RetrasoEnFracciónDeDía = (HoraDeEntrada
-HoraDeEntrar) 'días
RetrasoEnFracciónDeHora = (HoraDeEntrada
-HoraDeEntrar) * 24 'horas
RetrasoEnFracciónDeMinuto = (HoraDeEntrada
-HoraDeEntrar) * 24 * 60 'minutos
RetrasoEnFracciónDeSegundoo = (HoraDeEntrada
-HoraDeEntrar) * 24 * 60 * 60 'segundos
Else
'No hay retraso
End if

Si acumulas el tiempo retrasado tendrás el retraso total (en la


unidad de tiempo que hayas escogido). Si no ha sido en
minutos, lo puedes transformar de forma fácil, según hemos
hecho.

FIN

Potrebbero piacerti anche