I want to connect to a Cloudant database from an Excel Macro that I have written. The macro would essentially need to find data in a specific field searching on another field. Example: For ID="2", return data in field "Name". Does anyone know how this is possible?
Thanks.
Edit: I have posted an answer to my own question. The answer I posted gets all docs from a specified database. From here you can query, etc. to get the specific data you are looking for. You can also use an excel macro JSON parser, found here to help sort through the data. The Base64Encoder I used can be found here.
From the documentation:
All requests to Cloudant go over the web, which means any system that can speak to the web, can speak to Cloudant. All language-specific libraries for Cloudant are really just wrappers that provide some convenience and linguistic niceties to help you work with a simple API.
Now, to your question:
Does anyone know if/how this is possible?
VBA capable of sending and receiving HTTP requests, ergo, this is possible using Excel (or any other application that can run VBA).
In case anyone else ever searches for this, I figured I would upload an actual response to this question (nearly a month later) rather than just a "yes, this is possible".
Since Cloudant requires Basic Auth, the way that I have found to do this is below:
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
Dim response As String
'Sameple URL: https://ibmcds.cloudant.com/sandbox/_all_docs
URL = "https://" + CloudantUsername + ".cloudant.com/" + DatabaseName + "/_all_docs"
With objHTTP
.Open "GET", URL, False
.SetRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
.SetRequestHeader "Content-Type", "application/json"
.SetRequestHeader "Accept", "application/json"
.SetRequestHeader "Authorization", "Basic " + Base64Encode(CloudantUsername + ":" + CloudantPassword)
.Send ("")
End With
response = objHTTP.responseText
In this example, the Base64Encode function just encodes the given string. You can use any Base64 Encoder for this.
And if you want to check the status of the request you can use:
If objHTTP.Status = 200 Then
response = objHTTP.responseText
MsgBox "This request is valid.", vbOKOnly
Else
MsgBox "This request is not valid.", vbOKOnly
End If
Or something similar.
I hope this helps anyone else who may be looking to do something like this.
Related
I am trying to retrive some using XHR in VBA. When I am sending a query I get popup window that webpage is trying to open a page from my trusted site list: "https://microsoftonline.com".
I click "Yes" and get "Access denied" error from VBA.
Page which I am trying to query is using my microsoft 356 account to authenticate. How can I send a authetincation post before sending POST quesry to my webpage. I am trying to get some information and I think there i as token which I can send for authetication. Where can I find token connected to my miscrosoft 356 account?
Thank you and apperciate your support!
Here is my code
query = "ItemNos=" & "9611311588" & "%0D%0A&Description=&Quantity=1&StockCode=&SelectedSupplier=&action%3Alist="
url = "https://itemavailability.alfalaval.com/"
xmlhttp.Open "POST", url, False
xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xmlhttp.send query
Debug.Print xmlhttp.responseText
html.body.innerHTML = xmlhttp.responseText
So, I have this spreadsheet with a list of about 5000 URLs. (All pages on our corporate intranet.)
We know some of the links are broken, but don't know of a good way to determine which without clicking all 5000 links.
Normally this would be a simple matter: Create a web page with links to the 5000 pages, and then check the links with a tool like Xenu Link Sleuth.
But that won't work in this case because many of the links are being redirected, and the redirect code spoofs HTTP.response 200, which tricks Xenu into treating it as a valid URL.
However, there is some good news: The redirect script does not run from within Excel. If you click a bad link inside Excel, the redirect script does not execute and the HTTP response is reported back to Excel. I believe Excel should be able to identify the correct HTTP response code (404) - or at least whether the link was valid or not.
Which brings me to my question:
Is there a way using VBA to write a script that would click through every link and capture the result? The result captured could be in the form of the HTTP response code or anything else you think would be useful in finding the bad links in this list of 5000 pages. Ideally the result would be written to a cell in the spreadsheet adjacent to the link.
If anyone if familiar enough with VBA to suggest a solution to this problem, I would be eternally grateful!
Here is an example to check the status line from a list of URL with Excel:
Sub TestLinks()
Dim source As Range, req As Object, url$
Set req = CreateObject("Msxml2.ServerXMLHTTP.6.0")
' define were the links and results are
Set source = Range("A1:B2")
' clear the results
source.Columns(2).Clear
' iterate each row
For i = 1 To source.Rows.count
' get the link from the first column
url = source.Cells(i, 1)
' send the request using a HEAD to check the status line
req.Open "HEAD", url, False
req.setRequestHeader "Accept", "image/webp,image/*,*/*;q=0.8"
req.setRequestHeader "Accept-Language", "en-GB,en-US;q=0.8,en;q=0.6"
req.setRequestHeader "Accept-Encoding", "gzip, deflate"
req.setRequestHeader "Cache-Control", "no-cache"
req.setRequestHeader "Content-Type", "text/xml; charset=utf-8"
req.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36"
req.Send
' write the result in the second column
source.Cells(i, 2) = req.Status
Next
MsgBox "Finished!"
End Sub
Use a user defined function to return HTML-Status Codes and drag it down next to the links. Might take a while for Excel to check 5000 links, though.
Public Function CheckURL(url As String) As String
Dim request As New WinHttpRequest
request.Open "GET", url
request.Send
CheckURL = request.Status
End Function
You will probably need to add a reference to "Microsoft WinHTTP Services" under "Extras" -> "References"
I am new to VBA so this is probably my problem. I am trying to perform a HTTP POST from Excel to a web service, and I can POST quite happily, until I change the code so that I am posting content in my message, at which point I get the following error:
Run-time error '-2147024809 (80070057)':
The Parameter is incorrect.
My code is as follows:
Dim oHttp As Object
Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")
Call oHttp.Open("POST", url, False)
oHttp.setRequestHeader "Content-Type", "application/text"
oHttp.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
Call oHttp.send(content)
httpPOST = oHttp.responseText
The line which is killing the code is the oHttp.send - if I do not pass any content then it is fine, as soon as I put content here it is unhappy.
The content parameter is a large string containing comma separated text and includes line feeds. I think this is why it is unhappy, if I change the string to simply a short "Hello" then the send is sucessful and the application happily makes it to the next line, before hitting the run-time error:
The data necessary to complete this operation is not yet available
So I guess my question is, how do I POST a large block of text to a server?
Thanks
Thanks for the comments, I managed to get it to work by converting the string to a binary array and then send the binary array over.
The following Excel macro, which is making an xmlhttp request to this webpage to retrieve some values at a second stage, has worked normally in VBA until some time ago:
Sub WebReq()
Link = "http://it.finance.yahoo.com/q?s=^FCHI&ql=10" & str(rnd())
Set htm = CreateObject("htmlFile")
Set RequestWeb = CreateObject("msxml2.xmlhttp")
With RequestWeb
.Open "GET", "" & Link & "", False
.send
htm.body.innerhtml = .responsetext
End With
End Sub
Now, instead, at the call of the method:
.send
of the object msxml2.xmlhttp is raising the following error:
Run-time error '-2147024891 (80070005)'
Access is denied.
I've been looking on the web but all the similar threads are never answered. Can anyone explain me what this error means, and if there's any way I could fix it or even just work around it?
Note: the random string at the end of the variable 'Link' has been added to force the page reloading, since the script is retrieving real-time values and so it should be loaded every time.
Additional information: while looking for a solution, I'm noticing now that the random part of the link is yielding always the same value even when I end the running and restart again:
Link = http://it.finance.yahoo.com/q?s=^FCHI&ql=10 .7055475
Why is this happening? Shouldn't rnd() yield a new random value between 0 and 1 at every call?
Use
CreateObject("MSXML2.ServerXMLHTTP.6.0")
The standard request fired from a local machine forbids access to sites that aren't trusted by IE. MSXML2.ServerXMLHTTP.6.0 is the server-side object, that doesn't perform those checks.
i found that, in my case, changing http to https fixed the access denied problem. i can only assume that the website somehow made a change and didn't tell anyone
access denied is IE issue
internet options > security tab > custom security level > Miscellaneous >Access data sources across domains > enable
Update
Sub WebReq()
link = "http://it.finance.yahoo.com/q?s=^FCHI&ql=10" & Str(Rnd())
Set htm = CreateObject("htmlFile")
Dim objHttp
Set objHttp = CreateObject("Msxml2.ServerXMLHTTP")
objHttp.Open "GET", link, False
objHttp.Send
htm.body.innerhtml = objHttp.responsetext
Set objHttp = Nothing
End Sub
This works for me:
With CreateObject("MSXML2.ServerXMLHTTP.6.0")
.Open "GET", URL, False
.Send
content = .ResponseText
End With
In my case the user didn't have AD permissions to the proxy server on our corporate network. (Simple oversight when setting up the user.) Adding the missing security group fixed the problem for the user.
I was able to fix it by changing the link being passed from being "http://" to "https://"
The site I was pulling had upgraded and trying to pull the data using the unsecured link was failing. Works great now (no code change required.
add "www" after "https://" in your custom Link,
Like this:
XMLPage.Open "GET", "https://www.x-rates.com/table/?from=GBP&amount=3", False
XMLPage.send
I'm afraid I don't understand exactly why this problem occurs, but I'm guessing it is the secure "https://" versus insecure "http://". I ran into the same "access denied" message while following sample code from a VBA course. The original code was:
XMLPage.Open "GET", "http://x-rates.com/table/?from=GBP&amount=3", False
XMLPage.send
I changed the "http://" to "https://" and the error went away.
I am trying to update an old ASP classic Twitter program that my work currently uses to use the new OAUTH. I am not an ASP programmer but I managed to find the ASPTwitter library posted online by Tim Acheson at http://www.timacheson.com/Blog/2013/jun/asptwitter
Everything works, as we have our own code searching our database and passing on a built string to the ASPTwitter code to tweet.
The catch is that it will fail with the
{"errors":[{"message":"Could not authenticate you","code":32}]}
error message if there is so much as a "." period in the string. Every possible special character besides letters and numbers causes a fail.
We have many posts that will include various symbols as well as URLs.
I have searched all over and have not been able to find a solution. Comments on Tim's site have mentioned it but no solutions yet. Everyone here has been very helpful so I was hoping someone might have a solution.
I can't post the code as there are about 6 files and I don't know which one is causing the issue.
Thank you so much for the help!
Edit:
This is a block of the 300+ line file where the issue happens, I hope that the cause can be found here too.
' Gets bearer token for application-only authentication from Twitter API 1.1.
' Application-user authentication: https://dev.twitter.com/docs/auth/using-oauth
' and: https://dev.twitter.com/docs/auth/authorizing-request
' API endpoint statuses/update (post a tweet): https://dev.twitter.com/docs/api/1.1/post/statuses/update
Private Function UpdateStatusJSON(sStatus)
Dim sURL : sURL = API_BASE_URL + "/1.1/statuses/update.json"
Dim oXmlHttp: Set oXmlHttp = Server.CreateObject("MSXML2.ServerXMLHTTP")
oXmlHttp.open "POST", sURL, False
sStatus = "this is from the ASPTwitter dot asp file"
oXmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"
oXmlHttp.setRequestHeader "User-Agent", "emiratesjobpost.com"
oXmlHttp.setRequestHeader "Authorization", "OAuth " & GetOAuthHeader(sURL, sStatus)
oXmlHttp.send "status=" & Server.URLEncode(sStatus) ' Encoded spaces as + in request body.
UpdateStatusJSON = oXmlHttp.responseText
Set oXmlHttp = Nothing
REM: A JSON viewer can be useful here: http://www.jsoneditoronline.org/
' To fix error message "Read-only application cannot POST" go to your application's "Application Type" settings at dev.twitter.com/apps and set "Access" to "Read and Write".
' After changing access to read/write you must click the button to generate new auth tokens and then use those.
Response.Write "<textarea cols=""100"" rows=""3"" >" & UpdateStatusJSON & "</textarea>" : Response.Flush()
End Function
If I replace the "dot" with "." in the "sStatus" line, it breaks
Do your pages use UTF-8 encoding? Open them in Notepad, select save as from the file menu, and if ansi coding is selected then change it to UTF-8.
See this link for more things you can do
http://www.hanselman.com/blog/InternationalizationAndClassicASP.aspx