¿Cómo puedo enviar una solicitud HTTP POST a un servidor desde Excel usando VBA?

Respuestas:

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

Alternativamente, para un mayor control sobre la solicitud HTTP que puede usar WinHttp.WinHttpRequest.5.1en lugar de MSXML2.ServerXMLHTTP.

Bill el lagarto
fuente
9
Para un mayor control sobre la solicitud HTTP, puede usar "WinHttp.WinHttpRequest.5.1" en lugar de "MSXML2.ServerXMLHTTP"
Matthew Murdoch
55
Cabe destacar que también puede usar esto para emitir un PUT HTTP cambiando "POST" a "PUT". El contenido para PUT va en el método .send (). Cualquier encabezado adicional que necesite establecer también se puede hacer siguiendo la sintaxis utilizada en el ejemplo de User-Agent.
Radicand
77
No use paréntesis alrededor de los parámetros si no usa el valor de retorno de Sub: la sintaxis de VBA no permite paréntesis alrededor de los parámetros de Sub (sin embargo, son necesarios para las funciones), por lo que estos paréntesis son en realidad paréntesis aritméticos utilizados para aclarar la precedencia del operador. Además de ser engañoso y poco claro, esto puede dar lugar a un error de tiempo de ejecución si el argumento es un objeto. Y aunque no se solicita explícitamente, por lo general, querrá usar la respuesta HTTP, que podría mencionar que puede recuperar objHTTP.responseText.
Leviatán el
44
@Leviathan que los padres realmente hacen más que eso: hacen que el tiempo de ejecución de VBA evalúe la expresión como un valor , y lo pasan al método ByVal independientemente de si la firma del método dice ByRefo no. Es por eso que usarlos con variables de objeto de un tipo que no tiene un miembro predeterminado causa errores en tiempo de ejecución; y utilizarlos en un objeto que lo hace tener un miembro predeterminado, pasa el valor de ese miembro predeterminado en lugar del objeto real.
Mathieu Guindon
1
Un millón de veces gracias. No sé por qué, porque no lo vi en ningún otro ejemplo, pero el encabezado "User-Agent" fue crucial para mí, porque de lo contrario el cuerpo no se envió en mi solicitud.
redOctober13
51

Si necesita que funcione tanto en Mac como en Windows, puede usar 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:

  • Con respecto a la salida ... No sé si es posible devolver los resultados a la misma celda que llamó a la función VBA. En el ejemplo anterior, el resultado se escribe en A2.
  • Con respecto a la entrada ... Si desea que los resultados se actualicen cuando cambie ciertas celdas, asegúrese de que esas celdas sean el argumento de su función VBA.
  • Esto no funcionará en Excel para Mac 2008, que no tiene VBA. Excel para Mac 2011 recuperó VBA.

Para obtener más detalles, puede ver mi resumen completo sobre "el uso de servicios web desde Excel ".

Seamus Abshere
fuente
3
+1: Solo lo necesito en Windows, pero una solución multiplataforma podría beneficiar a alguien más.
Matthew Murdoch
No creo que pueda acceder al código html, solo puede obtener la información en la página web representada (no el código html real)
usuario1493046
1
+1 para la solución multiplataforma y +1 (si pudiera) para el resumen completo con el enlace esencial y todo. ¡¡Gracias!!
ataque aéreo
Tuve que admitir Windows y Mac, ¡y esta solución fue correcta! Tenga en cuenta que cuando especifica PostText, la URL debe procesar las solicitudes POST; de lo contrario, debe procesar las solicitudes GET.
amolk
1
¿Es posible enviar los resultados a una variable en lugar de un Rango? Necesito hacer un análisis Json.
Stanislasdrg Restablece a Mónica
42

Además de la respuesta de Bill el Lagarto :

La mayoría de los backends analizan los datos de publicación sin procesar. En PHP, por ejemplo, tendrá una matriz $_POSTen la que se almacenarán variables individuales dentro de los datos de publicación. En este caso, debe usar un encabezado 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")

De lo contrario, debe leer los datos de publicación sin procesar en la variable "$HTTP_RAW_POST_DATA".

este código
fuente
1
Estoy tratando de publicar esta solicitud (con llaves) y obtener errores de compilación ... ¿pueden ayudarme: "{" request ": {" carName ":" Honda "," model ":" 1A5 "}}"
violín
6

Puede usar ServerXMLHTTPen un proyecto VBA agregando una referencia a MSXML.

  1. Abra el Editor de VBA (generalmente editando una Macro)
  2. Ir a la lista de referencias disponibles
  3. Verificar Microsoft XML
  4. Haga clic en Aceptar.

(de Referencia a MSXML dentro de proyectos VBA )

La documentación de ServerXMLHTTP MSDN tiene detalles completos sobre todas las propiedades y métodos de ServerXMLHTTP.

En resumen, funciona básicamente así:

  1. Llamada abierta método para conectarse al servidor remoto
  2. Llamada enviar para enviar la solicitud.
  3. Lea la respuesta a través de responseXML , responseText , responseStream o responseBody
Mark Biek
fuente
1
ese enlace usa jscript, no VBA
John Henckel
1
Gracias @ JohnHenckel. He realizado algunos cambios para actualizar esa respuesta.
Mark Biek
3

Para completar la respuesta de los otros usuarios:

Para esto, he creado un objeto "WinHttp.WinHttpRequest.5.1" .

Envíe una solicitud de publicación con algunos datos de Excel usando 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")

Envíe una solicitud de obtención con autenticación de token desde Excel usando 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
fuente
David, una vez que envías la solicitud, ¿cómo lees la respuesta?
ps0604
La respuesta está adentro TCRequestItem Object, puedes leerlo como: TCRequestItem.ResponseTextdespués de hacerloTCRequestItem.send
David Q
0

Hice esto antes de usar la biblioteca MSXML y luego usar el objeto XMLHttpRequest, mira aquí .

Sijin
fuente
1
Archivo no encontrado.
SuShuang