我已经在 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
和循环。这似乎是导致该函数不起作用的原因。