Hojas de cálculo en Excel - página principal

Ejecutar una macro a una hora determinada

Son muchos los usuarios que llegan a este blog, buscando como se puede ejecutar una macro a una hora determinada. Realmente hasta el día de hoy, no había explicado como se hacía esto, así que aprovecharé la oportunidad para dar respuesta a las inquietudes de estos usuarios.

Antes de nada, quiero daros mi opinión sobre este macro que hoy veremos. Sinceramente no me gusta nada eso de ejecutar una macro a una hora determinada, porque puede interferir en otros usos que estemos haciendo con la hoja de cálculo. Por ejemplo, podemos estar trabajando con un fichero Excel, y no acordarnos de que a las 18:00 h., se va a cerrar automáticamente Excel sin previo aviso, y sin grabar los últimos cambios que hayamos realizado. Claro, si te sucede eso, pillas un buen cabreo...

En fin, comentarios aparte, vamos a ver como podemos ejecutar una macro a una hora determinada. Como siempre, lo veremos con un ejemplo. En este caso, lo que haremos será mostrar un mensaje cuando den las 18:00 h., avisándonos de que finaliza nuestra jornada laboral. El macro que grabaremos en un módulo, será este:


Sub Auto_open()
'Lanzamos el macro llamado mensajillo,
'cuando den las 6 de la tarde

Application.OnTime TimeValue("18:00:00"), "mensajillo"
End Sub

Como podéis ver, entre comillas aparece un texto llamado mensajillo. Pues bien, ese es el nombre del macro que se ejecutará a las 18:00 h., y que no es otro que este (que tendremos que grabar también en un módulo):

Sub mensajillo()
'lanzamos un mensaje, para avisar que es la
'hora de tomarse una cervecita fuera de la oficina

MsgBox ("Son las 18:00 h., hora de salir de la oficina. ¡Yuhuuuu!")
End Sub

Cuando lleguen las 18:00 h., nos aparecerá este bonito mensaje en pantalla, siempre que no hayamos cerrado el fichero que ejecuta estas macros (o no hayamos cerrado Excel, si tenemos los tenemos en el libro personal de macros):


Con esto, ya lo tenemos todo hecho. ¿Facilito, verdad?. Pues ahora solo nos queda por dar respuesta a algunas dudas.

¿Por qué tiene ese nombre tan raro el macro?. ¿Qué es eso de Auto_open()?. Pues es el nombre que obligatoriamente debe tener el macro para que al abrir el fichero, empiece a contar el tiempo, y que cuando den las 18:00 h. nos avise. Evidentemente, deberá estar abierto el fichero, para que eso suceda, pues en caso contrario no nos aparecerá el aviso. En lugar de crear ese macro Auto_open() en un módulo VBA, podemos hacer lo mismo llamando al evento Open a través de un macro llamado Workbook_Open(), dentro de ThisWorkbook, en lugar de hacerlo en un módulo.

¿Tengo que tener siempre abierto -aunque sea minimizado-, el fichero donde tengo ese "contador" de tiempo?. No necesariamente. Puedes grabar el macro en el libro personal de macros. Este libro está siempre "latente" para cuando lo necesitemos, pero oculto, por lo que el macro se ejecutará a la hora programada, siempre y cuando tengas abierto Excel, claro está.

Si en lugar de ejecutar el macro con ese mensaje a las 18:00h., quisiéramos que se ejecutase al cabo de 30 minutos contados a partir de ese mismo instante, es decir, a partir de la hora que pongamos en marcha el "contador", entonces deberemos cambiar el macro inicial, por este otro:

Sub Auto_open()
'Lanzamos el macro llamado mensajillo,
'30 minutos después de ejecutar este Auto_open,
'que es cuando ponemos en marcha el contador de tiempo

Application.OnTime Now + TimeValue("00:30:00"), "mensajillo"
End Sub



19 comentarios:

Miguel Pérez dijo...

Hola, Javier.

No he sabido cómo hacerte llegar esta consulta, ni si debo hacerlo, pero necesito tu ayuda en una cosita que estoy haciendo. No te asustes, no es lo de forzar la escritura en mayúsculas, ya desistí por el problema que te conté.

El problema que me ocupa ahora yo creo que es de entendimiento con Excel. Te cuento: realizo unos cálculos con la función BDSUMA, cálculos cuyo resultado queda reflejado en una celda, celda donde tengo una función SI que hace que se ejecute BDSUMA si se cumple una condición. Todo bien mientras si se cumple la condición, pero cuando no se cumple, que es al siguiente día, desaparece el resultado del cálculo que hizo en su día y me pone un cero, como si hubiese sumado cero, pero no ha podido sumar nada, porque no se cumple la condición para que se ejecute BDSUMA.

