Как я могу отправить HTTP-запрос POST на сервер из Excel с помощью VBA?

Какой код VBA требуется для выполнения HTTP POST из электронной таблицы Excel?


person Matthew Murdoch    schedule 01.10.2008    source источник


Ответы (6)


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

В качестве альтернативы, для большего контроля над HTTP-запросом вы можете использовать _ 2_ вместо MSXML2.ServerXMLHTTP.

person Bill the Lizard    schedule 01.10.2008
comment
Для большего контроля над HTTP-запросом вы можете использовать WinHttp.WinHttpRequest.5.1 вместо MSXML2.ServerXMLHTTP. - person Matthew Murdoch; 03.10.2008
comment
Примечательно, что вы также можете использовать это для выдачи HTTP PUT, изменив POST на PUT. Контент в PUT передается в методе .send (). Любые дополнительные заголовки, которые вам нужно установить, могут быть выполнены также в соответствии с синтаксисом, используемым в примере User-Agent. - person radicand; 24.01.2012
comment
Пожалуйста, не используйте круглые скобки вокруг параметров, если вы не используете возвращаемое значение Sub: синтаксис VBA не допускает скобок вокруг параметров Sub (хотя они необходимы для функций), поэтому эти круглые скобки фактически являются арифметическими скобками, используемыми для уточнения приоритета операторов. Помимо того, что это вводит в заблуждение и неясно, это может в конечном итоге привести к ошибке времени выполнения, если аргумент является объектом. И хотя явно не запрашивается, обычно вы хотите использовать HTTP-ответ, который, как вы могли упомянуть, может быть получен с помощью objHTTP.responseText. - person Leviathan; 09.01.2017
comment
@ Левиафан, паренсы на самом деле делают больше: они заставляют среду выполнения VBA оценивать выражение как значение и передавать его методу ByVal независимо от о том, написано ли в подписи метода ByRef или нет. Вот почему их использование с объектными переменными типа, не имеющего члена по умолчанию, вызывает ошибки времени выполнения; и используя их для объекта, который имеет член по умолчанию, передает значение этого члена по умолчанию вместо фактического объекта. - person Mathieu Guindon; 11.10.2017
comment
как насчет полезной нагрузки json ... как мы можем передать это в send? - person Amrit; 22.07.2019
comment
Предложение использовать WinHttp.WinHttpRequest.5.1 спасло меня, поскольку классы MSXML не позволили мне получить более одного заголовка Set-Cookie из ответа сервера на мой запрос. Спасибо! - person B1SeeMore; 13.01.2020
comment
Миллион раз спасибо. Я не знаю почему, потому что я не видел этого ни в каких других примерах, но заголовок User-Agent был для меня критически важен, потому что в противном случае тело не отправлялось в моем запросе. - person redOctober13; 20.03.2020

Если вам нужно, чтобы он работал как на Mac, так и на Windows, вы можете использовать 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

Примечания:

  • Что касается вывода ... Я не знаю, можно ли вернуть результаты в ту же ячейку, которая вызвала функцию VBA. В приведенном выше примере результат записывается в A2.
  • Что касается ввода ... Если вы хотите, чтобы результаты обновлялись при изменении определенных ячеек, убедитесь, что эти ячейки являются аргументом вашей функции VBA.
  • Это не будет работать в Excel для Mac 2008, в котором нет VBA. В Excel для Mac 2011 вернулся VBA.

Для получения дополнительной информации вы можете просмотреть мое полное резюме "об использовании веб-служб из Excel. "

person Seamus Abshere    schedule 06.01.2011
comment
+1: Мне это нужно только в Windows, но кроссплатформенное решение может принести пользу кому-то другому. - person Matthew Murdoch; 07.01.2011
comment
Я не думаю, что вы действительно можете получить доступ к html-коду, вы можете получить информацию только на визуализированной веб-странице (а не на фактическом html-коде) - person user1493046; 01.05.2013
comment
+1 за кроссплатформенное решение и +1 (если можно) за полное резюме с основной ссылкой и всем остальным. Спасибо!! - person airstrike; 23.07.2013
comment
Мне приходилось поддерживать как Windows, так и Mac, и это решение было правильным! Обратите внимание, что когда вы указываете PostText, URL-адрес должен обрабатывать запросы POST, в противном случае он должен обрабатывать запросы GET. - person amolk; 25.10.2013
comment
Можно ли вывести результаты в переменную вместо диапазона? Необходимо выполнить синтаксический анализ Json. - person Standaa - Remember Monica; 13.07.2016

В дополнение к ответу Ящерица Билла:

Большинство бэкэндов анализируют необработанные данные постов. В PHP, например, у вас будет массив $_POST, в котором будут храниться отдельные переменные в почтовых данных. В этом случае вам необходимо использовать дополнительный заголовок "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")

В противном случае вам придется читать необработанные данные поста в переменной "$HTTP_RAW_POST_DATA".

person thiscode    schedule 10.07.2013
comment
Я пытаюсь опубликовать этот запрос (с фигурными скобками) и получаю ошибки компиляции ... не могли бы вы помочь: {request: {carName: Honda, model: 1A5}} - person fiddle; 06.02.2018
comment
@fiddle вы URL кодировали эту строку? Фигурные скобки вызывают меньшее беспокойство, чем кавычки (которые завершают строки в VBA). - person Ruscal; 12.08.2020

Чтобы завершить ответ других пользователей:

Для этого я создал объект "WinHttp.WinHttpRequest.5.1".

Отправьте почтовый запрос с некоторыми данными из Excel с помощью 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")

Отправьте запрос на получение с аутентификацией токена из Excel с помощью 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
person david.q    schedule 11.12.2019
comment
Дэвид, как вы прочитаете ответ после того, как отправите запрос? - person ps0604; 16.02.2020
comment
Ответ находится внутри TCRequestItem Object, вы можете прочитать его так: TCRequestItem.ResponseText после выполнения TCRequestItem.send - person david.q; 18.02.2020

Вы можете использовать ServerXMLHTTP в проекте VBA, добавив ссылку на MSXML.

  1. Откройте редактор VBA (обычно путем редактирования макроса)
  2. Перейти к списку доступных ссылок
  3. Проверить Microsoft XML
  4. Щелкните ОК.

(из Ссылки на MSXML в проектах VBA )

Подробная информация содержится в ServerXMLHTTP MSDN документации. обо всех свойствах и методах ServerXMLHTTP.

Короче говоря, это работает примерно так:

  1. Вызовите метод open, чтобы подключиться к удаленный сервер
  2. Вызовите send, чтобы отправить запрос.
  3. Прочтите ответ через responseXML, responseText, responseStream или responseBody
person Mark Biek    schedule 01.10.2008
comment
эта ссылка использует jscript, а не VBA - person John Henckel; 19.08.2016
comment
Спасибо @JohnHenckel. Я внес некоторые изменения, чтобы обновить этот ответ. - person Mark Biek; 19.08.2016

Я сделал это перед использованием библиотеки MSXML, а затем с помощью объекта XMLHttpRequest, см. здесь.

person Sijin    schedule 01.10.2008
comment
Файл не найден. - person SuShuang; 13.09.2019