2011-07-04 32 views
10

He encontrado numerosos ejemplos para hacer esto en varios idiomas, pero ninguno que sea específico de VBA. Esta pregunta, How to download multiple files in VB6 with progress bar?, aborda tres enfoques diferentes para hacer esto en VB6.Descargar el archivo con el medidor de progreso en VBA

  1. Utilice la propiedad AsyncRead del control de usuario VB6/UserDocument objetos
  2. Uso tipo OLELIB.TLB biblioteca y la interfaz IBindStatusCallback
  3. Uso wininet.dll para escribir su propia función de descarga para presentar

Ninguno de estos enfoques funciona para mí porque:

  1. Los objetos UserControl/UserDocument no son disponible de VBA
  2. que preferiría no tener que mantener y distribuir una gran dependencia externa
  3. no vi una forma obvia de conseguir el progreso de descarga de archivos actual

número 2 anterior parecía el más prometedor . Me pregunto si puedo crear una interfaz IBindStatusCallback utilizando un módulo de clase desde mi proyecto de VBA.

O tal vez hay propiedades/métodos disponibles utilizando el número 3 anterior que proporcionaría el progreso actual. Cualquier ayuda es muy apreciada.

Respuesta

2

He hecho esto usando las funciones wininet.dll. Desafortunadamente no puedo pegar mi código ya que es propiedad de mi empleador.

Use InternetOpen e InternetOpenUrl para iniciar la descarga, HttpQueryInfoLong para obtener la longitud del contenido y luego llame repetidamente a InternetReadFile para leer datos en un búfer (uso un búfer de 128k), escribir los datos en un archivo y actualizar la barra de progreso como anda tu.

Declaraciones a empezar:

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 Long 
Private 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 Long 
Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal hInet As Long) As Integer 
Private Declare Function InternetReadFile Lib "wininet.dll" (ByVal hFile As Long, ByRef Buffer As Any, ByVal lNumberOfBytesToRead As Long, lNumberOfBytesRead As Long) As Integer 
Private 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 Long 

Private Const INTERNET_OPEN_TYPE_PRECONFIG = 0 
Private Const INTERNET_FLAG_RELOAD = &H80000000 
Private Const INTERNET_FLAG_KEEP_CONNECTION = &H400000 ' use keep-alive semantics - required for NTLM proxy authentication 
Private Const HTTP_QUERY_CONTENT_LENGTH = 5 
Private Const HTTP_QUERY_FLAG_NUMBER = &H20000000 

Si necesita cualquier aclaración, publicar un comentario.

0

¿Desea una barra de progreso en VBA, no funcionaría uno de estos enfoques?

Progress bar in VBA Excel

Parece mucho más simple de hacerlo como usted describe, o no soy yo la comprensión?

Bien, intente esto. Obtenga los encabezados de la URL y analícelos para Content-Length. Luego puede establecer su barra de progreso en consecuencia.

Function GetFileSize(URL As String) As Long 

Dim xml As Object ' MSXML2.XMLHTTP60 
Dim result As String 

Set xml = CreateObject("MSXML2.XMLHTTP.6.0") 

With xml 
    ' get headers only 
    .Open "HEAD", URL, False 
    .send 
End With 

result = xml.getResponseHeader("Content-Length") 

GetFileSize = CLng(result) 

End Function 

Ahora simplemente llame a la función con la URL del archivo que desea descargar. Debería darle la cantidad de bytes del archivo.

+1

Mostrar la barra de progreso es simple. La dificultad está en descubrir el progreso de la descarga en sí. En otras palabras, me gustaría saber si hay una forma de consultar el estado de descarga actual para ver si estoy al 10% completo, o al 25% completo, etc. Ahora mismo solo sé cuando estoy al 0% completo. y 100% completo. Eso no es demasiado útil para mis usuarios. – mwolfe02

+0

Ver mi respuesta actualizada. No es mucho, pero es algo. – JimmyPena

Cuestiones relacionadas