No sé qué hacer. Me tiene loco y seguro que es una gilipollez.

Gracias y perdón,
Miguel

Miguel Pérez dijo...

¿Cómo se haría para que se ejecutara con la fecha del sistema?

Gracias,
Miguel

El pilt®afilla - www.3piesalgato.com dijo...

Siempre se usa la fecha del sistema...

Bien tendrás que informar de la hora a la que quieres que se lance el macro, ¿no?. Pues esa hora la informas en el propio macro, y el reloj que cuenta es precisamente ese, el del sistema :-)

Anónimo dijo...

Saludos Javier...
Una inquietud, Se podria modificar la macro Auto_open() para que ejecute una macro a una hora determinada, en un archivo especifico, incluso sin que este se encuentre abierto, solo teniendo abierto excel.
Gracias por tus comentarios y ayuda.

Anónimo dijo...

Hola Javier...
Esta inquietud ya la resolvi aunque me gustaria de todas maneras conocer tu opinion, lo que me surge ahora es saber como hago para que ejecute en el mismo archivo dos macros distintas a dos horas distintas, por ejemplo la macro "abrir" a las 8:00 a.m. y la macro cerrar a las 4:00 p.m. ya que me sale un mensaje que dice (Error de compilacion. Se ha detectado un nombre ambiguo: Auto_open).
De nuevo muchas gracias y disculpa la molestia.

Anónimo dijo...

Nada, nada era una bobadita, como decimos en Colombia "se me fueron las luces" disculpame, ya esta arreglado. Quedo pendiente a tu opinion de la primera inquietud.
Gracias.

El pilt®afilla - www.3piesalgato.com dijo...

Para ejecutar una macro sin tener abierto un libro de excel (solo teniendo abierta la aplicación), puedes utilizar las macros del libro personal. En realidad ese libro personal está abierto, pero oculto.

Victor dijo...

Hola Javier:

Estoy tratando de retocar esta macro para que me guarde el libro que tengo abierto cada 5 minutos, pero algo me está fallando...

Sub Auto_open()
Application.OnTime Now + TimeValue("00:05:00"), ActiveWorkbook.Save
End Sub

Que pongo mal? Gracias por adelantado

El pilt®afilla - www.3piesalgato.com dijo...

Debes hacer una autollamada al macro. Fíjate en este macro donde se muestra la hora cada segundo: poner la hora en una celda.

Fíjate que lo que estamos haciendo es autollamar al macro "reloj". Aquí tienes que hacer algo similar, llamando al macro Auto_open

Un saludo.

Anónimo dijo...

Esto funaciona cuando se abra el archivo Excel conel auto_open, se puede sin abrir el archivo ejecutar una macro de copia de archivos, lo necesito para realzair copias de una transcripcion ya que tuvimos problemas con que algunos archivos estaban cambiados y la información era erronea, las maquinas de los trasncriptores son muy mala para poner una progrma ya sea en VB6 o superior, por favor ayudenme...
Atte, Ruben

Gusmario dijo...

hola...

se podria programar varias columnas para que cada 24 hrs, se bloque y no permita que se ingresen mas datos y asi asegurar que no se modifiquen, por ejemplo:
tenemos la columna "A" celda A1 con la fehca de hoy, columna "B" celda B1 con la fecha de mañana y asi sucecivamente por decir 7 dias y el resto de las celdas pueden ser usadas, pero al cumplirse las 24hr del dia de hoy se active la macro que impida ingresar mas datos a la columna "A", pero los renglones de las demas columnas seguiran abiertos, obvio que al cumplirse las siguientes 24hr, esta columna tambien se bloqueara y asi seguira hasta cumplir con todos los dias, al terminar la semana debera de desbloquear las columnas para permitir el analisis de esta informacion.

Podria alguien ayudarme con esto o sera mucho pedir?

gracias...

Gusmario dijo...

Hola...

En vista de que nadie opina o intenta ayudarme, viendo aqui, viendo haya, preguntando por aca, pude hacer lo que queria, "PERO", tengo un problema, quiero simplificar el codigo, ya que es muy pesado estar agregando dias a la macro, no habria forma de simplificarla!!!... Ya que si quiero me bloque un determinado rango hoy y otro determinado rango mañana, lo tengo que agregar todo dia por dia, aqui el codigo:

Sub bloquear_Cada_24_Horas()
If Date > DateSerial(2011, 5, 8) Then
Range("A2:A41").Select
ActiveWindow.SmallScroll Down:=-21
Selection.Locked = True
Selection.FormulaHidden = False
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
Range("A1").Select

If Date > DateSerial(2011, 6, 8) Then
ActiveSheet.Unprotect
Range("b2:b41").Select
ActiveWindow.SmallScroll Down:=-21
Selection.Locked = True
Selection.FormulaHidden = False
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
Range("b1").Select

