Eu escrevi esta função em VBA para buscar dados de uma URL. Estou chamando de outra função que é chamada em uma consulta do Access. O código é adaptado do código em um artigo citado nos comentários do 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()
'========================================================
Quando esta função é chamada, ela trava o VBA. Mas aqui está a coisa estranha: se eu definir um ponto de interrupção na linha:
Do While oRequest.ReadyState <> nProcessComplete
e, em seguida, diga ao VBA para continuar a partir daí, ele roda bem e retorna o resultado desejado. Ele faz isso repetidamente, retornando a sequência adequada de resultados, desde que o código seja interrompido nesse ponto de interrupção e continue. No entanto, se eu remover esse ponto de interrupção e definir um ponto de interrupção na linha logo após o loop:
sResponse = .responseText
então ele trava e eu não recebo nada.
Portanto, por algum motivo, essa função trava no loop, a menos que seja instruída a pausar por um ponto de interrupção antes de entrar no loop.
A finalidade do loop é garantir que o processo de busca foi concluído antes de gravar a resposta. Observei a operação do código e o loop geralmente se repete zero ou uma vez. Quando se repete, significa que a busca estava incompleta e precisava ser concluída. Portanto, o loop é necessário para o que estou buscando. E, por algum motivo, parece funcionar bem, desde que haja um ponto de interrupção antes, mas, de outra forma, trava misteriosamente.
A DoEvents
função, todo o conteúdo do loop, apenas diz ao VBA para deixar o sistema operacional fazer o que estiver acontecendo enquanto o loop está sendo executado. Essa chamada de função está no código original adaptado aqui e há documentação da função pela Microsoft e wellsr .
Tentei automatizar a pausa inserindo uma chamada para uma função que pausa o VBA por um tempo aleatório. Isso não impediu que a função travasse.
Resumo:
- A função funciona se for pausada por um ponto de interrupção no início do loop.
- Ele trava se for chamado sem um ponto de interrupção ou com um ponto de interrupção após esse loop.
O que pode estar causando a interrupção dessa função e o que posso alterar para que funcione?
Parece que o problema estava configurando o
asynch
parâmetro noOpen
comando paraTrue
. Essa configuração permite que a solicitação pare antes de ser concluída , o que tornou oDoEvents
loop necessário. Então eu tentei mudar esse parâmetroFalse
e comentar o loop. Depois disso, a função parece estar funcionando bem.Não sei por que o código original usado
asynch
=True
e o loop. Isso parece ter sido o que fez a função não funcionar.