Documentos de Académico
Documentos de Profesional
Documentos de Cultura
MAIN MENU
Share on facebook
Share on twitter
Share on linkedin
Share on whatsapp
Raymundo Ycaza
20 Comentarios
(Votos: 0 Promedio: 0)
Si tienes una macro y quieres que se repita cada cierto tiempo o que no se ejecute hasta una
hora determinada, esto es para ti.
Puede ser que quieras programar un recordatorio en Excel o que necesites ejecutar un proceso
que se repita periódicamente en tu trabajo.
Lo cierto es que en ocasiones nos hace falta darle ese toque automático a nuestras macros, es
decir, que no necesiten de una persona pinchando el botón cada vez.
En otros ámbitos, como en los que se desenvuelven los programadores de Visual Basic clásico y
.NET, contamos con un timer que se encarga de este trabajo; pero en nuestro sencillo editor de
VBA que tenemos en Excel, no existe tal opción.
¿Te he enredado? Pues mira, te dejo una imagen que lo aclara un poco:
Esta macro no funcionará si no la colocas en un módulo. Quiero decir que no puedes colocarla en
cualquier hoja, ni en el libro de trabajo. Debes escribir el código dentro de un módulo.
¿Recuerdas que conversamos sobre cómo insertar un módulo de VBA?
En este módulo, declararás dos variables para comenzar:
Tiempo: Para definir el tiempo que tomará el retraso que deseamos. Declárala como Variant
para el ejemplo.
Ejecutando: Para saber en un momento dado si la macro se está ejecutando o no. Declárala como
Boolean, porque solo queremos saber si es falso o verdadero su valor.
¿Y cómo puedo hacer que una macro se ejecute con ese retraso del que hablo? Pues con el
evento “OnTime” del objeto “Application”.
Este evento se disparará cuando se alcance el tiempo determinado por el usuario y ahí es donde
tú debes indicar el valor que necesitas, ya sea en segundos, minutos u horas.
Entonces, lo que tendrías que hacer es utilizar una variable y en ella colocar la suma de la
fecha/hora actual y el tiempo dentro del cual quieres que se ejecute tu macro, algo así:
Now + TimeValue("00:00:01")
Luego, usaremos el evento OnTime del objeto Application, el cual vendría a comportarse como
un timer. Este evento se activa cuando se alcanza el tiempo determinado por el usuario. Lo
usarás así:
Application.OnTime Tiempo, "miMacro", , True
Como ves, al evento Application.OnTime, le hemos pasado como primer argumento el tiempo
que hemos determinado (un segundo) y como segundo argumento le hemos pasado el nombre
de la macro que queremos que se ejecute (entre comillas, porque es un texto). En mi ejemplo, la
macro se llama “miMacro”.
Colocando el código.
Sub programarMacro()
End Sub
Con esto, estás diciéndole a Excel que, luego de haber transcurrido un segundo, ejecute la macro
“miMacro”.
Si quisieras, podrías usar este “truco” para hacer que tus macros se ejecuten después de un
tiempo de haber pinchado en un botón. Algo así como una alarma o un recordatorio, etc.
La segunda sub-rutina, no hará nada complicado, para facilitar el ejemplo. Lo único que quiero
que haga, es incrementar un contador (que estará en una celda), de manera que parezca un reloj
que va avanzando cada segundo: 1, 2, 3… etc.
¿Sencillo, no?
Bien, ¿y cómo haría eso? ¿Cómo puedo incrementar el valor de una celda?
Elijamos una celda cualquiera, digamos la celda D5. En esta celda quiero que se incremente en
una unidad su valor. Entonces lo haría así:
Range("D5").Value = Range("D5").Value + 1
En el rango D5 (la celda D5), al valor actual que tiene, le vas a colocar el resultado de sumarle el
mismo valor, más una unidad.
Entonces, si el valor era cero, ahora será uno. Si el valor era uno, ahora será dos… Y así,
sucesivamente.
Este código lo vas a poner en otra sub-rutina, la cual se llamará “miMacro”, así:
Sub miMacro()
Range("D5").Value = Range("D5").Value + 1
End Sub
Ahora, cada vez que se ejecute esta sub-rutina, el valor de la celda D5 se incrementará en una
unidad.
Sí, pero…
Esto sucederá una sola vez, ya que desde la sub-rutina “programarMacro” le dijimos que active la
segunda sub-rutina, después de un segundo de haberla ejecutado… Pero esto solo sucede una
vez ¡y nunca más!
Pues, es más sencillo de lo que parece. ¿Recuerdas la primera imagen que coloqué al iniciar este
artículo? En ese gráfico puedes ver que las dos sub-rutinas se llaman entre sí. Es una especie de
“llamada cruzada”. Ahora vamos a hacer que la segunda “le responda” a la primera y así
conseguimos un efecto de recursividad.
Call programarMacro
Call, es una palabra reservada que sirve para invocar a una sub-rutina o función, desde otra
porción de código similar.
Sub miMacro()
Range("D5").Value = Range("D5").Value + 1
Call programarMacro
End Sub
Ahora sí, cuando “programarMacro” ejecute a “miMacro”, esta última ejecutará de nuevo a la
primera, la cual volverá a llamar a la segunda y así, infinitamente.
Imáginate las cosas que podrías hacer a partir de este sencillo truco 🙂
¡Perfecto! Pero, ¿cómo hago para iniciar y detener mi nuevo cronómetro?
Pues, hagamos dos sub-rutinas más. La primera se llamará “iniciarReloj” y la segunda… ¡Pues sí!
Se llamará “detenerReloj” 😀
La primera sub-rutina, “iniciarReloj”, solo va a llamar por primera vez a la sub-rutina
“programarMacro”. Será como nuestro motor de arranque.
Sub iniciarReloj()
Ejecutando = True
Call programarMacro
End Sub
Nota que también he colocado el valor “True” a la variable “Ejecutando”, para que nuestra
aplicación ‘sepa’ que el cronómetro se está ejecutando.
Ahora, la segunda sub-rutina, “detenerReloj”, también será sencilla y tendrá dos líneas de código.
Sub detenerReloj()
Ejecutando = False
End Sub
Aquí también he usado la variable “Ejecutando” y le he asignado el valor “False”, para indicar que
nuestro cronómetro ya no se está ejecutando.
Como puedes ver también, he configurado nuevamente el evento “OnTime” del objeto
“Application”. El código es casi idéntico, pero con la diferencia de que en lugar de colocar “True”
en el último argumento, ahora uso el valor “False”.
Pues que ahora, esa sub-rutina ya no está en espera de ser ejecutada. Así que, si por alguna
razón le faltaba una ejecución por realizar, esta se cancela.
Este paso es útil cuando tienes períodos de tiempo más largos que un segundo como por
ejemplo, una espera de una hora, y quieres cancelar esa ejecución futura.
El código completo.
Toques finales.
Como paso final, vas a asignar las macros a un par de botones con los nombres apropiados y
pasarás directamente a probar tu flamante aplicación 😀
Ejecutar una macro periodicamente
¿Qué no recuerdas cómo asignar macros a un botón?
Pues mira, aquí te dejo un artículo en el que ya lo hicimos. Solo pincha aquí.
Pues después de tanto trabajo, solo nos falta ver el código terminado, ¿verdad? ¡Pues sí!
Entonces, aquí te dejo el enlace al archivo terminado para que pruebes en tu casa y compares
con lo que tienes, por si acaso te encuentras con algún inconveniente mientras practicas lo
aprendido.
Eso es todo.
Ahora te toca a ti. Pon en práctica lo aprendido o vas a olvidarlo muy pronto. Si no tienes en qué
usar este ejemplo… ¡pues invéntatelo! No dejes que la procrastinación se apodere de ti, o el
tiempo te va a sorprender algún día.
Si te ha gustado este artículo, no dejes de compartirlo en las redes sociales, usando los botones
de abajo. Así ayudamos a que más personas aprendan a dominar Excel, paso a paso 😀
¡Nos vemos!
[firma]
LEER MÁS »
6 comentarios
LEER MÁS »
1 comentario
Tablas Auxiliares
LEER MÁS »
1 comentario
CESAR
No se si te estoy contestando tarde, pero bueno, te va mi idea. Hay una forma de que se ejecute
una subrutina cualquiera, cada vez que se abre el libro. Lo único que deberás hacer es poner la
condición en esa subrutina.
Por ejemplo, mi subrutina del libro que estoy utilizando ahora se llama “AbrirExcel”, y se ejecuta
cada vez que se abre el libro. Abriendo el editor de VB vas a ver en el final de donde están las
hojas del libro una que se crea automáticamente llamada ThisWorkbook. En esa hoja colocas lo
siguiente:
AbrirExcel
End Sub
De esta manera, se va a ejecutar la subrutina “AbrirExcel” cada vez que se abra el libro. Luego
dentro de la misma simplemente tenes que colocar un “If” (por ejemplo) cuya condición compare
una fecha colocada en una celda con otra donde una de ellas debe tener la fecha actual. Si la
condición se cumple se ejecuta lo que vos quieras, de lo contrario nada.
Espero que te sirva, saludos!
Responder
Hola Raymundo, como lo puedo hacer para que un numero determinado vaya incrementando de
uno en uno pero cada 1 hora??? en excel, es que necesito una especie de contador de unidad
pero cada 1 hora…
Muchas gracias
Responder
RAYMUNDO YCAZA
Hola, Miguel. Pues sería de reemplazar la función que tienes en el ejemplo, por una que haga lo
que indicas. En el timevalue en lugar de poner un segundo, pondrías una hora, así: 01:00:00
function funcion_a_ejecutarse()
range(“A3”).value = range(“A3”).value + 1
end function
function funcion_a_ejecutarse()
mi_numero = mi_numero +1
end function
Saludos
Responder
Buenos dias
Responder
VICTOR RAMOS
Responder
ADRIAN
ray una pregunta use la macro para automatizar un proceso cada tanto tiempo, el problema es
🙁
que si tengo abierto otro libro el proceso bota un error
Responder
FRAN MONTERO
Mi consulta es la siguiente, yo trabajo con los dashbord en excel el cual esta conectada a una
base de datos (SQL SERVER) y estos dashbord hay que estarlos actualizando manualmente, cosa
que he querido eliminar y hacerlo automatico, ahora bien este dato que nos diste esta genial,
pero el problema que tengo, es que cada que actualizo esto manualmente, hay que ingresar el
usuario y contraseña para poder extraer los datos de sql y refrescar el archivo de excel.
Entonces como debe de ir el codigo (por asi decirlo) en la macro para meter estos datos y que
corra el scrip sin que yo intervenga…..
Responder
Tuve un problema con la Pila, al crear una sentencia como esta, ya que me marca “error 28 en
tiempo de ejecución: espacio de pila insuficiente”. Me puedes ayudar con esto?
Option Explicit
Sub ProgramarMacro()
Tiempo = Now + TimeValue(“00:00:01”)
End Sub
Sub MiMacro()
Range(“G1”).Value = Range(“G1”).Value + 1
Call ProgramarMacro
End Sub
Sub DetenerReloj()
Ejecutando = False
End Sub
Sub IniciarReloj()
Ejecutando = True
Call ProgramarMacro
End Sub
Responder
Hola esta muy bueno tu aporte, me podrías ayudar a programar un macro que ciertas celdas se
puedan escribir datos y pasados los 15 minutos se bloque las celdas y para poder actualizarlas te
pida contraseña y pinte la celda de rojo indicando que este dato se paso de los 15 minutos
Responder
KAREN AGUILAR
En mi trabajo utilizamos instrumentos que deben ser verificados cada año. Realicé una tabla con
un formulario que pide los datos del instrumento, la fecha de verificación y la frecuencia de ésta
(1 año, 2años, etc.) pero quiero que me informe dos semanas antes de que la verificación se debe
realizar y el mismo día de la verificación y que cuando ya paso la fecha se actualice para la
siguiente verificación.
Responder
RAYMUNDO YCAZA
Hola, Karen.
En esta entrada, trato de algo parecido, que utiliza fechas y puedes usarlo como referencia:
http://www.raymundoycaza.com/agenda-en-excel-1/
Para comparar en días o meses, podrias usar la función DATEDIFF, mientras que para actualizar
la fecha, sumandole dias o meses, podrias usar la función DATEADD.
Ya me contarás.
Saludos
Responder
SABRINA
Hola, necesito ayuda con una programacion como esta, pero lo quiero es una macro que cada 2
minutos cambie de sheet. es entre tres y que vaya cambiando cada 2 minutos infinitamente.
Responder
TAVINNI MTZ H
End Sub
Cada hora ejecuta la rutina especificada, pero tengo el problema que, si por ejemplo el libro lo
abro a las 12:45 hrs, comienza a ejecutar las macros desde las 13 hrs, ejecuta 23 rutinas
restantes, pero a las 13 hrs del siguiente día se detiene, ya no ejecuta nada, y tengo que cerrar y
abrir el libro.
Esto no me es funcional, ya que quiero que lo haga de manera que no se detenga. Ojalá me
puedas ayudar.
Responder
Responder
no puedes confundir miMacro que es una macro con miMacro del cronómetro que es una
subrutina. No funciona
Responder
JORGE
Estimado Raymundo, teniendo como base tu explicación intento hacer una macro pero aún no lo
consigo.
La idea es que por medio de un UserForm donde hayan 3 textboxs y un botón para ejecutar, el
usuario coloque la “hora”, “minutos” y “segundos” respectivamente en que quisiera que se vuelva
a ejecutar una macro que tengo realizada.
En tu ejemplo somos capaces de colocar el tiempo desde código, pero lo que busco es que esa
opción este disponible para un usuario.
Responder
ANDRES
Responder
CRISTIAN
Hola Raymundo, intente hace un parpadeo de celda pero que mantenga el color original de la
celda, y no sé como hacerlo, no me resulta, he intentado muchas veces, pero algo no debo estar
considerando. Agradezco tu ayuda.
Lo que finalmente quiero hacer es que la celda parpadee si es que tien un dato. Si está vacía,
para el parpadeo, pero nunca cambie el color original.
Gracias.
Responder
Enric
Responder
CLAUDIO RENGIFO
Excelente gracias
Responder
Deja un comentario
Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados
con *
Escribe aquí...
Escribe aquí...
Nombre*
Nombre*
Correo electrónico*
Correo electrónico*
Web
Web
Guardar mi nombre, correo electrónico y sitio web en este navegador para la próxima vez que
haga un comentario.
Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus
comentarios.
HOME
BLOG
VIDEOS
ACERCA DE…
CURSOS
Raymundo Ycaza
Creo que cada persona en el mundo, puede construir sus posibilidades: una mejor versión de sí
misma.
Servicios
Cursos de Excel
Consultoría informática
Accesos Directos
Sobre mí
Todos los cursos
Recursos
Blog
Contáctame
Contáctame
Guayaquil - Ecuador
Llámame 0959076237
Envíame un mensaje
Aviso Legal
Política de Privacidad
Política de Cookies