Excel VBA - Accessing transit_details array from Google directions API using XML - vba

I am accessing the Google Directions API from Excel using VBA. I would like to be able to access the transit_details array in the Google directions API when retrieving transit directions using XML from VBA so I can get number of stops etc. At the moment I have code that gives me basic directions but I don't get stop numbers etc for transit directions:
The following is the Google Directions API webpage: https://developers.google.com/maps/documentation/directions/
'Get Directions
For Each nodeRoute In .SelectSingleNode("//route/leg").ChildNodes
If nodeRoute.BaseName = "step" Then
strInstructions = strInstructions & nodeRoute.SelectSingleNode("html_instructions").text & " - " & nodeRoute.SelectSingleNode("distance/text").text & vbCrLf
End If
Next
strInstructions = CleanHTML(strInstructions) 'Removes MetaTag information from HTML result to convert to plain text.
Else
strError = .SelectSingleNode("//status").text
GoTo errorHandler
End If
End With

Sounds like you need an XML Parser for VBA so that you can reference the XML with it's native structure. I'm not sure if there's XML parsers for VBA, I'll look when I get home from work (no time now)

Related

Applying a formula to Get From Web URL with VBA Macro

I'm trying to find a way to apply a formula to a get data from web url.
So the url will look like:
http://www.thisurl.com/formula/restOfTheUrl
I'm new to this, so I tried recording the macro using the Advanced Get From Web function and breaking out the elements of the URL from there and substituting the formula in.
So the section of the code looked like this
Source = Xml.Tables(Web.Contents(""http://www.thisurl.com/"" & text(0.123456,2) & ""/restOfTheUrl""))
Had it worked, the number 2 would have been substituted in place of text(0.123456,2).
Is there another way to do this?
Try,
Source = Xml.Tables(Web.Contents("http://www.thisurl.com/" & mid("0.123456", 4, 1) & "/restOfTheUrl"))
'possibly (your sample contradicts your code)
Source = Xml.Tables(Web.Contents("http://www.thisurl.com/" & mid("0.123456", 4, 1) & "restOfTheUrl"))

Generating QR Code in Mac VBA

I'm trying to crate and display a whole series of QR codes (200+) in an excel sheet running on Mac. The first solution given by Patratacus found on Generating 2D (PDF417 or QR) barcodes using Excel VBA takes a long time to run so many codes and because the QR Codes are made up of multiple shapes the screen refresh becomes really slow with 200+ QR codes on one sheet.
So, I have got the code working on PC using #Luiz solution found at Generating 2D (PDF417 or QR) barcodes using Excel VBA but unfortunately it doesn't seem to work on Mac.
With the code:
sURL = "https://api.qrserver.com/v1/create-qr-code/?" + "size=" + Trim(Str(size)) + "x" + Trim(Str(size)) + "&color=" + color + "&bgcolor=" + bgcolor + "&data=" + data
Debug.Print sURL
Set pic = ActiveSheet.Pictures.Insert(sURL + sParameters)
SURL + sParameters - seems to return the raw data of the image from the API https://api.qrserver.com/v1/create-qr-code/?. So I have been able to get a Mac shell script to return the same raw data I think using:
sResult = execShell(= "curl --get -d """ & "size=" + Trim(Str(size)) + "x" + Trim(Str(size)) + "&color=" + color + "&bgcolor=" + bgcolor + "&data=" + data & """" & " " & "https://api.qrserver.com/v1/create-qr-code/?")
However, if you insert the returned string into:
ActiveSheet.Pictures.Insert()
On mac it doesn't seem to work either. So my guess is that on Mac ActiveSheet.Pictures.Insert() is not able to read raw image data and only a path and file name to a picture file.
So I think our options are:
Find a why to display a picture on an excel sheet using the raw data returned by the API or
Find a way to save the raw data returned by the API as a picture file on Macs file system and then open that file using excels ActiveSheet.Pictures.Insert() code.
Here is a link to the API documentation page: http://goqr.me/api/doc/create-qr-code/
I hope what I wrote above make some sense as I probably don't have all the terminology correct. I'm quite new to working with APIs etc.

Map.DataBinding.LoadSettings not working for HTTPS

I have a lookup function in Excel (2010) that maps to a google for getting zip code data. I have some cells with formulas to look up against the XML data remotely: I have one cell named ZipCode. The code below updates city and state based on a newly typed zip code.
Here is the code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row = [ZipCode].Row And Target.Column = [ZipCode].Column Then
Dim Zip As String: Zip = [ZipCode].Value
If Len(Zip) <> 5 Or Not IsNumeric(Zip) Then
MsgBox "Please enter a valid zip code!", vbCritical, "Invalid Zip"
Exit Sub
End If
Dim Map As XmlMap
Set Map = ActiveWorkbook.XmlMaps(1)
Map.DataBinding.LoadSettings "https://maps.googleapis.com/maps/api/geocode/xml/?address=" & Zip & "&sensor=false"
Map.DataBinding.Refresh
End If
End Sub
The routine fails at:
Map.DataBinding.LoadSettings "https://maps.googleapis.com/maps/api/geocode/xml/?address=" & Zip & "&sensor=false"
with the following runtime error
runtime error -214721376 (80041020) The system could not locate the object specified.
I am not having much luck in understanding why it is failing. Any help would be appreciated.
The URL is incorrect:
https://maps.googleapis.com/maps/api/geocode/xml/?address=
The URL should be:
https://maps.googleapis.com/maps/api/geocode/xml?address=
(also the sensor parameter is no longer required)
I'm no expert...but I know the video you are watching and I got this error. You aren't specifying to excel the proper xml source. Your code is perfect as per the video, but my guess is that you messing up here:
Set Map = ActiveWorkbook.XmlMaps(1)
This may not be referring to the correct xmlmap. I would suggest deleting the source files and reloading the xml map again.

Web-Crawler for VBA

I am trying to program a Webcrawler, using Visual Basic. I have a list with links, stored in an Excel (column 1). The Macro should then open each link and add certain information from the website to the excel file.
Here's the first link (stored in field A2).
The Macro should identify and insert the name of the hotel into column 2 (B2), the rating in column 3 (C2) and the address in column 4 (D2). This process could then be repeated with a loop for all other links (all websites have the same structure).
My code so far (I did not add the loop yet):
Sub Hoteldetails()
Dim IEexp As Object
Set IEexp = CreateObject("InternetExplorer.Application")
IEexp.Visible = True
Range("A2").Select
Selection.Hyperlinks(1).Follow NewWindow:=False, AddHistory:=True
End Sub
How can I "select" the specific data I want and insert it into the excel file? I tried to record the macro via "Add Data", but was not able to import the data from the website. I also tried to do it by using various example codes, but it did not work out for my specific website.
Thanks a lot for any assistance!
tl;dr;
I am not going to do all the work for you but this is fairly easy if the pages have the same structure.
You can issue a browserless XMLHTTP request, to get a nice fast response, and then select the items of interest using either id or classname and collection index.
Here is an example, using the link you provided, which you can adapt into a loop over all links.
Webpage view:
Code output:
VBA:
Option Explicit
Public Sub GetInfo()
Dim sResponse As String, HTML As New HTMLDocument
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", "https://www.tripadvisor.co.uk/Hotel_Review-g198832-d236315-Reviews-Grand_Hotel_Kronenhof-Pontresina_Engadin_St_Moritz_Canton_of_Graubunden_Swiss_Alps.html", False
.send
sResponse = StrConv(.responseBody, vbUnicode)
End With
sResponse = Mid$(sResponse, InStr(1, sResponse, "<!DOCTYPE "))
With HTML
.body.innerHTML = sResponse
Debug.Print "HotelName: " & .getElementById("HEADING").innerText
Debug.Print "Address: " & .getElementsByClassName("detail")(0).innerText
Debug.Print "Rating: " & .getElementsByClassName("overallRating")(0).innerText
End With
End Sub
References:
VBE > Tools > References > HTML Object Library
You have several options:
Option 1: IEObject
Either you need to use the getElementBy methods in IEObject and use string manipulation to extract the data you need. 2 options for string extractions:
Extracting a top-level element by Name or by Id then use string manipulation functions such as Mid, InStr, Left and Right
Use Regex (VBA Vbscript object) to extract the data (recommended)
Option 2: Scrape HTML Add-In
Sometime ago I developed an AddIn for Excel that allows you to easily scrape HTML data within an Excel formula. The process is similar as above as you still need to create a relevant Regex. See an example below for TripAdvisor:
The formula in B2 looks like this (A2 is the link, and the second argument is the Regex):
=GetElementByRegex(A2;"<h1 id=""HEADING"".*?>(?:(?:.|\n)*?)</div>((?:.|\n)*?)</h1>")
You can download the AddIn here:
http://www.analystcave.com/excel-tools/excel-scrape-html-add/

How to loop and write all HTTp Header name/value pairs

I am working on a vb.net 2.0 application and trying to read HTTP headers. I am able to get header values through Request.Headers.Get("HTTP_VARIABLE_NAME"). I would like to get all header name/value pairs using Headers property and display on a separate page under a button click event from a given page.
How can I loop and write all name/value pairs please?
Taken directly from MSDN, so all credit goes to the poor Microsoft employee who was given the rough task of documenting the system.net namespace. Although I do feel like I could write a better example myself...
The following code example displays the names and values of all headers in the HTTP request
Dim loop1, loop2 As Integer
Dim arr1(), arr2() As String
Dim coll As NameValueCollection
' Load Header collection into NameValueCollection object.
coll=Request.Headers
' Put the names of all keys into a string array.
arr1 = coll.AllKeys
For loop1 = 0 To arr1.GetUpperBound(0)
Response.Write("Key: " & arr1(loop1) & "<br>")
arr2 = coll.GetValues(loop1)
' Get all values under this key.
For loop2 = 0 To arr2.GetUpperBound(0)
Response.Write("Value " & CStr(loop2) & ": " & Server.HtmlEncode(arr2(loop2)) & "<br>")
Next loop2
Next loop1
I don't know what you mean by "write to a page", but this should get you started.
Is there a reason that forces you to use .NET 2? .NET 4 is still supported on Windows XP SP3 and up and offers many advantages over previous versions. Just putting it out there.