Como posso enviar uma solicitação HTTP POST para um servidor do Excel usando o VBA?

135

Qual código VBA é necessário para executar um HTTP POST a partir de uma planilha do Excel?

Matthew Murdoch
fonte

Respostas:

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

Como alternativa, para maior controle sobre a solicitação HTTP, você pode usar WinHttp.WinHttpRequest.5.1no lugar de MSXML2.ServerXMLHTTP.

Bill the Lizard
fonte
9
Para maior controle sobre a solicitação HTTP você pode usar "WinHttp.WinHttpRequest.5.1" em vez de "MSXML2.ServerXMLHTTP"
Matthew Murdoch
5
Digno de nota é que você também pode usar isso para emitir um HTTP PUT, alterando "POST" para "PUT". O conteúdo para PUT segue o método .send (). Quaisquer cabeçalhos adicionais que você precise definir também podem ser executados seguindo a sintaxe usada no exemplo Agente do Usuário.
Radicand
7
Por favor, não use parênteses em torno dos parâmetros se você não usar o valor de retorno do Sub: A Sintaxe do VBA não permite parênteses em torno dos parâmetros do Sub (eles são necessários para Funções), portanto, esses parênteses são na verdade parênteses aritméticos usados ​​para esclarecer a precedência do operador. Além de enganoso e pouco claro, isso pode resultar em um erro de tempo de execução se o argumento for um objeto. E, embora não seja solicitado explicitamente, geralmente você deseja usar a resposta HTTP, a qual você pode mencionar que pode ser recuperada objHTTP.responseText.
Leviathan
4
@Leviathan os parênteses realmente fazem mais do que isso: eles fazem o tempo de execução do VBA avaliar a expressão como um valor e a passam para o método ByVal, independentemente de a assinatura do método dizer ByRefou não. É por isso que usá-los com variáveis ​​de objeto de um tipo que não possui um membro padrão causa erros em tempo de execução; e usá-los em um objeto que faz ter um membro padrão, passa o valor desse membro padrão em vez do objeto real.
Mathieu Guindon
1
Um milhão de vezes obrigado. Não sei por que, porque não o vi em outros exemplos, mas o cabeçalho "User-Agent" foi crucial para mim, porque, caso contrário, o corpo não estava sendo enviado em minha solicitação.
redOctober13 20/03
51

Se você precisar que ele funcione no Mac e no Windows, use o 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

Notas:

  • Em relação à saída ... Não sei se é possível retornar os resultados para a mesma célula que chamou a função VBA. No exemplo acima, o resultado é gravado em A2.
  • Em relação à entrada ... Se você deseja que os resultados sejam atualizados ao alterar determinadas células, verifique se essas células são o argumento para sua função VBA.
  • Isso não funcionará no Excel para Mac 2008, que não possui VBA. O Excel para Mac 2011 recuperou o VBA.

Para mais detalhes, você pode ver meu resumo completo sobre " uso de serviços web do Excel ".

Seamus Abshere
fonte
3
+1: eu só preciso dele no Windows, mas uma solução de plataforma cruzada pode beneficiar outra pessoa.
Matthew Murdoch
Eu não acho que você pode realmente acessar o código html, você só pode obter a informação na página web prestados (não o código html real)
user1493046
1
+1 para a solução de plataforma cruzada e +1 (se possível) para o resumo completo com link essencial e tudo. Obrigado!!
ataque aéreo
Eu tinha que suportar Windows e Mac, e esta solução estava certa! Observe que, quando você especifica PostText, a URL deve processar solicitações POST, caso contrário, deve processar solicitações GET.
amolk
1
É possível gerar os resultados para uma variável em vez de um intervalo? Precisa fazer algumas análises de Json.
Stanislasdrg Restabelecer Monica
42

Além da resposta de Bill the Lizard :

A maioria dos back-end analisa os dados brutos da postagem. No PHP, por exemplo, você terá uma matriz $_POSTna qual variáveis ​​individuais nos dados de postagem serão armazenadas. Nesse caso, você precisa usar um cabeçalho adicional "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")

Caso contrário, você precisará ler os dados brutos da postagem na variável "$HTTP_RAW_POST_DATA".

este código
fonte
1
Estou tentando postar esta solicitação (com chaves) e obter erros de compilação ... upls pode ajudar: "{" request ": {" carName ":" Honda "," model ":" 1A5 "}}"
fiddle
6

Você pode usar ServerXMLHTTPem um projeto VBA adicionando uma referência a MSXML.

  1. Abra o Editor do VBA (geralmente editando uma macro)
  2. Vá para a lista de referências disponíveis
  3. Verifique Microsoft XML
  4. Clique OK.

(de Referenciando MSXML em projetos VBA )

A documentação do ServerXMLHTTP MSDN possui detalhes completos sobre todas as propriedades e métodos do ServerXMLHTTP.

Em resumo, porém, funciona basicamente assim:

  1. Chame o método aberto para conectar-se ao servidor remoto
  2. Ligue para enviar para enviar a solicitação.
  3. Leia a resposta via responseXML , responseText , responseStream ou responseBody
Mark Biek
fonte
1
que apontam usos JScript, não VBA
John Henckel
1
Obrigado @JohnHenckel. Fiz algumas alterações para atualizar essa resposta.
precisa saber é o seguinte
3

Para concluir a resposta dos outros usuários:

Para isso, criei um objeto "WinHttp.WinHttpRequest.5.1" .

Envie uma solicitação de postagem com alguns dados do Excel usando o 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")

Envie uma solicitação de obtenção com autenticação de token do Excel usando o 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
fonte
David, depois de enviar a solicitação, como você lê a resposta?
ps0604 16/02
A resposta está dentro TCRequestItem Object, você pode lê-lo como: TCRequestItem.ResponseTextdepois de fazerTCRequestItem.send
David Q
0

Eu fiz isso antes de usar a biblioteca MSXML e, em seguida, usar o objeto XMLHttpRequest, veja aqui .

Sijin
fonte
1
Arquivo não encontrado.
SuShuang 13/09/19