
Escribí esta función en VBA para recuperar datos de una URL. Lo estoy llamando desde otra función que se llama en una consulta de Access. El código está adaptado del código de un artículo citado en los comentarios del código:
'========================================================
Public Function sURLfetch(ByVal sURL As String) As String
'========================================================
' Return data found at a URL.
' From "www.MyExcelGenius.com/getting-data-from-a-website-in-json-format-using-vba/".
' Requires reference "Microsoft XML, v6.0".
Const bRunAsynch As Boolean = True
Const nProcessComplete As Integer = 4
Dim oRequest As MSXML2.XMLHTTP60
Set oRequest = New MSXML2.XMLHTTP60
Dim sResponse As String
With oRequest
.Open "get", sURL, bRunAsynch
.setRequestHeader "Content-Type", "application/json"
.send
Do While oRequest.ReadyState <> nProcessComplete
DoEvents
Loop
sResponse = .responseText
End With
sURLfetch = sResponse
'========================================================
End Function ' sURLfetch()
'========================================================
Cuando se llama a esta función, se bloquea VBA. Pero aquí está lo extraño: si establezco un punto de interrupción en la línea:
Do While oRequest.ReadyState <> nProcessComplete
y luego decirle a VBA que continúe desde allí, luego funciona bien y devuelve el resultado deseado. Hace esto una y otra vez, devolviendo la secuencia adecuada de resultados, siempre que el código se interrumpa en ese punto de interrupción y luego continúe. Sin embargo, si elimino ese punto de interrupción y establezco un punto de interrupción en la línea justo después del bucle:
sResponse = .responseText
luego se cuelga y no obtengo nada.
Entonces, por alguna razón, esta función se bloquea en el ciclo a menos que un punto de interrupción le indique que haga una pausa antes de ingresar al ciclo.
El propósito del bucle es garantizar que el proceso de búsqueda se haya completado antes de registrar la respuesta. He observado el funcionamiento del código y el ciclo generalmente se repite cero o una vez. Cuando se repite, significa que la búsqueda estaba incompleta y era necesario finalizarla. Entonces el bucle es necesario para lo que estoy buscando. Y por alguna razón, parece funcionar bien siempre que haya un punto de interrupción antes, pero por lo demás se bloquea misteriosamente.
La DoEvents
función, todo el contenido del bucle, simplemente le dice a VBA que permita que el sistema operativo haga lo que sea que esté sucediendo mientras se ejecuta el bucle. Esa llamada a función está en elcódigo originaladaptado aquí y hay documentación de la función pormicrosoftypozo.
Intenté automatizar la pausa insertando una llamada a una función que pausa VBA por un tiempo aleatorio. Eso no impidió que la función se colgara.
Resumen:
- La función funciona si está pausada por un punto de interrupción al comienzo del ciclo.
- Se cuelga si se llama sin un punto de interrupción o con un punto de interrupción después de ese bucle.
¿Qué podría estar causando que esta función se cuelgue y qué podría cambiar para que funcione?
Respuesta1
Parece que el problema fue configurar el asynch
parámetro en el Open
comando en True
. ese escenariopermite que la solicitud se detenga antes de que finalice, que es lo que hizo DoEvents
necesario el bucle. Así que intenté cambiar ese parámetro False
y comentar el bucle. Después de eso, la función parece funcionar bien.
No sé por qué elcódigo originalusado asynch
= True
y el bucle. Eso parece haber sido lo que hizo que la función no funcionara.