Wie Sie VBA-catch-request timeout der Fehler?
Ich bin mit Objekt MSXML2.ServerXMLHTTP60 senden Anfrage an webservice; mit diesem Objekt kann ich beschleunigen das laden von Daten von asynchrone Methode und vermeiden Absturz Excel-Bildschirm (reagiert nicht). Aber, ich bin immer noch ein problem haben, wenn der webservice-Antwort für eine lange Zeit, aus ServerXMLHTTP60 timeout-Einstellung, wird die Anfrage-Funktion war still, ich kann nicht fangen timeout-Fehler. Bei eine andere Frage, @osknows schlägt mit xmlhttp status = 408
zu fangen timeout-Fehler, aber es funktioniert nicht für mich.
Habe ich war eine test-Datei, die Sie herunterladen können hier. Öffnen VBA-Quelle durch drücken Atl + F8
sehen Sie Klasse Modul CXMLHTTPHandler
, dass ich kopiert aus diese Anleitung
If m_xmlHttp.readyState = 4 Then
If m_xmlHttp.Status = 200 Then
MsgBox m_xmlHttp.responseText
ElseIf m_xmlHttp.Status = 408 Then 'Debug never run to here?
MsgBox "Request timeout"
Else
'Error happened
End If
End If
, Wie Sie VBA-catch-request timeout der Fehler?
Danke für Eure Hilfe!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es mehrere Komplikationen hier.
MSXML2.ServerXMLHTTP
nicht aussetzen COM-Veranstaltungen nutzbar. Daher ist es nicht einfach möglich, instanziieren Sie ein Objekt mitWithEvents
und hängen Sie es an denOnReadyStateChange
Veranstaltung.Das Ereignis ist da, aber die standard-VBA-Weg zu handhaben, funktioniert es nicht.
waitForResponse()
wenn Sie asynchrone Anfragen (zusätzlich zum AufrufsetTimeouts()
!)timeout
Veranstaltung. Timeouts ausgelöst werden, wie ein Fehler.Zu beheben Problem #1:
In der Regel ein VBA-Klassenmodul (gilt auch für Benutzer Formulare oder Arbeitsblatt-Module) ermöglicht es Ihnen, dies zu tun:
so können Sie definieren einen event-handler wie diese:
Nicht so mit
MSXML2.ServerXMLHTTP
. Dadurch wird Ergebnis in ein Microsoft Visual Basic Kompilierungs-Fehler: "Objekt nicht source automation events".Offenbar das Ereignis wird nicht exportiert, für die COM verwenden. Es gibt einen Weg, um dieses.
Die Signatur für
onreadystatechange
liestSo ordnen Sie ein Objekt. Können wir erstellen ein Klassenmodul mit einer
onreadystatechange
- Methode und weisen wie diese:Jedoch, funktioniert dies nicht.
onreadystatechange
erwartet ein Objekt, und wenn das Ereignis ausgelöst wird, das Objekt sich genannt wird, und nicht die Methode, die wir definiert haben. (Für dieServerXMLHTTP
Instanz gibt es keine Möglichkeit zu wissen, welche Methode der Benutzer-definierteneventHandlingObject
wir beabsichtigen, zu verwenden, da der event-handler).Brauchen wir ein callable Objekt, d.h. ein Objekt mit einem Standard-Methode (jeder COM-Objekt kann genau ein).
(Zum Beispiel:
Collection
Objekte aufrufbar sind, können Sie sagenmyCollection("foo")
ist eine Kurzform fürmyCollection.Item("foo")
.)Zu beheben Problem #2:
Benötigen wir ein class-Modul mit einer default-Eigenschaft. Leider können diese nicht erstellt werden, mithilfe der VBA-IDE, aber Sie können erstellen Sie mit einem text-editor.
onreadystatechange
- Funktion in der VBA-IDE.cls
Datei über Rechtsklickonreadystatechange
Signatur:Attribute OnReadyStateChange.VB_UserMemId = 0
Dieser Marke wird die geänderte Methode als
Default
. Sehen Sie einen kleinen blauen Punkt in der Objekt-Browser (F2), Marken, die die Standard-Methode:Also jedes mal, wenn das Objekt aufgerufen wird, eigentlich die
OnReadyStateChange
- Methode aufgerufen wird.Zu beheben Problem #3:
Rufen Sie einfach
waitForResponse()
nachsend()
.Im Falle einer Zeitüberschreitung: Wenn Sie nicht diese Methode aufrufen, wird die Anfrage einfach nie zurück. Wenn du das getan hast, wird ein Fehler geworfen, nachdem
timeout
Millisekunden.Zu beheben Problem #4:
Brauchen wir eine
On Error
handler, fängt die timeout-Fehler auf und transformiert es in eine Veranstaltung, für die Bequemlichkeit.Setzen Sie alle zusammen
Hier ist ein VB-Klassenmodul habe ich geschrieben, dass Packungen und Griffe eine
MSXML2.ServerXMLHTTP
Objekt. Speichern Sie es alsAjaxRequest.cls
und importieren Sie es in Ihr Projekt:Beachten Sie die Zeile
m_xhr.OnReadyStateChange = Me
Zuordnung der AjaxRequest Instanz sich als Ereignis-handler möglich gemacht durch die KennzeichnungOnReadyStateChange()
als die Standard-Methode.Sich bewusst sein, dass wenn Sie änderungen an
OnReadyStateChange()
Sie brauchen durch zu gehen die exportieren/ändern/re-import-routine wieder kommen, da der VBA-IDE nicht speichern Sie die "Standard-Methode" Attribut.Die Klasse stellt die folgende Schnittstelle
HttpGet(url As String, [timeout As Long])
HttpPost(url As String, data As String, [timeout As Long])
Cancel()
IsRunning As Boolean
Started()
Stopped()
Success(data As String, serverStatus As String)
Error(data As String, serverStatus As String, xhr As MSXML2.ServerXMLHTTP)
TimedOut(message As String)
Verwenden Sie es in einer anderen Klasse, Modul, beispielsweise in einer user-form, mit
WithEvents
:Ergänzungen vornehmen, wie Sie sehen, passen. Die
AjaxRequest
Klasse war lediglich ein Nebenprodukt der Beantwortung dieser Frage.WinHttp.WinHttpRequest
- Objekt anstelle von hämmern aufMSXML2.ServerXMLHTTP
.WinHttpRequest
macht alle die richtigen Ereignisse in der richtigen Mode, aber dort gehen Sie.forget
zu überprüfen Antwort. Jetzt versuche ich esAjaxRequest
perfekt laufen! Nochmals vielen Dank!