为什么这个 VBA 数据获取函数挂起了?

为什么这个 VBA 数据获取函数挂起了?

我已经在 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中的参数设置OpenTrue。该设置允许请求在完成之前停止,这就是DoEvents循环的必要性。因此,我尝试将该参数更改为False并注释掉循环。之后,该函数似乎运行良好。

我不知道为什么原始代码使用了asynch=True和循环。这似乎是导致该函数不起作用的原因。

相关内容