How to Send Variables on .SetRequestData on Excel VBA - excel

I'm working on a API integration on my Excel WorkSheet using VBA and I'm trying to send user input on a cell sent to a RequestHeader in order to find a product on the server
I've tried importing the data directly from the sheet onto a string and then sending that string as the value for the header but I can't seem to get it to work. I'm new to this whole VBA stuff so I don't honestly know if that's possible. Here's what I've tried:
Sub GetCompanyInformation()
Dim hReq As Object, JSON As Dictionary
Dim i As Long
Dim var As Variant
Dim ws As Worksheet
Set ws = Sheet1
'create our URL string and pass the user entered information to it
Dim strUrl As String
strUrl = "My API URL Goes Here"
Dim cod As String
cod = ws.[MYCELL]
Set hReq = CreateObject("MSXML2.XMLHTTP")
With hReq
.Open "GET", strUrl, False
.SetRequestHeader "cache-control", "no-cache"
.SetRequestHeader "data_filter", ""
.SetRequestHeader "data", "products"
.SetRequestHeader "data_id", cod
.Send
End With
[...]
It returns me an empty string. However if I send the request with the same number I add on my cell as such:
[...]
Set hReq = CreateObject("MSXML2.XMLHTTP")
With hReq
.Open "GET", strUrl, False
.SetRequestHeader "cache-control", "no-cache"
.SetRequestHeader "data_filter", ""
.SetRequestHeader "data", "products"
.SetRequestHeader "data_id", "1234"
.Send
End With
It Works, and it returns me the data I need. Am I doing something wrong? Can I get the variable data on a Request Header?

Related

Unable to create SharePoint item & update external columns content (business connectivity services)?

I am having trouble creating a new item within a SharePoint 2013 list. I'm able to actually create the item, though the external data (business connectivity services [bcs]) does not autopopulate as it would during the creation of the item via the SharePoint UI. Is there any way to actually make this work, or to send the function that needs to run via POST? I've pasted my current item creation sub below.
Dim oXMLHTTP As Object
Dim sListNameOrGuid As String
Dim sBatchXml As String
sWTF As String
Set oXMLHTTP = CreateObject("MSXML2.XMLHTTP.6.0")
sCurrentUser = fGetUserID
With oXMLHTTP
.Open "POST", "MYSPSITE.COM/_api/web/lists/GetByTitle('THELIST')/items", True
.setRequestHeader "Accept", "application/json;odata=verbose"
.setRequestHeader "Content-Type", "application/json;odata=verbose"
' .setRequestHeader "X-HTTP-Method", "PATCH"
' .setRequestHeader "If-Match", "*"
.setRequestHeader "X-RequestDigest", fGetLoginToken
sWTF = "{ 'User': " & Int(sCurrentUser) & ", 'newComment': 'TESTING TESTING'}"
.send (sWTF)
Do While .readyState <> 4:
DoEvents
Loop
Debug.Print (.responseText)
.abort
End With
Set oXMLHTTP = Nothing
End Sub
Lower the timer job frequency.

VBA- Unable to update SharePoint 2013 item via REST API

