Come posso inviare una richiesta POST HTTP a un server da Excel utilizzando VBA?


Risposte:


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("")

In alternativa, per un maggiore controllo sulla richiesta HTTP è possibile utilizzare WinHttp.WinHttpRequest.5.1al posto di MSXML2.ServerXMLHTTP.


9
Per un maggiore controllo sulla richiesta HTTP è possibile utilizzare "WinHttp.WinHttpRequest.5.1" invece di "MSXML2.ServerXMLHTTP"
Matthew Murdoch,

5
È degno di nota il fatto che è anche possibile utilizzarlo per emettere un PUT HTTP modificando "POST" in "PUT". Il contenuto di PUT va nel metodo .send (). Eventuali intestazioni aggiuntive che è necessario impostare possono essere eseguite anche seguendo la sintassi utilizzata nell'esempio User-Agent.
Radicand,

7
Si prega di non utilizzare le parentesi attorno ai parametri se non si utilizza il valore restituito del Sub: la sintassi VBA non consente le parentesi attorno ai parametri del Sub (tuttavia sono necessarie per le funzioni), quindi queste parentesi sono in realtà parentesi aritmetiche utilizzate per chiarire la precedenza dell'operatore. Oltre ad essere fuorviante e poco chiaro, ciò può eventualmente causare un errore di runtime se l'argomento è un oggetto. E anche se non esplicitamente richiesto, di solito si desidera utilizzare la risposta HTTP, che si può menzionare può essere recuperata da objHTTP.responseText.
Leviatano,

4
@Leviathan in realtà i genitori fanno molto di più: fanno in modo che il runtime VBA valuti l'espressione come valore e lo passano al metodo ByVal indipendentemente dal fatto che la firma del metodo lo dica ByRefo meno. Ecco perché usarli con variabili oggetto di un tipo che non ha un membro predefinito provoca errori di runtime; e il loro utilizzo su un oggetto che ha un membro predefinito, passa valore membro di predefinito anziché l'oggetto effettivo.
Mathieu Guindon,

1
Milioni di volte grazie. Non so perché, perché non l'ho visto in nessun altro esempio, ma l'intestazione "User-Agent" è stata fondamentale per me, perché altrimenti il ​​corpo non veniva inviato nella mia richiesta.
rosso ottobre 13

51

Se ne hai bisogno per funzionare su Mac e Windows, puoi usare QueryTables:

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

Appunti:

  • Per quanto riguarda l'output ... Non so se è possibile restituire i risultati alla stessa cella che ha chiamato la funzione VBA. Nell'esempio sopra, il risultato è scritto in A2.
  • Riguardo all'input ... Se vuoi che i risultati si aggiornino quando cambi determinate celle, assicurati che quelle celle siano l'argomento della tua funzione VBA.
  • Questo non funzionerà su Excel per Mac 2008, che non ha VBA. Excel per Mac 2011 ha recuperato VBA.

Per maggiori dettagli, puoi vedere il mio riepilogo completo su " utilizzo dei servizi Web da Excel ".


3
+1: ne ho bisogno solo su Windows, ma una soluzione multipiattaforma potrebbe andare a beneficio di qualcun altro.
Matthew Murdoch,

Non penso che tu possa effettivamente accedere al codice html, puoi solo ottenere le informazioni sulla pagina web renderizzata (non il codice html effettivo)
user1493046

1
+1 per la soluzione multipiattaforma e +1 (se potessi) per il riepilogo completo con link gist e tutto il resto. Grazie!!
attacco aereo

Ho dovuto supportare sia Windows che Mac, e questa soluzione era perfetta! Si noti che quando si specifica PostText, l'URL dovrebbe elaborare le richieste POST, altrimenti dovrebbe elaborare le richieste GET.
amolk

1
È possibile produrre i risultati su una variabile anziché su un intervallo? Devo fare un po 'di analisi Json.
Stanislasdrg Ripristina Monica il

42

Oltre alla risposta di Bill the Lizard :

La maggior parte dei backend analizza i dati post non elaborati. In PHP, ad esempio, avrai un array $_POSTin cui verranno memorizzate le singole variabili all'interno dei dati di post. In questo caso devi usare un'intestazione aggiuntiva "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")

Altrimenti devi leggere i dati grezzi dei post sulla variabile "$HTTP_RAW_POST_DATA".


1
Sto cercando di pubblicare questa richiesta (con parentesi graffe) e ottenere errori di compilazione ... puoi aiutarmi: "{" request ": {" carName ":" Honda "," model ":" 1A5 "}}"
violino

6

È possibile utilizzare ServerXMLHTTPin un progetto VBA aggiungendo un riferimento a MSXML.

  1. Apri l'editor VBA (di solito modificando una macro)
  2. Vai all'elenco dei riferimenti disponibili
  3. Controlla Microsoft XML
  4. Clicca OK.

(dal riferimento a MSXML nei progetti VBA )

La documentazione MSDN ServerXMLHTTP contiene dettagli completi su tutte le proprietà e i metodi di ServerXMLHTTP.

In breve, funziona sostanzialmente così:

  1. Chiamare il metodo aperto per connettersi al server remoto
  2. Chiama invia per inviare la richiesta.
  3. Leggi la risposta tramite responseXML , responseText , responseStream o responseBody

1
quel link utilizza jscript, non VBA
John Henckel,

1
Grazie @JohnHenckel. Ho apportato alcune modifiche per aggiornare quella risposta.
Mark Biek,

3

Per completare la risposta degli altri utenti:

Per questo ho creato un oggetto "WinHttp.WinHttpRequest.5.1" .

Invia una richiesta di post con alcuni dati da Excel utilizzando 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")

Invia una richiesta get con autenticazione token da Excel utilizzando 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, una volta inviata la richiesta, come leggi la risposta?
ps0604,

La risposta è dentro TCRequestItem Object, puoi leggerlo come: TCRequestItem.ResponseTextdopo aver fattoTCRequestItem.send
David Q

0

L'ho fatto prima di utilizzare la libreria MSXML e quindi di utilizzare l'oggetto XMLHttpRequest, vedere qui .


1
File non trovato.
SuShuang,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.