Return to VBA Code Examples
In this Article
- Use of Application.Wait Method
- Wait 1 Second
- Wait Until
- Use of Sleep Method
- Using a Loop with Do Events
This tutorial will demonstrate how to pause / delay code using the Wait and Sleep functions in VBA.
When we create large VBA programs that perform a lot of calculations, or perhaps even call external program to run, we may require our VBA code to stop running for a specific length of time while the external process is taking place. VBA has a few methods available in order to achieve this.
Use of Application.Wait Method
If we need to pause our macro’s running for some time or until a specified time has been reached before executing the next step, we can use the Application.Wait method. This could be useful, for example, if we have automated a login process to a website and need to wait some seconds until the page is loaded before our macro continues running.
Wait 1 Second
Including this line below into your macro, its running will be paused for approximately 1 second:
Application.Wait (Now + TimeValue("0:00:01"))
Wait Until
In some cases you will need to wait until a specific time. With this line below your macro will not proceed before 9am:
Application.Wait "09:00:00"
Please note that the Application.Wait does not accept delays of less than 1 second.
Use of Sleep Method
If you need a more precise way of pausing your macro, you can use the Sleep method.
Sleep is a Windows API function, that is, it is not part of VBA. It can be accessed by using a special declaration statement.
If you are using the 64-bit version of Microsoft Office, you can insert the following statement into a new module or at the beginning of the module (not directly in the subroutine) you want to use the Sleep function in:
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal Milliseconds As LongPtr)
With 32-bit version use this line:
Public Declare Sub Sleep Lib "kernel32" (ByVal Milliseconds As LongPtr)
After declaring the Sleep function, you have access to it in you subroutines like this:
Sleep 10000
With this line above your macro will be paused for 10,000 milliseconds, i.e., 10 seconds.
Using a Loop with Do Events
The big disadvantage of using the Wait and Sleep methods is that the user cannot do anything in Excel while waiting for the macro to continue. A user could think that Excel has stopped responding and while the user can then use Ctl+Break to interrupt the macro, this defeats the purpose of putting a pause in the macro to begin with.
To overcome this problem, we can use a loop with a method called DoEvents.
Public Sub Test()
Dim i As Long
For i = 1 To 20000
Range(“A1”).Value = i
DoEvents
Next i
End Sub
Now, while Excel is running the macro above, the user can continue to interact with Excel – we can change tabs or format cells for example – basically, the macro is continuing to run but the Excel screen is not frozen. We could use a similar loop to create a timer function in Excel and incorporate the DoEvents method in that to unfreeze the screen while the timer is running.
VBA Coding Made Easy
Stop searching for VBA code online. Learn more about AutoMacro — A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!
Learn More!
Wait and Sleep functionality in programs is required to hold or pause the program execution for a specified time. These methods suspend all the activities of Microsoft Excel and sometimes may also prevent you from performing other operations on it until the pause is in effect.
However, your computer can simultaneously process other background tasks like printing or thread ordering.
Significance of Wait and Sleep Functions in VBA:
These functions can be quite useful when you need to hold the program to wait for some other process or task (not directly connected or communicable to the VBA engine) that is yet to be completed.
In such cases, you can find out the maximum time required for completing such a task, and then in your code, you hold the execution for that amount of time.
For example, We have a VBA code that can run some other executable (.exe) and after running that executable you need to wait for that executable to complete and then continue the code. So, in such a case we know that VBA cannot directly communicate with the executable file.
Hence we can code in such a way that first, we start that executable then let the code wait for 10 seconds (max time required for this executable to run), and then continue the execution again.
VBA Wait Function in Excel:
The WAIT is a VBA function only available in Excel. Its syntax is as follows:
Here ‘Time’ specifies the time at which you want the macro to resume again. ‘Time’ should always be in Microsoft excel time format.
Let’s see some examples of Wait Function in VBA:
Example 1: Pausing a code till 2.00 PM today.
Sub WaitTest()
MsgBox ("This application is started!")
Application.Wait "14:00:00"
MsgBox ("Excecution resumed after 2PM")
End Sub
Example 2: Pausing an application for 10 seconds.
Sub WaitTest()
MsgBox ("This application is started!")
Application.Wait (Now + TimeValue("0:00:10"))
MsgBox ("Excecution resumed after 10 Seconds")
End Sub
Example 3: Using the VBA Wait function to create a program that tells time after every minute (till 10 loops).
Public Sub TalkingTime()
For i = 0 To 10
Application.Wait (Now + TimeValue("0:01:00"))
Application.Speech.Speak ("The Time is" & Time)
Next i
End Sub
Now let’s move to Sleep Function.
Sleep Function:
Sleep is a windows function and not a VBA Function, but you can still use this function in VBA code by calling the windows Sleep API. Actually sleep is a function present inside Windows DLL files. So, before using them you have to declare the name of API above the code in your module.
The syntax of the Sleep statement is as follows:
Here, ‘delay’ specifies the time in milliseconds till which you have to pause the execution.
Let’s see some examples of Sleep Function in VBA:
Example 1: Pausing an application for 10 seconds
#If VBA7 Then
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) 'For 64 Bit Systems
#Else
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds as Long) 'For 32 Bit Systems
#End If
Sub SleepTest()
MsgBox "Execution is started"
Sleep 10000 'delay in milliseconds
MsgBox "Execution Resumed"
End Sub
Example 2: Halting the code for a user-defined delay by using an InputBox function.
Sub SleepTest()
On Error GoTo InvalidRes
Dim i As Integer
i = InputBox("Enter the Seconds for which you need to pause the code :")
Sleep i * 1000 'delay in milliseconds
MsgBox ("Code halted for " & i & " seconds.")
Exit Sub
InvalidRes:
MsgBox "Invalid value"
End Sub
Difference between VBA Wait and Sleep Function:
The job of both of these functions is the same but the sleep function is not as accurate as Wait. Sleep statement depends on the processor’s ticks to calculate the time delays which may vary slightly on different machines. But this is not the case with Wait Function.
The advantage of the Sleep statement over Wait is that it is quite flexible as you can give the time delays in milliseconds. While in the Wait function you can only delay the application by whole seconds.
So, this was all about VBA Wait and Sleep Functions. Do let us know in case you have any queries related to the topic.
Home / VBA / VBA Wait and Sleep Commands to Pause and Delay
VBA Wait Command
In VBA, the WAIT command (method) helps you to put a wait on all the activities that you do in Excel for a particular time or up to a specific time. In simple words, you can make VBA wait for a few seconds, minutes, or even hours, or up to fix time. It has one argument that needs you to specify.
Steps to use VBA Wait
- First, use the keyword “Application” and type a dot (.) to get the list of properties and methods.
- After that, select or type the “Wait” method.
- Now, specify the “Time” argument to tell VBA that how much time you want to wait.
- In the end, run the code to put wait for all the activities in Excel.
In this code, you have used the NOW and TIMEVALUE (VBA Functions) to tell VBA to wait for ten seconds starting from the moment you run the code. So once the ten seconds passed the IF statement will test the condition and run showing you a message box with the message “Wait Over”.
Sub vba_wait_example()
If Application.Wait(Now + TimeValue("00:00:10")) = True Then
MsgBox "Wait Over"
End If
End Sub
You can also use the Wait method to let Excel wait for all the activities up to a specific time. The following code waits until 01:00 PM. So, as it’s 12:52 in my system right now this code of line will make it wait for the next 8 minutes.
Application.Wait "13:00:00"
Note: With the wait method, you can only make wait a second not less than that.
Sleep is a windows function (under windows DLL files; you need to import this function using a code statement) that can help you pause or add a delay while running a macro. In this function, you can specify the time in milliseconds, but you can’t stop the sleep function once it’s put everything on pause.
Use Sleep Function in VBA
- First, you need to use the code statement to import the sleep function from the “kernel32 library”.
- And then you need to make sure to append the “PtrSafe” statement if you are using 64 Bit Excel.
- Next, you need to call the sleep function in the code.
- In the end, specify the time (milliseconds) for which you want to delay the code.
If VBA7 Then
'For 64-Bit versions of Excel
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
Else
'For 32-Bit versions of Excel
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
End If
Sub vba_sleep()
Sleep (10000)
'add code here
MsgBox "Finished"
End Sub
In the above code, you have 10000 milliseconds, which equals 10 seconds. When you run this code, it will delay the code for 10 seconds and then show a message box.
Note: When you use the sleep function, it stops everything in Excel for the time you have defined, you can’t even break it. Make sure to check out this link from Microsoft on Compatibility Between the 32-bit and 64-bit Versions
There’s More
VBA With Statement | VBA Status Bar | VBA ScreenUpdating | VBA Random Number | Line Break in a VBA Code | VBA Immediate Window (Debug.Print) | VBA Concatenate | VBA Module | VBA Random Number
Complete Guide to Pausing VBA Execution
Background Information and Explanation
All Microsoft Office applications run VBA code in the same thread as the main user interface. This means, as long as the VBA code doesn’t call DoEvents
, code execution freezes the entire application (It will show as «not responding» in Task-Manager!). This includes calls to the Sleep
API function. Once Sleep
is called, there is no way of recovering from this state without waiting for the time to pass or force quitting the Application and restarting it.
The Excel-specific Application.Wait
also suffers from this issue, except that the app will not show as not responding
in Task Manager in this case. It will still be just as unresponsive to the user.
A way to circumvent this problem is calling DoEvents
in a loop, as other people have already pointed out. However, this comes with another issue. Because the application will try to execute VBA code as fast as possible, DoEvents is called at the maximum achievable rate essentially saturating the CPU completely on that single thread, leading to high, unnecessary CPU and power usage and potentially slowing down other more important tasks in the UI.
This is why the best way of getting VBA to pause execution is a combination of both methods, using DoEvents
to stay responsive and Sleep
to avoid maximum CPU usage. An implementation of this is presented in the following.
Universal Solution
The following code implements a WaitSeconds
Sub
that will pause execution for a given amount of seconds while avoiding all of the above-mentioned issues.
It can be used like this:
Sub UsageExample()
WaitSeconds 3.5
End Sub
This will pause the macro for 3.5 seconds, without freezing the application or causing excessive CPU usage. For this to work, just copy the following code to the top of any standard code module.
#If Mac Then
#If VBA7 Then
Private Declare PtrSafe Sub USleep Lib "/usr/lib/libc.dylib" Alias "usleep" (ByVal dwMicroseconds As Long)
#Else
Private Declare Sub USleep Lib "/usr/lib/libc.dylib" Alias "usleep" (ByVal dwMicroseconds As Long)
#End If
#Else
#If VBA7 Then
Private Declare PtrSafe Sub MSleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)
#Else
Private Declare Sub MSleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)
#End If
#End If
'Sub providing a Sleep API consistent with Windows on Mac (argument in ms)
'Authors: Guido Witt-Dörring, https://stackoverflow.com/a/74262120/12287457
' Cristian Buse, https://stackoverflow.com/a/71176040/12287457
Public Sub Sleep(ByVal dwMilliseconds As Long)
#If Mac Then 'To avoid overflow issues for inputs > &HFFFFFFFF / 1000:
Do While dwMilliseconds And &H80000000
USleep &HFFFFFED8
If dwMilliseconds < (&H418937 Or &H80000000) Then
dwMilliseconds = &H7FBE76C9 + (dwMilliseconds - &H80000000)
Else: dwMilliseconds = dwMilliseconds - &H418937: End If
Loop
Do While dwMilliseconds > &H418937
USleep &HFFFFFED8: dwMilliseconds = dwMilliseconds - &H418937
Loop
If dwMilliseconds > &H20C49B Then
USleep (dwMilliseconds * 500& Or &H80000000) * 2&
Else: USleep dwMilliseconds * 1000&: End If
#Else
MSleep dwMilliseconds
#End If
End Sub
'Sub pausing code execution without freezing the app or causing high CPU usage
'Author: Guido Witt-Dörring, https://stackoverflow.com/a/74387976/12287457
Public Sub WaitSeconds(ByVal seconds As Single)
Dim currTime As Single: currTime = Timer()
Dim endTime As Single: endTime = currTime + seconds
Dim cacheTime As Single: cacheTime = currTime
Do While currTime < endTime
Sleep 15: DoEvents: currTime = Timer() 'Timer function resets at 00:00!
If currTime < cacheTime Then endTime = endTime - 86400! '<- sec per day
cacheTime = currTime
Loop
End Sub
[1] More information on the cross-platform Sleep
included in the above code can be found here and here.
If application freezing is not an issue, e.g. for very short delays or if user interaction is undesired, the best solution is to call Sleep
directly. This is why, in the above solution, it is also declared as Public
. Note that Sleep
takes its argument as milliseconds.
'Does freeze application
Sub UsageExample()
Sleep 3.5 * 1000
End Sub
Important Notes:
-
The time precision of the
Timer()
function used in this solution is better on Windows, however, the claim in the documentation, that resolution on Mac is one second, is wrong. Even on Mac, the resolution is better than 0.1 seconds. Still, you shouldn’t expect a resolution much better than ~0.1
seconds from this solution!WaitSeconds 1
will wait around1.015 ± 0.02
seconds on Windows. -
If you plan on using this to pause your code for long periods of time, or even in a case like OP is dealing with, you are most likely not using the correct tool for the job. If you are using Excel, consider looking into
Application.OnTime
. (See the following section)
Alternatives to Pausing VBA Execution and Better Solution for OP
The question op has asked does not lead to the best solution for his problem. It’s an XY-Problem.
It is not actually necessary to have VBA code running non-stop in the background in order to recalculate a Workbook every second. This is a typical example of a task that can also be achieved with Application.OnTime
.
A detailed guide including a copy-paste solution to recalculate any Range
at any desired time interval ≥ 1s
is available here.
The big advantage of using Application.OnTime
for this is that it avoids a continuously running macro and hence allows the use of other macros or other features that are unavailable while macros are running.
Meta-Analysis of All Other Solutions in This Thread
The reason I even wrote this answer is that all other solutions presented in this thread (at the time this post was written) have at least one of the following two severe drawbacks:
- They freeze the calling application completely, causing it to no longer respond to user input, or
- They cause excessive CPU usage (100% on the calling application’s thread) by calling
DoEvents
in a loop.
Additionally, many of the proposed solutions have other issues:
-
Some only work on Windows
-
Some only work in Excel
-
Some have an intrinsic imprecision of more than one second
-
Some have other problems or even bugs
The following table will give a short overview of all the solutions in this thread and their features
Legend
Column | ✅ (Good) | ❌ (Bad) |
---|---|---|
App Responds | App stays responsive and usable | Freezes calling app completely |
CPU Usage | Practically no CPU usage | 100% CPU usage in the single executing thread |
Cross-App | Works outside Excel | Works only in Excel |
Win/Mac | Works on both, Windows and Mac | Only works on Windows |
Precise | Time precision < 0.1 seconds | Time precision > 0.1 seconds (usually about 1 second) |
Other Issues | No other issues | Has some other issues described in the table below |
Overview
Other issues
Solution by | Other issues |
---|---|
cyberpunk | This solution will sleep indefinitely if at the time of calling Timer() + vSeconds > 172800 (vSevonds is the input value). In practice, this shouldn’t be a big problem because Timer() is always ≤ 86400 so the input value needs to be bigger than 86400 which is one day. Such functions usually shouldn’t be called for such long times anyways. |
Reverus | This solution doesn’t allow pausing for a specific amount of time at all! You just specify how often you want to call DoEvents before continuing. How long this is, depends on the speed of your system. On my PC, calling the function with the maximum value a Long can take (2147483647) (so the maximum time the function can pause) will pause for about 1434 seconds or about 24 minutes. Obviously, this is a terrible «solution». |
Brian Burns | This solution will sleep indefinitely if at the time of calling Timer() + sngSecs > 86400 (sngSecs is the input value). Because Timer() can return values up to 86400, calling this function right before midnight can cause this bug even with very small input values. This is a severe bug and should be considered! |
g t | This solution does not wait at all. If you consider its generalization, Application.Wait Second(Now) + dblInput , it will not wait at all for input values smaller than CDbl(Now) - 60# / 86400# , which is 44815 at the time of writing this, and for input values larger than that, it will wait for dblInput - CDbl(Now) - Second(Now) / 86400# days. While input values can be constructed that will make this wait for a reasonable amount of time, this is very difficult. A terrible «solution». |
ITI | The comment describes this function as being able to cause delays of up to 99 seconds. This is wrong because input values where T Mod 100 > 60 (T is the input parameter) will cause an error and hence stop execution indefinitely if the error is not handled by the calling code. You can confirm this by calling the function like this: Delay 61 |
dave | This solution will work correctly but additionally sets Application.EnableEvents = True for no reason at all. If the calling code set this property to False and reasonably doesn’t expect a function that has nothing to do with this to set it to True , this can lead to severe bugs in the calling code. If that line is deleted, the solution is fine. |
You may want some way of pausing or delaying VBA code execution and you can do this with two functions called Wait and Sleep. You can also do this using a loop, and we will look at that approach too, but first we’ll look at the functions available to Excel.
Why would you pause the code? Maybe you need to wait for another task to finish, for instance if you made a call to a Windows API/shell function. Or you may want to wait for the user to update data in the sheet, or you just want to run a macro at a set time.
Download the Workbook With Sample VBA Code
The queries in this Excel file can be copied/pasted into the Power BI Desktop Advanced Editor and will work there too.
Enter your email address below to download the workbook with the data and code from this post.
By submitting your email address you agree that we can email you our Excel newsletter.
Application.Wait
The .Wait method is available within Excel as a VBA function, as opposed to Sleep (see below). You can use it to specify that a macro is paused for a specific period of time.
This example makes the macro pause for approximately 10 seconds:
Application.Wait (Now + TimeValue("0:00:10"))
Or you can pause execution until a specific time e.g. this will pause a macro until 11am:
Application.Wait "11:00:00"
Wait does not accept delays of less than 1 second.
Sleep is a Windows API function, that is, it is not part of VBA it is part of the Windows operating system. But we can access it by using a special declaration statement in our VBA.
This declaration statement serves two purposes. Firstly, it tells Excel where to find the function, secondly it allows us to use the 32bit version of the function in 32bit Excel, and the 64bit version of the function in 64bit Excel.
The Declare statement looks like this
#If VBA7 Then ' Excel 2010 or later Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal Milliseconds As LongPtr) #Else ' Excel 2007 or earlier Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal Milliseconds As Long) #End If
Note : I’ve tested this code in Excel 2010 and 2013 only.
You can read more about these type of Declare statements and 32bit/64bit Office on Microsoft’s MSDN site
Sleep allows us to pause a macro for X milliseconds, which is a better resolution than Wait which has a minimum delay of 1 second. So to pause a macro for 5 seconds using Sleep we write this
Sleep 5000
Loops
The big drawback of using Wait or Sleep, is that Excel locks you out until the wait/sleep period has finished. You can use CTRL+BREAK to interrupt the macro, but Excel won’t accept input from the keyboard or mouse whilst paused using Wait or Sleep.
Events are suspended and anything you have scheduled using Application.OnTime is also delayed until the pause has finished. If you didn’t know what was happening, it looks like Excel has hung whilst Sleep or Wait are in effect. Background processes like printing and recalculation do carry on though.
To overcome this drawback you can use a loop to pause VBA execution, and also allow other things to happen whilst waiting. Macro execution isn’t actually paused, it’s just not doing anything other than running some loop commands.
A loop has an added advantage as Mac users can use them, whereas Wait and Sleep are not available on a Mac.
A simple loop would look something like this
Sub WasteTime(Finish As Long) Dim NowTick As Long Dim EndTick As Long EndTick = GetTickCount + (Finish * 1000) Do NowTick = GetTickCount DoEvents Loop Until NowTick >= EndTick End Sub
We write a sub called WasteTime, which when called from another sub or function has a value passed into it which is the number of seconds that we want it to do nothing, like so:
WasteTime(10)
The key here is the DoEvents method. DoEvents tells Excel to check if there is anything else the system wants to do like accept input from the keyboard or mouse. In this example, my macro is executing but allows the user to type into the worksheet. After approximately 10 seconds a message is then displayed.
The GetTickCount function is another Windows API function that we access by using another Declare statement. It returns the number of milliseconds since the computer started up.
The parameter, Finish that we pass into the WasteTime sub, is the number of seconds we want to delay code execution. To convert this to milliseconds, we multiply Finish by 1000.
Timer Resolution
In my examples I have used the word approximately when describing the delays I’m trying to achieve. I say approximately because the actual duration of the pause in the execution of the code depends on the resolution of the timer on your computer.
I could give you a very complicated description why this is so, or you could Google it, but let’s just say, if you want to delay something by 10s, then you will delay it for around 10s. It’ll only be out by a few milliseconds, which is perfectly fine for the type of things I am doing. I just wouldn’t use it to time Usain Bolt.
Disclaimer – Please test the code yourself, it may not work in your environment. All code provided as is without any warranty