Wie kann ich mit VBA eine HTTP-POST-Anfrage von Excel an einen Server senden?

135

Welcher VBA-Code ist erforderlich, um einen HTTP-POST aus einer Excel-Tabelle auszuführen?

Matthew Murdoch
quelle

Antworten:

147
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
URL = "http://www.somedomain.com"
objHTTP.Open "POST", URL, False
objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
objHTTP.send("")

Alternativ können Sie für eine bessere Kontrolle über die HTTP-Anforderung WinHttp.WinHttpRequest.5.1anstelle von verwenden MSXML2.ServerXMLHTTP.

Bill die Eidechse
quelle
9
Für eine bessere Kontrolle über die HTTP-Anfrage können Sie "WinHttp.WinHttpRequest.5.1" anstelle von "MSXML2.ServerXMLHTTP" verwenden
Matthew Murdoch
5
Bemerkenswert ist, dass Sie dies auch verwenden können, um einen HTTP-PUT auszugeben, indem Sie "POST" in "PUT" ändern. Der Inhalt für PUT erfolgt nach der Methode .send (). Alle zusätzlichen Header, die Sie festlegen müssen, können auch nach der im User-Agent-Beispiel verwendeten Syntax ausgeführt werden.
Radicand
7
Verwenden Sie keine Klammern um Parameter, wenn Sie den Rückgabewert des Sub nicht verwenden: Die VBA-Syntax erlaubt keine Klammern um die Parameter von Sub (sie werden jedoch für Funktionen benötigt), daher sind diese Klammern tatsächlich arithmetische Klammern, die zur Verdeutlichung der Operatorpriorität verwendet werden. Abgesehen davon, dass dies irreführend und unklar ist, kann dies letztendlich zu einem Laufzeitfehler führen, wenn das Argument ein Objekt ist. Und obwohl nicht explizit danach gefragt, möchten Sie normalerweise die HTTP-Antwort verwenden, von der Sie erwähnen können, dass sie von abgerufen werden kann objHTTP.responseText.
Leviathan
4
@Leviathan Die Parens tun tatsächlich mehr als das: Sie veranlassen die VBA-Laufzeit , den Ausdruck als Wert auszuwerten und ihn an die Methode ByVal zu übergeben, unabhängig davon, ob die Signatur der Methode dies sagt ByRefoder nicht. Aus diesem Grund führt die Verwendung mit Objektvariablen eines Typs ohne Standardelement zu Laufzeitfehlern. Wenn Sie sie für ein Objekt verwenden, das ein Standardmitglied hat, wird der Wert dieses Standardmitglieds anstelle des tatsächlichen Objekts übergeben.
Mathieu Guindon
1
Eine Million Mal danke. Ich weiß nicht warum, weil ich es in keinem anderen Beispiel gesehen habe, aber der "User-Agent" -Header war für mich entscheidend, weil sonst der Text in meiner Anfrage nicht gesendet wurde.
redOctober13
51

Wenn Sie es für Mac und Windows benötigen, können Sie QueryTables verwenden:

With ActiveSheet.QueryTables.Add(Connection:="URL;http://carbon.brighterplanet.com/flights.txt", Destination:=Range("A2"))
    .PostText = "origin_airport=MSN&destination_airport=ORD"
    .RefreshStyle = xlOverwriteCells
    .SaveData = True
    .Refresh
End With

Anmerkungen:

  • In Bezug auf die Ausgabe ... Ich weiß nicht, ob es möglich ist, die Ergebnisse an dieselbe Zelle zurückzugeben, die die VBA-Funktion aufgerufen hat. Im obigen Beispiel wird das Ergebnis in A2 geschrieben.
  • Informationen zur Eingabe ... Wenn Sie möchten, dass die Ergebnisse beim Ändern bestimmter Zellen aktualisiert werden, stellen Sie sicher, dass diese Zellen das Argument für Ihre VBA-Funktion sind.
  • Dies funktioniert nicht unter Excel für Mac 2008, das kein VBA hat. Excel für Mac 2011 hat VBA zurückbekommen.

Für weitere Details können Sie meine vollständige Zusammenfassung über " Verwenden von Webdiensten aus Excel ".