I am attempting to update a SharePoint item via REST API, though I am receiving the below error:
{"odata.error":{"code":"-1, System.InvalidOperationException","message":{"lang":"en-US","value":"The type of data at position 0 is different than the one expected."}}}
I'm not quite sure what is causing this- I have the request type set to JSON, but it does not seem to accept my input. Any help is appreciated :-)
My code:
Sub Work_Damn_You()
Dim oXMLHTTP As Object
Dim sListNameOrGuid As String
Dim sBatchXml As String
Dim sSoapBody As String
Dim sWTF as string
Set oXMLHTTP = CreateObject("MSXML2.XMLHTTP.6.0")
sListNameOrGuid = sListName
With oXMLHTTP
.Open "POST", "http://SPSITE.COM/_api/web/lists/GetByTitle('PAGE')/items(22)", True
.setRequestHeader "X-RequestDigest", testerino
.setRequestHeader "Accept", "application/json;odata=nometadata"
.setRequestHeader "Content-Type", "application/json;odata=verbose"
.setRequestHeader "__metadata", "(""type"":""SP.Data.QATrackerListItem"""
sWTF = """preTestComment""=""Hello"""
.send (sWTF)
Debug.Print (.responseText)
' Check response
If .Status = 200 Then
Debug.Print .Status & " [Happy Days!]"
Else
Debug.Print .Status & " [Sad Days :-(]"
End If
End With
Set oXMLHTTP = Nothing
End Sub
'''

VBA HTTP request to API with JSON body returns empty array (MSXML2.XMLHTTP in Excel)

Update: SOLVED --> Look below for answer.
Update:
At the Microsoft docs i can see that when open method is called with Async=false, the response might not return if "the protocol stack times out", however I have not been able to read up on the timeout timers.
https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms931177%28v%3dmsdn.10%29
Not really sure if it's related or not.
I'm trying to retrieve a JSON response object through VersionOne query API.
When i try to read the responseText in VBA I receive an empty array, however the exact same request returns correct data from PostMan. I get an HTTP 200 code response, but no data in the response body.
The reason for doing it in VBA and Excel is that the data needs to be analalyzed in a pre-existing Excel model.
I've tried different auth possibilities, both OAUTH and Basic.
This is the VBA code
Option Explicit
Sub Test_LateBinding()
Dim objRequest As Object
Dim strUrl As String
Dim strResponse As String
Dim body As String
Dim strResponseHeaders As String
Dim allResponseHeader As String
Set objRequest = CreateObject("MSXML2.XMLHTTP")
strUrl = "https://endpoint"
body = " { ""from"": ""Epic"",""select"": []}"
'with basic'
With objRequest
.Open "GET", strUrl, False, "XXXX", "XXXX"
.SetRequestHeader "Content-Type", "application/json"
.Send body
strResponseHeaders = .StatusText
strResponse = .ResponseText
allResponseHeader = .GetAllResponseHeaders
End With
Debug.Print body
Debug.Print allResponseHeader
Debug.Print strResponse
End Sub
This is my console output:
OK
Content-Type: application/json; charset=utf-8
Content-Length: 2
X-Content-Type-Options: nosniff
V1-MemberID: skatteministeriet/120267
Strict-Transport-Security: max-age=31536000; includeSubdomains
X-Robots-Tag: noindex
VersionOne: Ultimate/19.0.3.29; 0
X-Instart-Request-ID: 3912039762705832388:SEN01-NPPRY25:1553377406:0
[]
This is the PostMan response headers:
PostMan response headers
This is the URL and request JSON body:
URL and request body
SOLVED Finally...
So i found the answer.
After re-analyzing the Postman response i found that the JSON response was actually handed as a gzip encoded response. Which is simply not compatible with the MSXML2.XMLHTTP lib.
So to solve the problem all I did was to use the WinHttp.WinHttpRequest.5.1 lib instead, which is basicly newer. No other changes to the code was needed.
So to others out there using MSXML2.XMLHTTP or the WinHTTPserver.6.0 lib, change to the newer library :)
Option Explicit
Sub Test_LateBinding()
Dim objRequest As Object
Dim strUrl As String
Dim strResponse As String
Dim body As String
Dim strResponseHeaders As String
Dim allResponseHeader As String
Set objRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
strUrl = "https://endpoint"
body = " { ""from"": ""Epic"",""select"": []}"
'with basic'
With objRequest
.Open "GET", strUrl, False, "XXXX", "XXXX"
.SetRequestHeader "Content-Type", "application/json"
.Send body
strResponseHeaders = .StatusText
strResponse = .ResponseText
allResponseHeader = .GetAllResponseHeaders
End With
Debug.Print body
Debug.Print allResponseHeader
Debug.Print strResponse
End Sub

HTTPS Post using Excel VBA with XML body and request headers issue

I am trying to use Excel-VBA to perform an https POST of an XML body as follows:
Public Sub test()
Dim xmlhttp As Object
Set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")
Dim myDom As Object
Set myDom = CreateObject("MSXML2.DOMDocument.6.0")
URL = "https://uatgateway.topl.com.au/quote"
myDom.async = False
myXMLstr = URL & "<?xml version=&Chr(34)&1.0&Chr(34)& encoding=&Chr(34)&UTF-
8&Chr(34)& standalone=&Chr(34)&yes&Chr(34)&?><IMPULSE><REQUEST><QUOTE>
<MERCHANT><ACQUIRERID>Bank A</ACQUIRERID><NETWORKID>eComm</NETWORKID>
<MERCHANTID>987654321</MERCHANTID></MERCHANT><MCH_TRANSACTION>
<QUOTEREF>3456789012</QUOTEREF><MCH_ISO>036</MCH_ISO>
<MCH_AMT>1000.00</MCH_AMT><BIN>400555000</BIN></MCH_TRANSACTION></QUOTE>
</REQUEST></IMPULSE>"
myDom.Load (myXMLstr)
xmlhttp.Open "post", URL, False
xmlhttp.setRequestHeader "Content-Type", "application/xml"
xmlhttp.setRequestHeader "Content-Length", "356"
xmlhttp.setRequestHeader "Accept", "text/xml"
xmlhttp.setRequestHeader "Host", "uatgateway.topl.com.au"
xmlhttp.setRequestHeader "Cache-Control", "no-cache"
xmlhttp.send myDom.XML
MsgBox xmlhttp.responseText
End Sub
My VBA code compiles ok, but on execution stops at the xmlhttp.send line almost immediately with an error "the server returned an invalid or unrecognised response". The same POST on Postman works. I am not sure if I an referencing the myDom.XML correctly?
Any suggestions welcome?

Establishing an API session with xmlHttp in VBA

I apologize if my question's title is incorrect - I'm used to the idea of PHP sessions with APIs.
I'm trying to accomplish the same feat in VBA with the following code:
'Login
strLogin = "https://URL.COM/authenticateUser?login=username&apiKey=password"
Set xmlHttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")
xmlHttp.Open "GET", strLogin
xmlHttp.setRequestHeader "Content-Type", "text/xml"
xmlHttp.send
'Save the response to a string
strReturn = xmlHttp.responseText
'Open URL and get JSON data
strUrl = "https://URL.COM/Search/search?searchTerm=" & Keyword & "&mode=beginwith"
Set xmlHttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")
xmlHttp.Open "GET", strUrl
xmlHttp.setRequestHeader "Content-Type", "text/xml"
xmlHttp.send
'Save the response to a string
strReturn = xmlHttp.responseText
Sheets(1).Cells(20, 2).Value = strReturn
With this API, I need to login first prior to executing any calls that will return data.
My problem is that I cannot determine how to "stay logged in" so that my second call works.
after I login, strReturn is populated with the following string:
{"Status":{"Code":"2","Message":"Authentication Succeeded","Success":"true"}}
However, when I go to utilize strUrl, I get the following message:
{"Status":{"Code":"1","Message":"Invalid User Name Or Password","Success":"false"}}
I have used this code in prior projects where I needed to supply an API key along with the URL for each request to the server - so this obviously worked fine. I'm not sure how to achieve the concept of "establishing a session" though with xmlHttp.
So, to anyone else who runs across this, the simple solution was to remove the following line from the second call:
Set xmlHttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")
By not creating a new object, vba is able to keep and use the cookie from the first login call.
The final code looks like this:
'Login
strLogin = "https://URL.COM/authenticateUser?login=username&apiKey=password"
Set xmlHttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")
xmlHttp.Open "GET", strLogin
xmlHttp.setRequestHeader "Content-Type", "text/xml"
xmlHttp.send
'Save the response to a string
strReturn = xmlHttp.responseText
'Open URL and get JSON data
strUrl = "https://URL.COM/Search/search?searchTerm=" & Keyword & "&mode=beginwith"
xmlHttp.Open "GET", strUrl
xmlHttp.setRequestHeader "Content-Type", "text/xml"
xmlHttp.send
'Save the response to a string
strReturn = xmlHttp.responseText
Sheets(1).Cells(20, 2).Value = strReturn
And the API which requires a login is able to keep the session established.

Resources