VBA
Excel
asynchronous downloads
file download automation
Excel programming

Asynchronous File Downloads from Within VBA Excel

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

VBA is fundamentally single-threaded, but you can still perform non-blocking HTTP downloads by using COM objects that support asynchronous requests and event callbacks. The important distinction is that Excel itself is not becoming multi-threaded; instead, the HTTP component performs work in the background and notifies VBA when progress changes.

The Basic Approach

For asynchronous downloads in Excel VBA, a practical pattern is:

  • create a class module with WithEvents
  • use MSXML2.XMLHTTP60 in async mode
  • handle the onreadystatechange event
  • save the responseBody when the request completes

This gives you a responsive workbook while the request is in flight. Users can still interact with Excel, though you should avoid starting dozens of downloads at once unless you also manage state carefully.

Class Module Example

Create a class module named CDownloadJob and paste this code into it:

vb
1Option Explicit
2
3Public WithEvents Http As MSXML2.XMLHTTP60
4Private mTargetPath As String
5
6Public Sub Start(ByVal url As String, ByVal targetPath As String)
7    mTargetPath = targetPath
8    Set Http = New MSXML2.XMLHTTP60
9    Http.Open "GET", url, True
10    Http.send
11End Sub
12
13Private Sub Http_onreadystatechange()
14    If Http.readyState <> 4 Then
15        Exit Sub
16    End If
17
18    If Http.Status = 200 Then
19        Dim stream As Object
20        Set stream = CreateObject("ADODB.Stream")
21
22        stream.Type = 1
23        stream.Open
24        stream.Write Http.responseBody
25        stream.SaveToFile mTargetPath, 2
26        stream.Close
27
28        MsgBox "Download finished: " & mTargetPath
29    Else
30        MsgBox "Download failed. HTTP status: " & Http.Status
31    End If
32End Sub

The key detail is the third argument to Open. Passing True requests asynchronous behavior.

Standard Module Code

Now add a standard module so Excel can create and retain the download object. Keeping a reference is important because the class must stay alive long enough to receive the callback.

vb
1Option Explicit
2
3Public ActiveDownload As CDownloadJob
4
5Public Sub StartDownload()
6    Dim url As String
7    Dim targetPath As String
8
9    url = "https://example.com/report.csv"
10    targetPath = Environ$("TEMP") & "\report.csv"
11
12    Set ActiveDownload = New CDownloadJob
13    ActiveDownload.Start url, targetPath
14
15    MsgBox "Download started in the background."
16End Sub

Run StartDownload from the macro dialog or attach it to a button in the sheet.

What Makes This Asynchronous

The macro that starts the request returns almost immediately. The HTTP request continues after control goes back to Excel. When the component changes state, the event handler runs. That is why this technique feels asynchronous to the user even though VBA itself is not using await or threads in the modern sense.

This also means your workbook must remain open and the object reference must remain valid. If the class instance goes out of scope, the events will stop and the download callback will never arrive.

Handling Multiple Downloads

If you need several downloads, store several CDownloadJob objects in a collection instead of a single module-level variable. Remove each job from the collection when it completes. That prevents it from being garbage collected too early while avoiding leaked references after the request is done.

You may also want to report progress in cells or a status form instead of showing MsgBox dialogs. The event-based model supports that cleanly once the basic download flow is working.

Why Synchronous Code Feels Worse in Excel

A synchronous download blocks the Excel UI until the request finishes. During a slow network call, the workbook can appear frozen, formulas do not recalculate visibly, and users may think the application crashed.

That is why async download patterns are valuable in VBA even if the language itself is older. The network wait is usually the expensive part, and handing that wait to a COM component makes the workbook much more usable.

Common Pitfalls

The most common mistake is letting the download object go out of scope. If you create it inside a procedure and do not store it anywhere, the event handler may never run.

Another issue is forgetting required references. MSXML2.XMLHTTP60 needs the Microsoft XML library available on the machine, and writing binary data cleanly is easiest with ADODB.Stream.

Developers also assume asynchronous means parallel-safe. It does not. Event callbacks can still modify workbook state at awkward times, so shared state should be updated carefully.

Finally, do not ignore HTTP status codes. A request that finishes with 404 or 500 still reaches ready state 4, but it did not succeed. Always inspect Status before saving the response.

Summary

  • VBA can support non-blocking downloads by using asynchronous COM HTTP objects with events.
  • 'MSXML2.XMLHTTP60 plus a WithEvents class is a practical pattern for Excel automation.'
  • Keep the download object alive or the completion callback will never fire.
  • Use ADODB.Stream to save binary response data safely to disk.
  • Treat ready state 4 as “request finished,” not automatically as “download succeeded.”

Course illustration
Course illustration

All Rights Reserved.