Seamus Abshere
quelle
3
+1: Ich brauche es nur unter Windows, aber eine plattformübergreifende Lösung könnte jemand anderem zugute kommen.
Matthew Murdoch
Ich glaube nicht, dass Sie tatsächlich auf den HTML-Code zugreifen können. Sie können nur die Informationen auf der gerenderten Webseite
abrufen
1
+1 für die plattformübergreifende Lösung und +1 (wenn ich könnte) für die vollständige Zusammenfassung mit dem Hauptlink und allem. Vielen Dank!!
Luftangriff
Ich musste sowohl Windows als auch Mac unterstützen, und diese Lösung war genau richtig! Beachten Sie, dass bei der Angabe von PostText die URL POST-Anforderungen verarbeiten sollte, andernfalls GET-Anforderungen.
Amolk
1
Ist es möglich, die Ergebnisse in einer Variablen anstelle eines Bereichs auszugeben? Müssen einige Json Parsing machen.
Stanislasdrg Reinstate Monica
42

Neben der Antwort von Bill the Lizard :

Die meisten Backends analysieren die Rohdaten der Post. In PHP haben Sie beispielsweise ein Array, $_POSTin dem einzelne Variablen in den Post-Daten gespeichert werden. In diesem Fall müssen Sie einen zusätzlichen Header verwenden "Content-type: application/x-www-form-urlencoded":

Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
URL = "http://www.somedomain.com"
objHTTP.Open "POST", URL, False
objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
objHTTP.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
objHTTP.send ("var1=value1&var2=value2&var3=value3")

Andernfalls müssen Sie die Rohdaten der Post für die Variable lesen "$HTTP_RAW_POST_DATA".

dieser Code
quelle
1
Ich versuche, diese Anfrage (mit geschweiften Klammern) zu posten und Kompilierungsfehler zu erhalten ... können Sie helfen: "{" request ": {" carName ":" Honda "," model ":" 1A5 "}}"
Geige
6

Sie können ServerXMLHTTPin einem VBA-Projekt verwenden, indem Sie einen Verweis auf hinzufügen MSXML.

  1. Öffnen Sie den VBA-Editor (normalerweise durch Bearbeiten eines Makros).
  2. Gehen Sie zur Liste der verfügbaren Referenzen
  3. Überprüfen Sie Microsoft XML
  4. OK klicken.

(aus Referenzieren von MSXML in VBA-Projekten )

Die ServerXMLHTTP-MSDN-Dokumentation enthält ausführliche Informationen zu allen Eigenschaften und Methoden von ServerXMLHTTP.

Kurz gesagt, es funktioniert im Grunde so:

  1. Anruf offen Methode auf, um eine Verbindung zum Remote-Server herzustellen
  2. Anruf senden an, um die Anfrage zu senden.
  3. Lesen Sie die Antwort über responseXML , responseText , responseStream oder responseBody
Mark Biek
quelle
1
Dieser Link verwendet jscript, nicht VBA
John Henckel
1
Danke @JohnHenckel. Ich habe einige Änderungen vorgenommen, um diese Antwort auf den neuesten Stand zu bringen.
Mark Biek
3

So vervollständigen Sie die Antwort der anderen Benutzer:

Dafür habe ich ein "WinHttp.WinHttpRequest.5.1" Objekt erstellt.

Senden Sie eine Post-Anfrage mit einigen Daten aus Excel mit VBA:

Dim LoginRequest As Object
Set LoginRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
LoginRequest.Open "POST", "http://...", False
LoginRequest.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
LoginRequest.send ("key1=value1&key2=value2")

Senden Sie eine Get-Anfrage mit Token-Authentifizierung aus Excel mit VBA:

Dim TCRequestItem As Object
Set TCRequestItem = CreateObject("WinHttp.WinHttpRequest.5.1")
TCRequestItem.Open "GET", "http://...", False
TCRequestItem.setRequestHeader "Content-Type", "application/xml"
TCRequestItem.setRequestHeader "Accept", "application/xml"
TCRequestItem.setRequestHeader "Authorization", "Bearer " & token
TCRequestItem.send
David Q.
quelle
David, wenn Sie die Anfrage gesendet haben, wie lesen Sie die Antwort?
ps0604
Die Antwort ist drinnen TCRequestItem Object, Sie können sie wie folgt lesen: TCRequestItem.ResponseTextNach dem AusführenTCRequestItem.send
David Q
0

Ich habe dies getan, bevor ich die MSXML-Bibliothek und dann das XMLHttpRequest-Objekt verwendet habe (siehe hier) .

Sijin
quelle
1
Datei nicht gefunden.
SuShuang