在循环内部打开对象“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响应。 当代码尝试再次循环时,我得到:

对象IXMLHTTPRequest的方法打开失败

我不明白为什么我的代码只运行一次,只是一次循环。 我试图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