TL;DR —
Sleepno forma parte de VBA. Es una función de la API de Windows que pausa tu macro un número de milisegundos, y tienes que declararla antes de poder llamarla. En Excel de 64 bits esa declaración debe llevar el atributoPtrSafe, envuelta en una guarda#If VBA7para que siga compilando en todas partes:
#If VBA7 Then
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Sub PauseQuarterSecond()
Sleep 250 ' 250 milisegundos = un cuarto de segundo
End Sub
La gente echa mano de Sleep cuando Application.Wait no basta — cuando necesita pausar una fracción de
segundo, no uno entero. Y lo primerísimo que ocurre es un error de compilación, porque Sleep no es en
absoluto un comando de VBA: vive en Windows. Esta guía se construye sobre una sola idea — Sleep es una
pausa de milisegundos que tomas prestada del sistema operativo — porque explica la declaración, la
trampa de los 64 bits, y por qué Sleep sigue sin poder darte una pausa receptiva.
Lo que aprenderás
- El modelo mental —
Sleepes una funciónkernel32de Windows que tomas prestada, no una palabra clave de VBA - La trampa
PtrSafede 64 bits — el error de compilación exacto y el arreglo exacto con#If VBA7 - Milisegundos, no segundos — la precisión por debajo del segundo que es toda la razón para usar
Sleep - Por qué «milisegundos» no es «preciso» — el suelo de ~15 ms del planificador del sistema operativo
- Por qué
Sleepsigue congelando Excel, y cuándo usar Wait o un bucle DoEvents en su lugar
El modelo mental: una pausa que tomas prestada de Windows
Application.Wait es la herramienta propia de Excel. Sleep no lo es — pertenece a Windows, en una
biblioteca del sistema llamada kernel32. Para usarla, sales fuera de VBA con una instrucción Declare
que dice, en esencia: «hay una función llamada Sleep allá en kernel32; esta es su forma; déjame
llamarla». Solo entonces puedes escribir Sleep 250.
Ese «tomarlo prestado de Windows» es el modelo mental, y todo lo incómodo de Sleep se deriva de ahí.
Una palabra clave nativa de VBA simplemente funcionaría. Una función de API prestada hay que declararla,
tiene que coincidir con la convención de llamada del sistema operativo y — esto es lo crucial — hay que
declararla de forma distinta en Windows de 32 y de 64 bits. Ese último punto es donde casi todo el mundo
se atasca.
La trampa PtrSafe de 64 bits: el error y el arreglo
Este es el problema número uno de Sleep, y es la razón por la que una macro que «funcionaba en el
ordenador viejo» de repente se niega a arrancar. La declaración clásica que encontrarás en código viejo y
en posts de foros antiguos es:
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) ' estilo anterior a 2010
Ejecútala en un Excel de 64 bits moderno y, antes de que se ejecute una sola línea, VBA se detiene con:
Compile error: The code in this project must be updated for use on 64-bit systems. Please review and update Declare statements and then mark them with the PtrSafe attribute.
El arreglo tiene dos partes. Primero, añade la palabra clave PtrSafe, que le dice a VBA que la
declaración se ha revisado para la seguridad de punteros de 64 bits. Segundo, envuélvela en un bloque de
compilación condicional #If VBA7 para que el mismo archivo siga compilando en versiones antiquísimas
de Excel anteriores a PtrSafe:
#If VBA7 Then
' Excel 2010 y posteriores - seguro en 64 bits
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
' Excel 2007 y anteriores - no existe la palabra clave PtrSafe
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
#If VBA7 se comprueba en tiempo de compilación, no de ejecución, así que cada versión de Excel solo
ve la única declaración que entiende. Pon este bloque al principio de un módulo estándar, por encima de
cualquier procedimiento, y Sleep compila y corre en todo Excel moderno. Si solo vas a apuntar a Excel
365 de 64 bits, basta con la línea PtrSafe sola — pero la versión protegida es el copiar-y-pegar seguro.
Milisegundos, no segundos — la razón de ser de Sleep
Sleep toma milisegundos. Sleep 250 es un cuarto de segundo; Sleep 1000 es un segundo; Sleep 50
es una cincuentava parte. Esta es toda la razón para preferir Sleep sobre
Application.Wait, que solo puede pausar en segundos enteros. Si necesitas moderar un
bucle a unas pocas veces por segundo, espaciar peticiones de API o esperar un instante corto a que algo se
asiente, Sleep es la herramienta con la resolución adecuada.
Do
' ... comprueba si el archivo de exportacion ha aparecido ...
If Dir(exportPath) <> "" Then Exit Do
Sleep 200 ' sondea cinco veces por segundo en vez de machacar el disco
Loop
Pero «milisegundos» no es «preciso»
No confundas unidades finas con precisión fina. Windows planifica los hilos en un tick de aproximadamente
15,6 milisegundos, así que Sleep 1 no duerme un milisegundo — duerme hasta el siguiente tick del
planificador, normalmente unos 15 ms. Sleep garantiza «al menos este tiempo», nunca «exactamente este
tiempo», y la pausa real se redondea hacia arriba a la granularidad del planificador. Eso está bien para
moderar y marcar el ritmo, donde solo quieres «más o menos con esta frecuencia». Es la herramienta
equivocada si necesitas temporización precisa o medición exacta — para medir el tiempo transcurrido, usa
Timer; para temporización de alta precisión bajarías a QueryPerformanceCounter.
Sleep sigue congelando Excel
Aquí está la trampa que Sleep comparte con Application.Wait: mientras pausa, Excel está congelado.
Sleep aparca el único hilo de Excel durante todo ese tiempo y no procesa la cola de mensajes, así que la
pantalla no se repinta, los clics no se atienden, y un Sleep lo bastante largo — o muchos cortos en un
bucle — hace que la ventana pase a «No responde». La precisión por debajo del segundo no cambia esto;
una pausa es una pausa, y un hilo bloqueado es un Excel congelado.
Así que Sleep, igual que Wait, es la herramienta equivocada cuando el objetivo de la pausa es
dejar que el usuario vea algo o haga algo. Una pausa en la que Excel sigue vivo es un bucle que cede con
DoEvents:
' Ritmo receptivo por debajo del segundo - Excel sigue vivo entre pulsos
Dim nextBeat As Double
nextBeat = Timer + 0.25
Do While Timer < nextBeat
DoEvents
Loop
El veredicto honesto: Wait, Sleep o un bucle DoEvents
Alinea las tres según lo que de verdad necesitas:
- Una pausa de segundos enteros, sin líos —
Application.Wait Now + TimeValue(...). SinDeclare, sinPtrSafe, nada que se pueda equivocar. Echa mano de esto primero para «espera ~2 segundos». - Una pausa por debajo del segundo —
Sleep, porqueApplication.Waitno puede bajar de un segundo. Acepta la ceremonia deDeclare/PtrSafecomo el precio de la resolución de milisegundos. - Una pausa en la que Excel debe seguir receptivo — un bucle
DoEvents, porque tantoWaitcomoSleepcongelan la ventana. Esta es la que la gente más a menudo necesita y menos a menudo elige.
El reto: no añadas un Sleep «por si acaso» para ralentizar una macro. Si una macro se porta mal sin una
pausa artificial, la pausa casi siempre esconde un bug real — un valor leído antes de estar listo, un
evento que se disparó dos veces — y el arreglo honesto ataca eso, no un Sleep 500 espolvoreado por
encima.
Cómo ayuda ExcelMaster
La declaración de Sleep es justo el tipo de código repetitivo que es fácil de equivocar y tedioso de
acertar: la cadena Lib "kernel32", el argumento ByVal, el atributo PtrSafe, la guarda #If VBA7, y
luego la decisión de criterio de si Sleep es siquiera la herramienta que querías en vez de
Application.Wait o un bucle DoEvents.
ExcelMaster escribe por ti la
declaración correcta y segura en 64 bits y, más importante aún, elige la construcción de espera adecuada
para lo que describiste. Pídele «sondea un archivo cada 200 ms» y te da un bucle Sleep protegido; pídele
«pausa pero déjame cancelar» y te da un bucle DoEvents en su lugar — así nunca publicas el Declare
anterior a 2010 que revienta en Excel de 64 bits, ni congelas Excel cuando querías mantenerlo vivo.
Preguntas frecuentes
¿Cómo uso Sleep en Excel VBA?
Decláralo una vez al principio de un módulo estándar y luego llámalo con un valor en milisegundos. Usa la
forma segura en 64 bits: #If VBA7 Then Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) (con un Declare normal en la rama #Else para Excel viejo). Entonces
Sleep 250 pausa la macro 250 milisegundos — un cuarto de segundo.
¿Por qué mi Declare de Sleep provoca un error de compilación en Excel de 64 bits?
Porque el viejo estilo de declaración es anterior a Office de 64 bits. El Excel de 64 bits moderno exige
el atributo PtrSafe en cada instrucción Declare, y sin él obtienes «The code in this project must be
updated for use on 64-bit systems… mark them with the PtrSafe attribute». Añade PtrSafe después de
Declare, y envuelve la línea en un bloque #If VBA7 para que también siga compilando en Excel más
antiguo.
¿Cuál es la diferencia entre Sleep y Application.Wait?
Sleep es una llamada a la API de Windows que debes declarar; pausa un número de milisegundos y da
precisión por debajo del segundo. Application.Wait viene integrado en Excel, no necesita declaración, y
pausa hasta un momento del reloj con resolución de segundos enteros. Usa Sleep cuando necesites algo
más fino que un segundo, y Application.Wait para pausas simples de segundos enteros. Ambos congelan Excel
mientras esperan.
¿Sleep deja Excel sin responder?
Sí. Sleep bloquea el único hilo de Excel durante toda la pausa y no procesa mensajes, así que la ventana
no puede repintarse ni atender clics y puede mostrar «No responde». Si necesitas que Excel siga receptivo
durante una pausa — para mostrar progreso o un botón de Cancelar — usa un bucle que llame a DoEvents en
vez de Sleep.
¿Es Sleep preciso al milisegundo?
No. Windows planifica los hilos en un tick de unos 15,6 ms, así que Sleep 1 en realidad pausa unos 15 ms,
y Sleep solo garantiza «al menos este tiempo». Está bien para moderar y marcar el ritmo, pero no para
temporización precisa. Para medir cuánto tarda un código, usa en su lugar la función Timer.
Probado en
Probado en: Excel 365 (Windows 11, 64 bits), VBA 7.1 — última verificación el 19/08/2026.
Guías relacionadas: VBA Wait · VBA Timer · VBA DoEvents · VBA On Error · VBA ScreenUpdating
