為什麼這個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和循環。這似乎是導致該功能不起作用的原因。

相關內容