I made the switch to Mac and now some of my old Excel macros that are depended on the operating system do not work. One particular item is the ability to fetch data from the Web. So here I am after many years using Office and Excel learning again. This is fun!
Ok, let’s get series now…Today’s goal is to build a user defined function that can be called from the Excel datasheet and fetch a web page. We will call that function getHTTP and it will work on Mac (but not on Windows).
Luck is on my side as there are many others looking for the same solution. I found an entry called “How do I issue an HTTP GET from Excel VBA for Mac 2011” (See it here) and it has exactly what we need.
Navigation in Excel on Mac is just a little bit different so here are steps by step instructions:
1. Open an Excel file or create a new one.
2. Save as “Excel Macro-Enabled Workbook (.xlsm)” file.
3. From the menu navigate to Tools->Macro->Macros…
4. In the “Macro Name:” field type the name of the new Macro we want to create. In this case getHTTP. You should see a screen like this:
5. Click “Create” and you will find yourself in the VBA editor with an empty Sub called getHTTP.
6. Next we will copy paste the VBA code from below (taken from the link at stackoverflow listed above with minor change of the function name from HTTPGet to getHTTP just cause I like this format better):
' execShell() function courtesy of Robert Knight via StackOverflow
Private Declare Function popen Lib "libc.dylib" (ByVal command As String, ByVal mode As String) As Long
Private Declare Function pclose Lib "libc.dylib" (ByVal file As Long) As Long
Private Declare Function fread Lib "libc.dylib" (ByVal outStr As String, ByVal size As Long, ByVal items As Long, ByVal stream As Long) As Long
Private Declare Function feof Lib "libc.dylib" (ByVal file As Long) As Long
Function execShell(command As String, Optional ByRef exitCode As Long) As String
Dim file As Long
file = popen(command, "r")
If file = 0 Then
While feof(file) = 0
Dim chunk As String
Dim read As Long
chunk = Space(50)
read = fread(chunk, 1, Len(chunk) - 1, file)
If read > 0 Then
chunk = Left$(chunk, read)
execShell = execShell & chunk
exitCode = pclose(file)
Function getHTTP(sUrl As String, sQuery As String) As String
Dim sCmd As String
Dim sResult As String
Dim lExitCode As Long
sCmd = "curl --get -d """ & sQuery & """" & " " & sUrl
sResult = execShell(sCmd, lExitCode)
' ToDo check lExitCode
getHTTP = sResult
7. And we are ready to give it a try… Leave the VBA editor and return to the Excel sheet.
8. Let’s put in cell A2 the value: http://api.openweathermap.org/data/2.1/forecast/city
9. Let’s pub in cell B2 the value: q=Boston
10. Let’s pub in cell C2 the value: =getHTTP(A2,B2)
11. The page should refresh and you should see a lot of gibberish JSON things. Something like this:
This is what we wanted! We are done!