在循环内部打开对象“IXMLHTTPRequest”失败
我想检查一下我的服务器每秒存在一个文件大概十秒钟。 如果该文件在那里,请下载它。 它不在那里(404)再次尝试,直到最多十次分散在十秒以上。 我通常不会在VBA中编写代码,但在这里..我有我的下载function:
Function DownloadFile(url As String, fileID As String) ' Setup our path where we will save the downloaded file. Dim fileSavePath As String fileSavePath = Environ("USERPROFILE") & "\" & Environ("USERNAME") & "-123-" & fileID & ".xlsx" ' Use Microsoft.XMLHTTP in order to setup a connection. ' https://msdn.microsoft.com/en-us/library/ms535874(v=vs.85).aspx#methods Dim WinHttpReq As Object Set WinHttpReq = CreateObject("MSXML2.XMLHTTP") ' Pass GET to the Open method in order to start the download of the file. WinHttpReq.Open "GET", url, False ' method, http verb, async = false ' Send our request: https://msdn.microsoft.com/en-us/library/ms536736(v=vs.85).aspx WinHttpReq.send ' Reset the url parameter to be the body of the response. url = WinHttpReq.responseBody ' WinHttpReq.Status holds the HTTP response code. If WinHttpReq.Status = 200 Then ' Setup an object to hold the binary stream of data (the file). Set oStream = CreateObject("ADODB.Stream") oStream.Open ' Set type read only or not: https://msdn.microsoft.com/en-us/library/ms681553(v=vs.85).aspx oStream.Type = 1 ' Write the binary data to WinHttpReq.responseBody ' We can do this because we have confirmed a download via the response code (200). oStream.Write WinHttpReq.responseBody oStream.SaveToFile fileSavePath, 2 ' 2 = overwrites the existing file, 1 = will not. ' We are done we the stream, close it. oStream.Close Debug.Print "File downloaded! File path: " & fileSavePath DownloadFile = 1 End If ' Handle if the file doesn't exist. If WinHttpReq.Status = 404 Then DownloadFile = 0 End If End Function
而且我有一个Sub可以调用这个函数十次:
Sub Callee(url As String, fileID As String) Dim i As Integer i = 0 Do While i < 10 If DownloadFile(url, fileID) = 1 Then Debug.Print "here" i = 100 Else Debug.Print fileID & " not found! Try number: " & i i = i + 1 ' We didnt get the response we wanted, so we will wait one second and try again. Application.Wait (Now + TimeValue("0:00:01")) End If Loop End Sub
我的代码只运行一次,当我收到一个404响应。 当代码尝试再次循环时,我得到:
我不明白为什么我的代码只运行一次,只是一次循环。 我试图Set WinHttpReq = Nothing
在我的函数结束,以防万一某种垃圾回收没有被照顾,但是我意识到这个variables是作用于我的函数,所以…
谢谢你的帮助。
对不起,这个问题和答案是误导性的。 代码中有一个错误
' Reset the url parameter to be the body of the response. url = WinHttpReq.responseBody
url
被二进制数据填充。 你为什么做这个? 当然,使用ByVal
意味着你每次都得到一个新的url
但你为什么要这样做呢? 我评论了这条线,问题就消失了。
所以,恕我直言,这与MSXML2.XMLHTTP
实例化和垃圾收集没有任何关系,只是传入的url
是无效的。
你可以尝试在Callee
方法中创buildWinHttpReq
,并使用这个对象来发送请求? 例:
Option Explicit Sub Callee(url As String, fileID As String) ' Setup our path where we will save the downloaded file. Dim fileSavePath As String fileSavePath = Environ("USERPROFILE") & "\" & Environ("USERNAME") & "-123-" & fileID & ".xlsx" ' Use Microsoft.XMLHTTP in order to setup a connection. ' https://msdn.microsoft.com/en-us/library/ms535874(v=vs.85).aspx#methods Dim WinHttpReq As Object Set WinHttpReq = CreateObject("MSXML2.XMLHTTP") ' Pass GET to the Open method in order to start the download of the file. WinHttpReq.Open "GET", url, False ' method, http verb, async = false Dim i As Integer i = 0 Do While i < 10 If DownloadFile(url, fileID, fileSavePath, WinHttpReq) = 1 Then Debug.Print "here" Exit Do Else Debug.Print fileID & " not found! Try number: " & i i = i + 1 ' We didnt get the response we wanted, so we will wait one second and try again. Application.Wait (Now + TimeValue("0:00:01")) End If Loop End Sub Function DownloadFile(url As String, fileID As String, fileSavePath As String, WinHttpReq As Object) ' Send our request: https://msdn.microsoft.com/en-us/library/ms536736(v=vs.85).aspx WinHttpReq.send ' Reset the url parameter to be the body of the response. url = WinHttpReq.responseBody ' WinHttpReq.Status holds the HTTP response code. If WinHttpReq.Status = 200 Then ' Setup an object to hold the binary stream of data (the file). Dim oStream Set oStream = CreateObject("ADODB.Stream") oStream.Open ' Set type read only or not: https://msdn.microsoft.com/en-us/library/ms681553(v=vs.85).aspx oStream.Type = 1 ' Write the binary data to WinHttpReq.responseBody ' We can do this because we have confirmed a download via the response code (200). oStream.Write WinHttpReq.responseBody oStream.SaveToFile fileSavePath, 2 ' 2 = overwrites the existing file, 1 = will not. ' We are done we the stream, close it. oStream.Close Debug.Print "File downloaded! File path: " & fileSavePath DownloadFile = 1 End If ' Handle if the file doesn't exist. If WinHttpReq.Status = 404 Then DownloadFile = 0 End If End Function