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