Download file with progress meter in VBA Download file with progress meter in VBA vba vba

Download file with progress meter in VBA


I have done this using the wininet.dll functions. Unfortunately I cannot paste my code as it is owned by my employer.

Use InternetOpen and InternetOpenUrl to start the download, HttpQueryInfoLong to get the content length and then repeatedly call InternetReadFile to read data into a buffer (I use a 128k buffer), writing the data to a file and updating the progress bar as you go.

Declarations to get you started:

Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" (ByVal sAgent As String, ByVal lAccessType As Long, ByVal sProxyName As String, ByVal sProxyBypass As String, ByVal lFlags As Long) As LongPrivate Declare Function HttpQueryInfo Lib "wininet.dll" Alias "HttpQueryInfoA" (ByVal hHttpRequest As Long, ByVal lInfoLevel As Long, ByRef sBuffer As Any, ByRef lBufferLength As Long, ByRef lIndex As Long) As LongPrivate Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal hInet As Long) As IntegerPrivate Declare Function InternetReadFile Lib "wininet.dll" (ByVal hFile As Long, ByRef Buffer As Any, ByVal lNumberOfBytesToRead As Long, lNumberOfBytesRead As Long) As IntegerPrivate Declare Function InternetOpenUrl Lib "wininet.dll" Alias "InternetOpenUrlA" (ByVal hInternet As Long, ByVal lpszUrl As String, ByVal lpszHeaders As String, ByVal dwHeadersLength As Long, ByVal dwFlags As Long, ByVal dwContext As Long) As LongPrivate Const INTERNET_OPEN_TYPE_PRECONFIG = 0Private Const INTERNET_FLAG_RELOAD = &H80000000Private Const INTERNET_FLAG_KEEP_CONNECTION = &H400000 ' use keep-alive semantics - required for NTLM proxy authenticationPrivate Const HTTP_QUERY_CONTENT_LENGTH = 5Private Const HTTP_QUERY_FLAG_NUMBER = &H20000000

If you need any clarification, post a comment.


You want a progress bar in VBA, wouldn't one of these approaches work?

Progress bar in VBA Excel

Seems a lot simpler than doing it as you describe, or am I not understanding?

OK, try this. Get the headers from the URL and parse them for Content-Length. Then you can set your progress bar accordingly.

Function GetFileSize(URL As String) As LongDim xml As Object ' MSXML2.XMLHTTP60Dim result As StringSet xml = CreateObject("MSXML2.XMLHTTP.6.0")With xml  ' get headers only  .Open "HEAD", URL, False  .sendEnd Withresult = xml.getResponseHeader("Content-Length")GetFileSize = CLng(result)End Function

Now just call the function with the URL of the file you want to download. It should give you the number of bytes of the file.