If Date > DateSerial(2011, 7, 8) Then
ActiveSheet.Unprotect
Range("c2:c41").Select
ActiveWindow.SmallScroll Down:=-21
Selection.Locked = True
Selection.FormulaHidden = False
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
Range("c1").Select

If Date > DateSerial(2011, 8, 8) Then
ActiveSheet.Unprotect
Range("d2:d41").Select
ActiveWindow.SmallScroll Down:=-21
Selection.Locked = True
Selection.FormulaHidden = False
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
Range("d1").Select

If Date > DateSerial(2011, 9, 8) Then
ActiveSheet.Unprotect
Range("e2:e41").Select
ActiveWindow.SmallScroll Down:=-21
Selection.Locked = True
Selection.FormulaHidden = False
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
Range("e1").Select

If Date > DateSerial(2011, 10, 8) Then
ActiveSheet.Unprotect
Range("f2:f41").Select
ActiveWindow.SmallScroll Down:=-21
Selection.Locked = True
Selection.FormulaHidden = False
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
Range("f1").Select

If Date > DateSerial(2011, 11, 8) Then
ActiveSheet.Unprotect
Range("g2:g41").Select
ActiveWindow.SmallScroll Down:=-21
Selection.Locked = True
Selection.FormulaHidden = False
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
Range("g1").Select
End If
End If
End If
End If
End If
End If
End If
End Sub


AYUDA POR FAVOR!!!...

El pilt®afilla - www.3piesalgato.com dijo...

Hola Gusmario.

Ten en cuenta que esto no es un foro, y que lo normal es responder a las preguntas que surgen como consecuencia de alguna duda no aclarada en el artículo en cuestión. Aparte de eso, ten en cuenta que tenemos otras obligaciones, y que no todo es bloguear :-)

Aquí tienes el macro que buscas, y que se ejecutará automáticamente al abrir el libro:

Sub Auto_open()
'ocultamos el procedimiento
Application.ScreenUpdating = False
'si hay errores, que continúe
On Error Resume Next
'comenzamos con el 05-08-2011, que equivale a 40760
fecha_inicial = FormatDateTime(40760, 0)
columna_inicial = 1 'equivale a la columna A
diferencia_en_dias = DateDiff("d", fecha_inicial, Date)
'desbloqueamos toda la hoja
ActiveSheet.Unprotect
Cells.Locked = False
'bloqueamos en función de los días de diferencia
Range(Cells(2, 1), Cells(41, 1 + diferencia_en_dias)).Select
Selection.Locked = True
ActiveSheet.Protect
'volvemos a A1
Range("A1").Select
'mostramos el procedimiento
Application.ScreenUpdating = True
End Sub

Saludos.

Gusmario dijo...

Perdona si te hice molestar, no fue mi intencion, se que no son esclusivos para el bloguear, gracias por el codigo, si simplifica mucho el procedimiento que hice yo. Repito gracias por la ayuda, y disculpa mi insolencia, simplemente me frustra el intentar algo muchas veces y no conseguir el resultado deseado.

Gracias Javier Marco.

El pilt®afilla - www.3piesalgato.com dijo...

No tienes que pedir disculpas por nada Gusmario :-)

Un saludo.

Bernardo dijo...

buenas noches Javier, mira a ver si puedes ayudarme, seguro que el problema es muy facil ¡pero no lo veo! :(, tengo en un libro siete macros que tienen que ejecutarse aleatoriamente (desde qeu se abre el libro hasta que se cierra), en intervalos de 7 minutos, sé hacer una macro para que empiece a determinada hora, pero no paso de aqui, :(, mira a ver si me puedes echar una manita.


Saludos y gracias

El pilt®afilla - www.3piesalgato.com dijo...

Bernardo, prueba esto:

Sub Auto_open()
'Lanzamos el macro llamado lanzar_aleatorio,
'7 minutos después de ejecutar este Auto_open,
'que es cuando ponemos en marcha el contador de tiempo
Application.OnTime Now + TimeValue("00:07:00"), "lanzar_aleatorio"
End Sub

Sub lanzar_aleatorio()
'ejecutamos el código que nos genera los números
'aleatorios y asociamos un nº a un macro
'bla, bla, bla
'bla, bla, bla
'volvemos a Auto_open
Auto_open
End Sub

Para el tema de los aleatorios, mírate este artículo: aleatorios no repetidos. Luego, con un poco de imaginación, puedes asociar un número a un macro, con la instruccion Select Case (en la ayuda de VBA de Excel, puedes ver un ejemplo).

Saludos.

Bernardo dijo...

Gracias por responder tan rapido, ya mañana le echaré un ojo, y te comento como me ha ido.

gracias nuevamente

Unknown dijo...

muy buen blog, Felicitaciones