
Я написал эту функцию на VBA для извлечения данных из URL. Я вызываю ее из другой функции, которая вызывается в запросе Access. Код адаптирован из кода в статье, цитируемой в комментариях к коду:
'========================================================
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()
'========================================================
При вызове этой функции VBA зависает. Но вот что странно: если я ставлю точку останова на строке:
Do While oRequest.ReadyState <> nProcessComplete
и затем сказать VBA продолжить оттуда, тогда он запустится нормально и вернет желаемый результат. Он делает это снова и снова, возвращая правильную последовательность результатов, пока код прерывается на этой точке останова и затем продолжается. Однако, если я уберу эту точку останова и установлю вместо нее точку останова на строке сразу после цикла:
sResponse = .responseText
затем он зависает и я ничего не получаю.
Итак, по какой-то причине эта функция зависает в цикле, если только ей не приказано сделать паузу с помощью точки останова перед входом в цикл.
Цель цикла — убедиться, что процесс извлечения завершен перед записью ответа. Я наблюдал за работой кода, и цикл обычно повторяется ноль или один раз. Когда он повторяется, это означает, что извлечение было неполным и его нужно было завершить. Так что цикл необходим для того, что я извлекаю. И по какой-то причине он, кажется, работает нормально, пока перед ним есть точка останова, но в противном случае загадочно зависает.
Функция DoEvents
, все содержимое цикла, просто говорит VBA позволить операционной системе делать то, что она должна делать, пока выполняется цикл. Этот вызов функции находится висходный кодадаптированная здесь и там документация функцииМайкрософтиуэллср.
Я попытался автоматизировать паузу, вставив вызов функции, которая останавливает VBA на случайное время. Это не предотвратило зависание функции.
Краткое содержание:
- Функция работает, если она остановлена точкой останова в начале цикла.
- Он зависает, если вызывается без точки останова или с точкой останова после этого цикла.
Что может быть причиной зависания этой функции и что можно изменить, чтобы она заработала?
решение1
Похоже, проблема была в установке asynch
параметра в Open
команде на True
. Эта настройкапозволяет остановить запрос до его завершения, что и сделало DoEvents
цикл необходимым. Поэтому я попробовал изменить этот параметр на False
и закомментировать цикл. После этого функция, похоже, работает нормально.
Я не знаю, почемуисходный кодиспользовал asynch
= True
и цикл. Похоже, именно это и заставило функцию не работать.