Jak mogę wysłać żądanie HTTP POST do serwera z programu Excel przy użyciu VBA?


Odpowiedzi:


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

Alternatywnie, aby uzyskać większą kontrolę nad żądaniem HTTP, możesz użyć WinHttp.WinHttpRequest.5.1zamiast MSXML2.ServerXMLHTTP.


9
Aby uzyskać większą kontrolę nad żądaniami HTTP, możesz użyć „WinHttp.WinHttpRequest.5.1” zamiast „MSXML2.ServerXMLHTTP”
Matthew Murdoch

5
Warto zauważyć, że możesz również użyć tego do wysłania HTTP PUT, zmieniając „POST” na „PUT”. Treść do PUT trafia do metody .send (). Wszelkie dodatkowe nagłówki, które musisz ustawić, można również wykonać zgodnie ze składnią używaną w przykładzie User-Agent.
radicand

7
Nie używaj nawiasów wokół parametrów, jeśli nie używasz wartości zwracanej przez Sub: składnia VBA nie zezwala na nawiasy wokół parametrów Sub (są one jednak potrzebne dla funkcji), więc te nawiasy są w rzeczywistości nawiasami arytmetycznymi używanymi do wyjaśnienia pierwszeństwa operatorów. Oprócz tego, że jest mylący i niejasny, może to ostatecznie spowodować błąd w czasie wykonywania, jeśli argument jest obiektem. I chociaż nie jest to wyraźnie wymagane, zwykle chciałbyś użyć odpowiedzi HTTP, o której możesz wspomnieć, że można ją pobrać objHTTP.responseText.
Lewiatan,

4
@Leviathan pareny faktycznie robią więcej: sprawiają, że środowisko wykonawcze VBA ocenia wyrażenie jako wartość i przekazuje je do metody ByVal niezależnie od tego, czy sygnatura metody mówi, ByRefczy nie. Dlatego używanie ich ze zmiennymi obiektowymi typu, który nie ma domyślnego elementu członkowskiego, powoduje błędy w czasie wykonywania; i użycie ich na obiekcie, który ma domyślny element członkowski, przekazuje wartość tego domyślnego elementu członkowskiego zamiast rzeczywistego obiektu.
Mathieu Guindon

1
Milion razy dziękuję. Nie wiem dlaczego, bo nie widziałem tego w innych przykładach, ale nagłówek "User-Agent" był dla mnie kluczowy, bo inaczej treść nie była wysyłana w moim żądaniu.
czerwony,

51

Jeśli potrzebujesz go do pracy zarówno na Macu, jak i Windowsie, możesz użyć 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

Uwagi:

  • Odnośnie wyników ... Nie wiem, czy możliwe jest zwrócenie wyników do tej samej komórki, która wywołała funkcję VBA. W powyższym przykładzie wynik jest zapisywany w A2.
  • Odnośnie danych wejściowych ... Jeśli chcesz, aby wyniki były odświeżane po zmianie niektórych komórek, upewnij się, że te komórki są argumentem funkcji VBA.
  • To nie zadziała w programie Excel dla komputerów Mac 2008, który nie ma języka VBA. Program Excel dla komputerów Mac 2011 odzyskał VBA.

Aby uzyskać więcej informacji, zobacz moje pełne podsumowanie dotyczące „ korzystania z usług internetowych w programie Excel ”.


3
+1: Potrzebuję tego tylko w systemie Windows, ale rozwiązanie wieloplatformowe może przynieść korzyści komuś innemu.
Matthew Murdoch

Myślę, że nie masz dostępu do kodu html, możesz tylko uzyskać informacje z renderowanej strony internetowej (a nie rzeczywisty kod HTML)
user1493046

1
+1 za rozwiązanie wieloplatformowe i +1 (jeśli mógłbym) za pełne podsumowanie z linkiem do treści i wszystkim. Dzięki!!
nalot

Musiałem obsługiwać zarówno Windows, jak i Maca, a to rozwiązanie działało! Zauważ, że jeśli określisz PostText, adres URL powinien przetwarzać żądania POST, w przeciwnym razie powinien przetwarzać żądania GET.
amolk

1
Czy można wyprowadzić wyniki do zmiennej zamiast do zakresu? Muszę przeprowadzić analizę Json.
Stanislasdrg Przywróć Monikę

42

Oprócz odpowiedzi Billa Jaszczura :

Większość backendów analizuje nieprzetworzone dane post. Na przykład w PHP będziesz mieć tablicę, $_POSTw której będą przechowywane poszczególne zmienne w danych wiadomości. W takim przypadku musisz użyć dodatkowego nagłówka "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")

W przeciwnym razie musisz odczytać surowe dane postu dotyczące zmiennej "$HTTP_RAW_POST_DATA".


1
Próbuję wysłać tę prośbę (z nawiasami klamrowymi) i otrzymuję błędy kompilacji ... czy możesz u pls pomóc: "{" request ": {" carName ":" Honda "," model ":" 1A5 "}}"
skrzypce

6

Możesz użyć ServerXMLHTTPw projekcie VBA, dodając odwołanie do MSXML.

  1. Otwórz edytor VBA (zwykle edytując makro)
  2. Przejdź do listy dostępnych referencji
  3. Sprawdź Microsoft XML
  4. Kliknij OK.

(z odniesienia do MSXML w projektach VBA )

Dokumentacja ServerXMLHTTP MSDN zawiera szczegółowe informacje o wszystkich właściwościach i metodach ServerXMLHTTP.

Krótko mówiąc, działa to zasadniczo w ten sposób:

  1. Wywołaj metodę otwartą , aby połączyć się ze zdalnym serwerem
  2. Zadzwoń wyślij, aby wysłać zapytanie.
  3. Przeczytaj odpowiedź przez responseXML , responseText , responseStream lub responseBody

1
ten link używa jscript, a nie VBA
John Henckel

1
Dzięki @JohnHenckel. Wprowadziłem kilka zmian, aby zaktualizować tę odpowiedź.
Mark Biek

3

Aby uzupełnić odpowiedź innych użytkowników:

W tym celu utworzyłem „WinHttp.WinHttpRequest.5.1” .

Wyślij żądanie wpisu z niektórymi danymi z Excela za pomocą 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")

Wyślij żądanie odbioru z uwierzytelnianiem tokenów z programu Excel za pomocą 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

Davidzie, po wysłaniu prośby, jak odczytujesz odpowiedź?
ps0604

Odpowiedź jest w środku TCRequestItem Object, możesz to przeczytać tak: TCRequestItem.ResponseTextpo wykonaniuTCRequestItem.send
David Q

0

Zrobiłem to przed użyciem biblioteki MSXML, a następnie używając obiektu XMLHttpRequest, patrz tutaj .


1
Nie znaleziono pliku.
SuShuang
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.