FlightCaster API examples in VBA

flightcaster logo

FlightCaster is a web application that offers information on flight delays. According to FlightCaster,

FlightCaster predicts flight delays. We use an advanced algorithm that scours data on every domestic flight for the past 10-years and matches it to real-time conditions.

That means you can use their site to guess if your flight (or that of your loved ones) is going to be on time. Here's a colorful sample. You can also check on airport weather and ground delays imposed by the FAA.

The site offers a web API you can use to consume flight data in your programs. That's why we're here, right?

As with other web APIs, you'll need a key to use their service. I have an API key, but in the examples below it has been removed. Get one!

Note: This article is very long so if you're not in the mood to scroll through hundreds of lines of VBA, you may want to read it at another time. If you happen to work for FlightCaster, read my Open Letter.

Like the other web API examples found here(Wordnik, Australian post codes, Delicious RSS feeds), these functions use similar techniques: call the web API, cache the response, load and parse it using the MSXML object model. Note that I didn't enumerate all the available methods. See the API documentation for all the data you can pull from the API.

When using the FlightCaster API, make sure you use the right flight identifier:

IATA issues 'controlled duplicates', so it is recommended that the ICAO identifier be used. Controlled duplicates are issued to regional airlines who do not operate in the same air space.

Note: This code uses the FlightCaster API but is not endorsed or certified by FlightCaster. Nor should the use of their logo imply endorsement. And for the record, that is true of any code found here. Any code that uses the fill-in-the-blank API is not endorsed or certified by fill-in-the-blank.

Also, don't forget to paste the helper functions into a standard module in the same project.

Get Airline Information

Pass in your API key and this function returns the following about each airline:

  • callsign
  • country
  • IATA code
  • ICAO code
  • ID number
  • airline name
Function GetAirlines(apiKey As String, Optional page As Long = 1, _
                     Optional resultsPerPage As Long = 30) As String()
' default for FlightCaster is 30 results

Dim xml As Object ' MSXML2.XMLHTTP
Dim tempFile As String
Dim tempString() As String
Dim result As String
Dim i As Long, j As Long
Dim numRows As Long
Dim numCols As Long
Dim xmlDoc As Object ' MSXML2.DOMDocument
Dim xmlDocRoot As Object ' MSXML2.IXMLDOMNode
Dim airlines As Object ' MSXML2.IXMLDOMNodeList
Dim airline As Object ' MSXML2.IXMLDOMNode
Dim airlineSubNodes As Object ' MSXML2.IXMLDOMNodeList
Dim airlineSubNode As Object ' MSXML2.IXMLDOMNode

Const TEMP_FILENAME As String = "GetAirlines"
Const XML_FILE_EXTENSION As String = ".xml"

  ' if XML file exists, don't requery website
  tempFile = environ("temp") & "\" & TEMP_FILENAME & XML_FILE_EXTENSION

  If Len(Dir(tempFile)) = 0 Then

    Set xml = CreateObject("MSXML2.XMLHTTP.6.0")

    With xml
      .Open "GET", "http://api.flightcaster.com/airlines.xml?api_key=" & _
    apiKey & "&api_version=0.1.1&page=" & page & "&per_page=" & resultsPerPage, False
      .send
    End With

    result = xml.responseText

    ' save result as temp XML document
    tempFile = CreateFile(tempFile, result)

  End If

  ' load XML file into new XML document
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

  With xmlDoc
    .async = False
    .validateOnParse = False
    .Load tempFile
  End With

  ' check that the XML doc loaded
  If LoadError(xmlDoc) Then
    Exit Function
  End If

  ' get root node
  Set xmlDocRoot = GetRootNode(xmlDoc)

  ' get first level child nodes
  Set airlines = GetChildNodes(xmlDocRoot)

  ' resize array
  numRows = airlines.Length
  numCols = airlines.item(0).childNodes.Length
  ReDim tempString(1 To numRows, 1 To numCols)

  ' get second level child nodes
  For i = 0 To numRows - 1
    Set airline = airlines.item(i)

    For j = 0 To numCols - 1
      Set airlineSubNode = airline.childNodes.item(j)

      tempString(i + 1, j + 1) = airlineSubNode.nodeTypedValue

    Next j
  Next i

  GetAirlines = tempString

End Function

To check the number of entries, use

xmlDocRoot.attributes.getNamedItem("total-entries").nodeTypedValue

and for the number of pages, check

xmlDocRoot.attributes.getNamedItem("total-pages").nodeTypedValue

Sample usage

This sample procedure returns the first five airlines in the FlightCaster database.

Sub TestFlightCaster()

Dim apiKey As String
Dim numberOfResults As Long
Dim results() As String
Dim i As Long

  apiKey = "your API key here"
  numberOfResults = 5

  results = GetAirlines(apiKey, , numberOfResults)

  For i = 1 To numberOfResults
    Debug.Print results(i, 1)
  Next i
End Sub

Get Information for specific airline

Using the ICAO ID you returned from the GetAirlines function, pass it (and your API key) to the GetAirline function to return information about a specific airline. The function returns the same information as GetAirlines, except for a single airline only.

  • callsign
  • country
  • IATA code
  • ICAO code
  • ID number
  • airline name
Function GetAirline(apiKey As String, ID As String) As String()

Dim xml As Object ' MSXML2.XMLHTTP
Dim tempFile As String
Dim uIdentifier As String
Dim tempString() As String
Dim result As String
Dim i As Long
Dim numCols As Long
Dim xmlDoc As Object ' MSXML2.DOMDocument
Dim xmlDocRoot As Object ' MSXML2.IXMLDOMNode
Dim airlines As Object ' MSXML2.IXMLDOMNodeList
Dim airline As Object ' MSXML2.IXMLDOMNode

Const TEMP_FILENAME As String = "GetAirline"
Const XML_FILE_EXTENSION As String = ".xml"

  ' if XML file exists, don't requery website
  uIdentifier = UCase$(ID)
  tempFile = environ("temp") & "\" & uIdentifier & XML_FILE_EXTENSION

  If Len(Dir(tempFile)) = 0 Then

    Set xml = CreateObject("MSXML2.XMLHTTP.6.0")

    With xml
      .Open "GET", "http://api.flightcaster.com/airlines/" & uIdentifier & _
    ".xml?api_key=" & apiKey & "&api_version=0.1.1", False
      .send
    End With

    result = xml.responseText

    ' save result as temp XML document
    tempFile = CreateFile(tempFile, result)

  End If

  ' load XML file into new XML document
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

  With xmlDoc
    .async = False
    .validateOnParse = False
    .Load tempFile
  End With

  ' check that the XML doc loaded
  If LoadError(xmlDoc) Then
    Exit Function
  End If

  ' get root node
  Set xmlDocRoot = GetRootNode(xmlDoc)

  ' get first level child nodes
  Set airlines = GetChildNodes(xmlDocRoot)

  ' resize array
  numCols = airlines.Length
  ReDim tempString(1 To numCols)

  For i = 0 To numCols - 1
    ' get second level child nodes
    Set airline = airlines.item(i)

    tempString(i + 1) = airline.nodeTypedValue

  Next i

  GetAirline = tempString

End Function

Sample usage

This procedure returns the airline information for Chautauqua Airlines (ICAO ID: CHQ), which operates in the U.S.

Sub TestFlightCaster()

Dim apiKey As String
Dim identifier As String
Dim results() As String
Dim i As Long

  apiKey = "your API key here"
  identifier = "CHQ"

  results = GetAirline(apiKey, identifier)

  For i = 1 To UBound(results)
    Debug.Print results(i)
  Next i
End Sub

Using this we can write a procedure that accepts any ICAO ID and returns the name of the airline:

Function GetAirlineName(ICAO As String) As String

Dim apiKey As String
Dim identifier As String
Dim results() As String
Dim i As Long

  apiKey = "your API key here"
  identifier = ICAO

  results = GetAirline(apiKey, identifier)

  GetAirlineName = results(UBound(results))
End Sub

Return flight information for a specific airline

The following function returns a wealth of information about available flights for a given airline. In this case I chose to return all available data points.

  • ID
  • Flightstats ID (for use with FlightStats)
  • Number
  • airline ICAO ID
  • origin ICAO ID
  • destination ICAO ID
  • diverted ICAO ID (if applicable)
  • published arrival time
  • published departure time
  • date created
  • date updated

And what you were all waiting for: on time probability

  • On Time
  • 60 minutes late
  • More than one hour late

In all, there are fourteen data points for each flight.

Function GetFlightsPerAirlineID(apiKey As String, ID As String, Optional page As Long = 1, _
                                Optional resultsPerPage As Long = 30, Optional forceRequery As Boolean = False) As String()

Dim xml As Object ' MSXML2.XMLHTTP
Dim tempFile As String
Dim tempString() As String
Dim result As String
Dim xmlDoc As Object ' MSXML2.DOMDocument
Dim xmlDocRoot As Object ' MSXML2.IXMLDOMNode
Dim flights As Object ' MSXML2.IXMLDOMNodeList
Dim subFlights As Object ' MSXML2.IXMLDOMNodeList
Dim flight As Object ' MSXML2.IXMLDOMNode
Dim i As Long, j As Long

Const TEMP_FILENAME As String = "GetFlightsPerAirlineID"
Const XML_FILE_EXTENSION As String = ".xml"

  ' if XML file exists or we force requery, don't requery website
  tempFile = environ("temp") & "\" & TEMP_FILENAME & ID & XML_FILE_EXTENSION

  If Len(Dir(tempFile)) = 0 Or forceRequery Then

    Set xml = CreateObject("MSXML2.XMLHTTP.6.0")

    With xml
      .Open "GET", "http://api.flightcaster.com/airlines/" & ID & "/flights.xml?api_key=" & apiKey & "&api_version=0.1.1&page=" & page & "&per_page=" & resultsPerPage, False
      .send
    End With

    result = xml.responseText

    ' save result as temp XML document
    Call CreateFile(tempFile, result)

  End If

  ' load XML file into new XML document
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

  With xmlDoc
    .async = False
    .validateOnParse = False
    .Load tempFile
  End With

  ' check that the XML doc loaded
  If LoadError(xmlDoc) Then
    Exit Function
  End If

  ' get root node
  Set xmlDocRoot = GetRootNode(xmlDoc)

  ' get first level child nodes
  Set flights = GetChildNodes(xmlDocRoot)

  ' resize array
  ' each node has 14 data points to extract
  ReDim tempString(1 To flights.Length, 1 To 14)

  For i = 1 To flights.Length

    Set flight = flights.item(i - 1)

    ' for the first 11 nodes, loop as usual
    ' for the last node, loop through it
    For j = 1 To flight.childNodes.Length
      Select Case j
        Case Is < 12
          tempString(i, j) = flight.childNodes(j - 1).nodeTypedValue
        Case Else
          Set subFlights = flights.item(j).childNodes
          tempString(i, j) = subFlights.item(j - 1).childNodes(0).nodeTypedValue
          tempString(i, j + 1) = subFlights.item(j - 1).childNodes(1).nodeTypedValue
          tempString(i, j + 2) = subFlights.item(j - 1).childNodes(2).nodeTypedValue
      End Select
    Next j
  Next i

  GetFlightsPerAirlineID = tempString

End Function

To check the number of entries, use

xmlDocRoot.attributes.getNamedItem("total-entries").nodeTypedValue

and for the number of pages, check

xmlDocRoot.attributes.getNamedItem("total-pages").nodeTypedValue

Sample usage

Let's again use Chautauqua Airlines (ICAO ID: CHQ) as an example.

Sub TestFlightCaster()

Dim apiKey As String
Dim results() As String
Dim i As Long, j As Long

  apiKey = "your API key here"

  results = GetFlightsPerAirlineID(apiKey, "CHQ")
  For i = LBound(results) To UBound(results)
    For j = LBound(results, 2) To UBound(results, 2)
      Debug.Print results(i, j)
    Next j
  Next i
End Sub

Return airport information

This function will return information about all available airports. Each airport has 12 data points:

  • City
  • Country
  • Elevation
  • FAA ID
  • IATA ID
  • ICAO ID
  • ID (this is the FlightCaster ID)
  • Latitude
  • Longitude
  • Airport Name
  • State
  • Time zone

Run this function first to find out what airports are listed, and the ICAO ID for each.

Function GetAirports(apiKey As String, Optional page As Long = 1, _
                     Optional resultsPerPage As Long = 30) As String()

Dim xml As Object ' MSXML2.XMLHTTP
Dim tempFile As String
Dim tempString() As String
Dim result As String
Dim numRows As Long
Dim numCols As Long
Dim i As Long, j As Long
Dim xmlDoc As Object ' MSXML2.DOMDocument
Dim xmlDocRoot As Object ' MSXML2.IXMLDOMNode
Dim airports As Object ' MSXML2.IXMLDOMNodeList
Dim airport As Object ' MSXML2.IXMLDOMNode
Dim airportSubNodes As Object ' MSXML2.IXMLDOMNodeList
Dim airportSubNode As Object ' MSXML2.IXMLDOMNode

Const TEMP_FILENAME As String = "GetAirports"
Const XML_FILE_EXTENSION As String = ".xml"

  ' if XML file exists, don't requery website
  tempFile = environ("temp") & "\" & TEMP_FILENAME & XML_FILE_EXTENSION

  If Len(Dir(tempFile)) = 0 Then

    Set xml = CreateObject("MSXML2.XMLHTTP.6.0")

    With xml
      .Open "GET", "http://api.flightcaster.com/airports.xml?api_key=" & apiKey & "&api_version=0.1.1&page=" & page & "&per_page=" & resultsPerPage, False
      .send
    End With

    result = xml.responseText

    ' save result as temp XML document
    tempFile = CreateFile(tempFile, result)

  End If

  ' load XML file into new XML document
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

  With xmlDoc
    .async = False
    .validateOnParse = False
    .Load tempFile
  End With

  ' check that the XML doc loaded
  If LoadError(xmlDoc) Then
    Exit Function
  End If

  ' get root node
  Set xmlDocRoot = GetRootNode(xmlDoc)

  ' get first level child nodes
  Set airports = GetChildNodes(xmlDocRoot)

  ' resize array
  numRows = airports.Length
  numCols = airports.item(0).childNodes.Length
  ReDim tempString(1 To numRows, 1 To numCols)

  ' get second level child nodes
  For i = 0 To numRows - 1
    Set airport = airports.item(i)

    For j = 0 To numCols - 1
      Set airportSubNode = airport.childNodes.item(j)

      tempString(i + 1, j + 1) = airportSubNode.nodeTypedValue

    Next j
  Next i

  GetAirports = tempString

End Function

To check the number of entries, use

xmlDocRoot.attributes.getNamedItem("total-entries").nodeTypedValue

and for the number of pages, check

xmlDocRoot.attributes.getNamedItem("total-pages").nodeTypedValue

Sample usage

Sub TestFlightCaster()

Dim apiKey As String
Dim results() As String
Dim i As Long, j As Long

  apiKey = "your API key here"

  results = GetAirports(apiKey)
  For i = LBound(results) To UBound(results)
    For j = LBound(results, 2) To UBound(results, 2)
      Debug.Print results(i, j)
    Next j
  Next i
End Sub

Get individual airport information

This function will return the same information as GetAirports, but only about a single airport. Pass in your API key and either the FlightCaster ID (the "ID" field from GetAirports), the IATA ID or the ICAO ID.

Function GetAirport(apiKey As String, ID As String) As String()

Dim xml As Object ' MSXML2.XMLHTTP
Dim tempFile As String
Dim tempString() As String
Dim result As String
Dim i As Long
Dim xmlDoc As Object ' MSXML2.DOMDocument
Dim xmlDocRoot As Object ' MSXML2.IXMLDOMNode
Dim airports As Object ' MSXML2.IXMLDOMNodeList

Const TEMP_FILENAME As String = "GetAirport"
Const XML_FILE_EXTENSION As String = ".xml"

  ' if XML file exists, don't requery website
  tempFile = environ("temp") & "\" & TEMP_FILENAME & ID & XML_FILE_EXTENSION

  If Len(Dir(tempFile)) = 0 Then

    Set xml = CreateObject("MSXML2.XMLHTTP.6.0")

    With xml
      .Open "GET", "http://api.flightcaster.com/airports/" & ID & ".xml?api_key=" & apiKey & "&api_version=0.1.1", False
      .send
    End With

    result = xml.responseText

    ' save result as temp XML document
    tempFile = CreateFile(tempFile, result)

  End If

  ' load XML file into new XML document
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

  With xmlDoc
    .async = False
    .validateOnParse = False
    .Load tempFile
  End With

  ' check that the XML doc loaded
  If LoadError(xmlDoc) Then
    Exit Function
  End If

  ' get root node
  Set xmlDocRoot = GetRootNode(xmlDoc)

  ' get first level child nodes
  Set airports = GetChildNodes(xmlDocRoot)

  ' resize array
  ReDim tempString(1 To airports.Length)

  For i = 1 To airports.Length
    tempString(i) = airports.item(i - 1).nodeTypedValue
  Next i

  GetAirport = tempString

End Function

Here's a sample API response when using CHQ as an airport code:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;airport&gt;
  &lt;city&gt;Charleston&lt;/city&gt;
  &lt;country&gt;US&lt;/country&gt;
  &lt;elevation&gt;95&lt;/elevation&gt;
  &lt;faa-id&gt;CHQ&lt;/faa-id&gt;
  &lt;iata-id /&gt;
  &lt;icao-id&gt;KCHQ&lt;/icao-id&gt;
  &lt;id&gt;5882&lt;/id&gt;
  &lt;latitude&gt;36.8421372&lt;/latitude&gt;
  &lt;longitude&gt;-89.3596578&lt;/longitude&gt;
  &lt;name&gt;Mississippi County Airport&lt;/name&gt;
  &lt;state&gt;MO&lt;/state&gt;
  &lt;time-zone&gt;America/Chicago&lt;/time-zone&gt;
&lt;/airport&gt;

Sample usage

This example prints the airport information for airport IATA code CHQ (ICAO code KCHQ) to the Immediate Window.

Sub TestFlightCaster()

Dim apiKey As String
Dim results() As String
Dim i As Long

  apiKey = "your API key here"

  results = GetAirport(apiKey, "CHQ")
  For i = 1 To UBound(results)
    Debug.Print results(i)
  Next i
End Sub

Return flight information for a specific airline

This function returns the same information as GetFlightsPerAirlineID, including the on-time percentage. Just pass in the airport ID.

Function GetAirportArrivals(apiKey As String, ID As String, Optional page As Long = 1, _
                            Optional resultsPerPage As Long = 30, Optional forceRequery As Boolean = False) As String()

Dim xml As Object ' MSXML2.XMLHTTP
Dim tempFile As String
Dim tempString() As String
Dim result As String
Dim xmlDoc As Object ' MSXML2.DOMDocument
Dim xmlDocRoot As Object ' MSXML2.IXMLDOMNode
Dim flights As Object ' MSXML2.IXMLDOMNodeList
Dim subFlights As Object ' MSXML2.IXMLDOMNodeList
Dim flight As Object ' MSXML2.IXMLDOMNode
Dim i As Long, j As Long

Const TEMP_FILENAME As String = "GetAirportArrivals"
Const XML_FILE_EXTENSION As String = ".xml"

  ' if XML file exists or we force requery, don't requery website
  tempFile = environ("temp") & "\" & TEMP_FILENAME & ID & XML_FILE_EXTENSION

  If Len(Dir(tempFile)) = 0 Or forceRequery Then

    Set xml = CreateObject("MSXML2.XMLHTTP.6.0")

    With xml
      .Open "GET", "http://api.flightcaster.com/airports/" & ID & "/arrivals.xml?api_key=" & apiKey & "&api_version=0.1.1&page=" & page & "&per_page=" & resultsPerPage, False
      .send
    End With

    result = xml.responseText

    ' save result as temp XML document
    Call CreateFile(tempFile, result)

  End If

  ' load XML file into new XML document
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

  With xmlDoc
    .async = False
    .validateOnParse = False
    .Load tempFile
  End With

  ' check that the XML doc loaded
  If LoadError(xmlDoc) Then
    Exit Function
  End If

  ' get root node
  Set xmlDocRoot = GetRootNode(xmlDoc)

  ' make sure there are flights
  If xmlDocRoot.Attributes.getNamedItem("total-entries").nodeTypedValue = 0 Then
    MsgBox "No flights found", vbInformation
    Exit Function
  End If

  ' get first level child nodes
  Set flights = GetChildNodes(xmlDocRoot)

  ' resize array
  ' each node has 14 data points to extract
  ReDim tempString(1 To flights.Length, 1 To 14)

  For i = 1 To flights.Length

    Set flight = flights.item(i - 1)

    ' for the first 11 nodes, loop as usual
    ' for the last node, loop through it
    For j = 1 To flight.childNodes.Length
      Select Case j
        Case Is < 12
          tempString(i, j) = flight.childNodes(j - 1).nodeTypedValue
        Case Else
          Set subFlights = flights.item(j).childNodes
          tempString(i, j) = subFlights.item(j - 1).childNodes(0).nodeTypedValue
          tempString(i, j + 1) = subFlights.item(j - 1).childNodes(1).nodeTypedValue
          tempString(i, j + 2) = subFlights.item(j - 1).childNodes(2).nodeTypedValue
      End Select
    Next j
  Next i

  GetAirportArrivals = tempString

End Function

To check the number of entries, use

xmlDocRoot.attributes.getNamedItem("total-entries").nodeTypedValue

and for the number of pages, check

xmlDocRoot.attributes.getNamedItem("total-pages").nodeTypedValue

Sample usage

This sample procedure returns all the flights arriving at LaGuardia Airport.

Sub TestFlightCaster()

Dim apiKey As String
Dim results() As String
Dim i As Long, j As Long

  apiKey = "your API key here"

  results = GetAirportArrivals(apiKey, "LGA")
  For i = LBound(results) To UBound(results)
    For j = LBound(results, 2) To UBound(results, 2)
      Debug.Print results(i, j)
    Next j
  Next i
End Sub

Return departures for a specific airport

This function returns the same information as GetAirportArrivals and GetFlightsPerAirlineID. Pass in the airport ID and it returns the departures for that airport.

Function GetAirportDepartures(apiKey As String, ID As String, Optional page As Long = 1, _
                              Optional resultsPerPage As Long = 30, Optional forceRequery As Boolean = False) As String()

Dim xml As Object ' MSXML2.XMLHTTP
Dim tempFile As String
Dim tempString() As String
Dim result As String
Dim xmlDoc As Object ' MSXML2.DOMDocument
Dim xmlDocRoot As Object ' MSXML2.IXMLDOMNode
Dim flights As Object ' MSXML2.IXMLDOMNodeList
Dim subFlights As Object ' MSXML2.IXMLDOMNodeList
Dim flight As Object ' MSXML2.IXMLDOMNode
Dim i As Long, j As Long

Const TEMP_FILENAME As String = "GetAirportDepartures"
Const XML_FILE_EXTENSION As String = ".xml"

  ' if XML file exists or we force requery, don't requery website
  tempFile = environ("temp") & "\" & TEMP_FILENAME & ID & XML_FILE_EXTENSION

  If Len(Dir(tempFile)) = 0 Or forceRequery Then

    Set xml = CreateObject("MSXML2.XMLHTTP.6.0")

    With xml
      .Open "GET", "http://api.flightcaster.com/airports/" & ID & "/departures.xml?api_key=" & apiKey & "&api_version=0.1.1&page=" & page & "&per_page=" & resultsPerPage, False
      .send
    End With

    result = xml.responseText

    ' save result as temp XML document
    Call CreateFile(tempFile, result)

  End If

  ' load XML file into new XML document
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

  With xmlDoc
    .async = False
    .validateOnParse = False
    .Load tempFile
  End With

  ' check that the XML doc loaded
  If LoadError(xmlDoc) Then
    Exit Function
  End If

  ' get root node
  Set xmlDocRoot = GetRootNode(xmlDoc)

  ' make sure there are flights
  If xmlDocRoot.Attributes.getNamedItem("total-entries").nodeTypedValue = 0 Then
    MsgBox "No flights found", vbInformation
    Exit Function
  End If

  ' get first level child nodes
  Set flights = GetChildNodes(xmlDocRoot)

  ' resize array
  ' each node has 14 data points to extract
  ReDim tempString(1 To flights.Length, 1 To 14)

  For i = 1 To flights.Length

    Set flight = flights.item(i - 1)

    ' for the first 11 nodes, loop as usual
    ' for the last node, loop through it
    For j = 1 To flight.childNodes.Length
      Select Case j
        Case Is < 12
          tempString(i, j) = flight.childNodes(j - 1).nodeTypedValue
        Case Else
          Set subFlights = flights.item(j).childNodes
          tempString(i, j) = subFlights.item(j - 1).childNodes(0).nodeTypedValue
          tempString(i, j + 1) = subFlights.item(j - 1).childNodes(1).nodeTypedValue
          tempString(i, j + 2) = subFlights.item(j - 1).childNodes(2).nodeTypedValue
      End Select
    Next j
  Next i

  GetAirportDepartures = tempString

End Function

To check the number of entries, use

xmlDocRoot.attributes.getNamedItem("total-entries").nodeTypedValue

and for the number of pages, check

xmlDocRoot.attributes.getNamedItem("total-pages").nodeTypedValue

Sample usage

This sample procedure returns all the flights arriving at LaGuardia Airport.

Sub TestFlightCaster()

Dim apiKey As String
Dim results() As String
Dim i As Long, j As Long

  apiKey = "your API key here"

  results = GetAirportDepartures(apiKey, "LGA")
  For i = LBound(results) To UBound(results)
    For j = LBound(results, 2) To UBound(results, 2)
      Debug.Print results(i, j)
    Next j
  Next i
End Sub

Get Flights From Specific Airports

Just like the other functions that return airline departures and flights (GetAirportDepartures

and GetAirportArrivals), this function also returns flight information, except you can specify the origin and destination airports. Otherwise it returns the same information, including on-time percentage.

Function GetFlightsToFromSpecificAirports(apiKey As String, fromAirport As String, toAirport As String, Optional page As Long = 1, _
                                          Optional resultsPerPage As Long = 30, Optional forceRequery As Boolean = False) As String()

Dim xml As Object ' MSXML2.XMLHTTP
Dim tempFile As String
Dim tempString() As String
Dim result As String
Dim xmlDoc As Object ' MSXML2.DOMDocument
Dim xmlDocRoot As Object ' MSXML2.IXMLDOMNode
Dim flights As Object ' MSXML2.IXMLDOMNodeList
Dim subFlights As Object ' MSXML2.IXMLDOMNodeList
Dim flight As Object ' MSXML2.IXMLDOMNode
Dim i As Long, j As Long

Const TEMP_FILENAME As String = "GetFlightsToFromSpecificAirports"
Const XML_FILE_EXTENSION As String = ".xml"

  ' if XML file exists or we force requery, don't requery website
  tempFile = environ("temp") & "\" & TEMP_FILENAME & fromAirport & toAirport & XML_FILE_EXTENSION

  If Len(Dir(tempFile)) = 0 Or forceRequery Then

    Set xml = CreateObject("MSXML2.XMLHTTP.6.0")

    With xml
      .Open "GET", "http://api.flightcaster.com/airports/" & fromAirport & "/departures/" & toAirport & ".xml?api_key=" & apiKey & "&api_version=0.1.1&page=" & page & "&per_page=" & resultsPerPage, False
      .send
    End With

    result = xml.responseText

    ' save result as temp XML document
    Call CreateFile(tempFile, result)

  End If

  ' load XML file into new XML document
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

  With xmlDoc
    .async = False
    .validateOnParse = False
    .Load tempFile
  End With

  ' check that the XML doc loaded
  If LoadError(xmlDoc) Then
    Exit Function
  End If

  ' get root node
  Set xmlDocRoot = GetRootNode(xmlDoc)

  ' make sure there are flights
  If xmlDocRoot.Attributes.getNamedItem("total-entries").nodeTypedValue = 0 Then
    MsgBox "No flights found", vbInformation
    Exit Function
  End If

  ' get first level child nodes
  Set flights = GetChildNodes(xmlDocRoot)

  ' resize array
  ' each node has 14 data points to extract
  ReDim tempString(1 To flights.Length, 1 To 14)

  For i = 1 To flights.Length

    Set flight = flights.item(i - 1)

    ' for the first 11 nodes, loop as usual
    ' for the last node, loop through it
    For j = 1 To flight.childNodes.Length
      Select Case j
        Case Is < 12
          tempString(i, j) = flight.childNodes(j - 1).nodeTypedValue
        Case Else
          Set subFlights = flights.item(j).childNodes
          tempString(i, j) = subFlights.item(j - 1).childNodes(0).nodeTypedValue
          tempString(i, j + 1) = subFlights.item(j - 1).childNodes(1).nodeTypedValue
          tempString(i, j + 2) = subFlights.item(j - 1).childNodes(2).nodeTypedValue
      End Select
    Next j
  Next i

  GetFlightsToFromSpecificAirports = tempString

End Function

To check the number of entries, use

xmlDocRoot.attributes.getNamedItem("total-entries").nodeTypedValue

and for the number of pages, check

xmlDocRoot.attributes.getNamedItem("total-pages").nodeTypedValue

Sample usage

This example prints the flight information for all flights leaving LaGuardia and landing at Dallas Fort Worth.

Sub TestFlightCaster()

Dim apiKey As String
Dim results() As String
Dim i As Long, j As Long

  apiKey = "your API key here"

  results = GetFlightsToFromSpecificAirports(apiKey, "LGA", "DFW")
  For i = LBound(results) To UBound(results)
    For j = LBound(results, 2) To UBound(results, 2)
      Debug.Print results(i, j)
    Next j
  Next i
End Sub

Return flight information from specific airports by date

This function allows you to further filter the list of available flights returned by GetFlightsToFromSpecificAirports. You can list flights by date. This will allow you to loop through a list of dates and call the function, returning the results to a listbox on a form.

The date must be formatted as follows: yyyymmdd

For example, 20100501 for May 1st, 2010. If you forget to format the date this way, the function will reformat it for you.

Function GetFlightsToFromSpecificAirportsOnDate(apiKey As String, fromAirport As String, _
                                                toAirport As String, givenDate As Date, Optional page As Long = 1, _
                                                Optional resultsPerPage As Long = 30, _
                                                Optional forceRequery As Boolean = False) As String()

Dim xml As Object ' MSXML2.XMLHTTP
Dim tempFile As String
Dim tempString() As String
Dim result As String
Dim xmlDoc As Object ' MSXML2.DOMDocument
Dim xmlDocRoot As Object ' MSXML2.IXMLDOMNode
Dim flights As Object ' MSXML2.IXMLDOMNodeList
Dim subFlights As Object ' MSXML2.IXMLDOMNodeList
Dim flight As Object ' MSXML2.IXMLDOMNode
Dim i As Long, j As Long
Dim dateToCheck As String

Const TEMP_FILENAME As String = "GetFlightsToFromSpecificAirportsOnDate"
Const XML_FILE_EXTENSION As String = ".xml"

  If Not IsDate(givenDate) Then
    MsgBox "givenDate should be a Date type variable or a value like this: #mm/dd/yyyy#"
    Exit Function
  Else
    dateToCheck = Format(givenDate, "yyyymmdd")
  End If

  ' if XML file exists or we force requery, don't requery website
  tempFile = environ("temp") & "\" & TEMP_FILENAME & fromAirport & toAirport & dateToCheck & XML_FILE_EXTENSION

  If Len(Dir(tempFile)) = 0 Or forceRequery Then

    Set xml = CreateObject("MSXML2.XMLHTTP.6.0")

    With xml
      .Open "GET", "http://api.flightcaster.com/airports/" & fromAirport & _
                   "/departures/" & toAirport & "/" & dateToCheck & ".xml?api_key=" & _
                   apiKey & "&api_version=0.1.1&page=" & page & "&per_page=" & resultsPerPage, False
      .send
    End With

    result = xml.responseText

    ' save result as temp XML document
    Call CreateFile(tempFile, result)

  End If

  ' load XML file into new XML document
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

  With xmlDoc
    .async = False
    .validateOnParse = False
    .Load tempFile
  End With

  ' check that the XML doc loaded
  If LoadError(xmlDoc) Then
    Exit Function
  End If

  ' get root node
  Set xmlDocRoot = GetRootNode(xmlDoc)

  ' make sure there are flights
  If xmlDocRoot.Attributes.getNamedItem("total-entries").nodeTypedValue = 0 Then
    MsgBox "No flights found", vbInformation
    Exit Function
  End If

  ' get first level child nodes
  Set flights = GetChildNodes(xmlDocRoot)

  ' resize array
  ' each node has 14 data points to extract
  ReDim tempString(1 To flights.Length, 1 To 14)

  For i = 1 To flights.Length

    Set flight = flights.item(i - 1)

    ' for the first 11 nodes, loop as usual
    ' for the last node, loop through it
    For j = 1 To flight.childNodes.Length
      Select Case j
        Case Is < 12
          tempString(i, j) = flight.childNodes(j - 1).nodeTypedValue
        Case Else
          Set subFlights = flights.item(j).childNodes
          tempString(i, j) = subFlights.item(j - 1).childNodes(0).nodeTypedValue
          tempString(i, j + 1) = subFlights.item(j - 1).childNodes(1).nodeTypedValue
          tempString(i, j + 2) = subFlights.item(j - 1).childNodes(2).nodeTypedValue
      End Select
    Next j
  Next i

  GetFlightsToFromSpecificAirportsOnDate = tempString

End Function

To check the number of entries, use

xmlDocRoot.attributes.getNamedItem("total-entries").nodeTypedValue

and for the number of pages, check

xmlDocRoot.attributes.getNamedItem("total-pages").nodeTypedValue

Sample usage

This sample procedure further filters GetFlightsToFromSpecificAirports by limiting the results to May 20th, 2010.

Sub TestFlightCaster()

Dim apiKey As String
Dim results() As String
Dim i As Long, j As Long

  apiKey = "your API key here"

  results = GetFlightsToFromSpecificAirportsOnDate(apiKey, "LGA", "DFW", #5/20/2010#)
  For i = LBound(results) To UBound(results)
    For j = LBound(results, 2) To UBound(results, 2)
      Debug.Print results(i, j)
    Next j
  Next i
End Sub

Check airport delays

The following function will check for posted delays at a given airport. It returns

  • Affected traffic (departing/arriving)
  • Airport ID
  • Date created
  • ID
  • Maximum
  • Minimum
  • Reason for delay
  • Trend
  • Date updated
Function GetAirportDelays(apiKey As String, airportID As String) As String()

Dim xml As Object ' MSXML2.XMLHTTP
Dim tempFile As String
Dim tempString() As String
Dim result As String
Dim xmlDoc As Object ' MSXML2.DOMDocument
Dim xmlDocRoot As Object ' MSXML2.IXMLDOMNode
Dim hash As Object ' MSXML2.IXMLDOMNodeList
Dim departureDelay As Object ' MSXML2.IXMLDOMNode
Dim i As Long

Const TEMP_FILENAME As String = "GetAirportDelays"
Const XML_FILE_EXTENSION As String = ".xml"

  ' if XML file exists, don't requery website
  tempFile = environ("temp") & "\" & TEMP_FILENAME & airportID & XML_FILE_EXTENSION

  If Len(Dir(tempFile)) = 0 Then

    Set xml = CreateObject("MSXML2.XMLHTTP.6.0")

    With xml
      .Open "GET", "http://api.flightcaster.com/airports/" & airportID & "/delays.xml?api_key=" & apiKey & "&api_version=0.1.1", False
      .send
    End With

    result = xml.responseText

    ' save result as temp XML document
    tempFile = CreateFile(tempFile, result)

  End If

  ' load XML file into new XML document
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

  With xmlDoc
    .async = False
    .validateOnParse = False
    .Load tempFile
  End With

  ' check that the XML doc loaded
  If LoadError(xmlDoc) Then
    Exit Function
  End If

  ' get root node
  Set xmlDocRoot = GetRootNode(xmlDoc)

  ' if there are no delays, root node will be empty
  If (Len(xmlDocRoot.nodeTypedValue) > 0) Then

    Set hash = GetChildNodes(xmlDocRoot)
    Set departureDelay = hash.item(0)

    ' resize array
    ReDim tempString(1 To departureDelay.childNodes.Length)

    For i = 1 To departureDelay.childNodes.Length
      tempString(i) = departureDelay.childNodes(i - 1).nodeTypedValue
    Next i

  End If

  GetAirportDelays = tempString
End Function

Sample usage

Sub TestFlightCaster()

Dim apiKey As String
Dim results() As String
Dim i As Long, j As Long

  apiKey = "your API key here"

  results = GetAirportDelays(apiKey, "LGA")
  For i = 1 To UBound(results)
    Debug.Print results(i)
  Next i
End Sub

Get flights

Returns all available flights in the FlightCaster database. This function returns the same information as all the other functions that return flight information (GetFlightsPerAirlineID).

Run this function to return the ID for each flight.

Function GetFlights(apiKey As String, Optional page As Long = 1, _
                    Optional resultsPerPage As Long = 30, _
                    Optional forceRequery As Boolean = False) As String()

Dim xml As Object ' MSXML2.XMLHTTP
Dim tempFile As String
Dim tempString() As String
Dim result As String
Dim xmlDoc As Object ' MSXML2.DOMDocument
Dim xmlDocRoot As Object ' MSXML2.IXMLDOMNode
Dim flights As Object ' MSXML2.IXMLDOMNodeList
Dim subFlights As Object ' MSXML2.IXMLDOMNodeList
Dim flight As Object ' MSXML2.IXMLDOMNode
Dim i As Long, j As Long

Const TEMP_FILENAME As String = "GetFlights"
Const XML_FILE_EXTENSION As String = ".xml"

  ' if XML file exists or we force requery, don't requery website
  tempFile = environ("temp") & "\" & TEMP_FILENAME & XML_FILE_EXTENSION

  If Len(Dir(tempFile)) = 0 Or forceRequery Then

    Set xml = CreateObject("MSXML2.XMLHTTP.6.0")

    With xml
      .Open "GET", "http://api.flightcaster.com/flights.xml?api_key=" & _
                   apiKey & "&api_version=0.1.1&page=" & page & "&per_page=" & resultsPerPage, False
      .send
    End With

    result = xml.responseText

    ' save result as temp XML document
    Call CreateFile(tempFile, result)

  End If

  ' load XML file into new XML document
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

  With xmlDoc
    .async = False
    .validateOnParse = False
    .Load tempFile
  End With

  ' check that the XML doc loaded
  If LoadError(xmlDoc) Then
    Exit Function
  End If

  ' get root node
  Set xmlDocRoot = GetRootNode(xmlDoc)

  ' make sure there are flights
  If xmlDocRoot.Attributes.getNamedItem("total-entries").nodeTypedValue = 0 Then
    MsgBox "No flights found", vbInformation
    Exit Function
  End If

  ' get first level child nodes
  Set flights = GetChildNodes(xmlDocRoot)

  ' resize array
  ' each node has 14 data points to extract
  ReDim tempString(1 To flights.Length, 1 To 14)

  For i = 1 To flights.Length

    Set flight = flights.item(i - 1)

    ' for the first 11 nodes, loop as usual
    ' for the last node, loop through it
    For j = 1 To flight.childNodes.Length
      Select Case j
        Case Is < 12
          tempString(i, j) = flight.childNodes(j - 1).nodeTypedValue
        Case Else
          Set subFlights = flights.item(j).childNodes
          tempString(i, j) = subFlights.item(j - 1).childNodes(0).nodeTypedValue
          tempString(i, j + 1) = subFlights.item(j - 1).childNodes(1).nodeTypedValue
          tempString(i, j + 2) = subFlights.item(j - 1).childNodes(2).nodeTypedValue
      End Select
    Next j
  Next i

  GetFlights = tempString

End Function

To check the number of entries, use

xmlDocRoot.attributes.getNamedItem("total-entries").nodeTypedValue

and for the number of pages, check

xmlDocRoot.attributes.getNamedItem("total-pages").nodeTypedValue

Sample usage

Sub TestFlightCaster()

Dim apiKey As String
Dim results() As String
Dim i As Long, j As Long

  apiKey = "your API key here"

  results = GetFlights(apiKey)
  For i = LBound(results) To UBound(results)
    For j = LBound(results, 2) To UBound(results, 2)
      Debug.Print results(i, j)
    Next j
  Next i
End Sub

Get specific flight

This function returns the details for an individual flight. Run GetFlights first to get the flight ID. Otherwise it returns the same information.

Function GetFlight(apiKey As String, flightID As String, _
                   Optional forceRequery As Boolean = False) As String()

Dim xml As Object ' MSXML2.XMLHTTP
Dim tempFile As String
Dim tempString() As String
Dim result As String
Dim xmlDoc As Object ' MSXML2.DOMDocument
Dim xmlDocRoot As Object ' MSXML2.IXMLDOMNode
Dim flights As Object ' MSXML2.IXMLDOMNodeList
Dim subFlights As Object ' MSXML2.IXMLDOMNodeList
Dim flight As Object ' MSXML2.IXMLDOMNode
Dim i As Long, j As Long

Const TEMP_FILENAME As String = "GetFlight"
Const XML_FILE_EXTENSION As String = ".xml"

  ' if XML file exists or we force requery, don't requery website
  tempFile = environ("temp") & "\" & TEMP_FILENAME & flightID & XML_FILE_EXTENSION

  If Len(Dir(tempFile)) = 0 Or forceRequery Then

    Set xml = CreateObject("MSXML2.XMLHTTP.6.0")

    With xml
      .Open "GET", "http://api.flightcaster.com/flights/" & flightID & ".xml?api_key=" & _
                   apiKey & "&api_version=0.1.1", False
      .send
    End With

    result = xml.responseText

    ' save result as temp XML document
    Call CreateFile(tempFile, result)

  End If

  ' load XML file into new XML document
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

  With xmlDoc
    .async = False
    .validateOnParse = False
    .Load tempFile
  End With

  ' check that the XML doc loaded
  If LoadError(xmlDoc) Then
    Exit Function
  End If

  ' get root node
  Set xmlDocRoot = GetRootNode(xmlDoc)

  ' get first level child nodes
  Set flights = GetChildNodes(xmlDocRoot)

  ' resize array
  ' there are 14 data points for each flight
  ReDim tempString(1 To 14)

  ' array has 14 elements, but we only loop 12 times because there are only 12 nodes
  For i = 1 To flights.Length

    ' for the first 11 nodes, loop as usual
    ' for the last node, loop through it
    Select Case i
      Case Is < 12
        tempString(i) = flights.item(i - 1).nodeTypedValue
      Case Else
        Set subFlights = flights.item(i - 1).childNodes
        tempString(i) = subFlights.item(0).nodeTypedValue
        tempString(i + 1) = subFlights.item(1).nodeTypedValue
        tempString(i + 2) = subFlights.item(2).nodeTypedValue
    End Select

  Next i

  GetFlight = tempString

End Function

Sample usage

Sub TestFlightCaster()

Dim apiKey As String
Dim results() As String
Dim i As Long, j As Long

  apiKey = "your API key here"

  results = GetFlight(apiKey, "191219033")
  For i = 1 To UBound(results)
    Debug.Print results(i)
  Next i
End Sub

Return ground delays

Delays happen all the time. This function will return the location and reason for delays at any airport in the FlightCaster database.

Function GetGroundDelays(apiKey As String, Optional page As Long = 1, _
                         Optional resultsPerPage As Long = 30, _
                         Optional forceRequery As Boolean = False) As String()

Dim xml As Object ' MSXML2.XMLHTTP
Dim tempFile As String
Dim tempString() As String
Dim result As String
Dim xmlDoc As Object ' MSXML2.DOMDocument
Dim xmlDocRoot As Object ' MSXML2.IXMLDOMNode
Dim delays As Object ' MSXML2.IXMLDOMNodeList
Dim delay As Object ' MSXML2.IXMLDOMNode
Dim i As Long, j As Long

Const TEMP_FILENAME As String = "GetGroundDelays"
Const XML_FILE_EXTENSION As String = ".xml"

  ' if XML file exists or we force requery, don't requery website
  tempFile = environ("temp") & "\" & TEMP_FILENAME & XML_FILE_EXTENSION

  If Len(Dir(tempFile)) = 0 Or forceRequery Then

    Set xml = CreateObject("MSXML2.XMLHTTP.6.0")

    With xml
      .Open "GET", "http://api.flightcaster.com/ground_delays.xml?api_key=" & _
                   apiKey & "&api_version=0.1.1&page=" & page & "&per_page=" & resultsPerPage, False
      .send
    End With

    result = xml.responseText

    ' save result as temp XML document
    Call CreateFile(tempFile, result)

  End If

  ' load XML file into new XML document
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

  With xmlDoc
    .async = False
    .validateOnParse = False
    .Load tempFile
  End With

  ' check that the XML doc loaded
  If LoadError(xmlDoc) Then
    Exit Function
  End If

  ' get root node
  Set xmlDocRoot = GetRootNode(xmlDoc)

  ' make sure there are delays
  If xmlDocRoot.Attributes.getNamedItem("total-entries").nodeTypedValue = 0 Then
    MsgBox "No delays found", vbInformation
    Exit Function
  End If

  ' get first level child nodes
  Set delays = GetChildNodes(xmlDocRoot)

  ' resize array
  ' each delay has five data points
  ReDim tempString(1 To delays.Length, 1 To 5)

  For i = 1 To delays.Length
    Set delay = delays.item(i - 1)

    For j = 1 To delay.childNodes.Length
      tempString(i, j) = delay.childNodes(j - 1).nodeTypedValue
    Next j
  Next i

  GetGroundDelays = tempString

End Function

To check the number of entries, use

xmlDocRoot.attributes.getNamedItem("total-entries").nodeTypedValue

and for the number of pages, check

xmlDocRoot.attributes.getNamedItem("total-pages").nodeTypedValue

Sample usage

Sub TestFlightCaster()

Dim apiKey As String
Dim results() As String
Dim i As Long, j As Long

  apiKey = "your API key here"

  results = GetGroundDelays(apiKey)
  For i = LBound(results) To UBound(results)
    For j = LBound(results, 2) To UBound(results, 2)
      Debug.Print results(i, j)
    Next j
  Next i
End Sub

You may also want to visit Ground Delay Program to see what the delay codes mean.

Ground stops information

Ground stops can occur during periods of bad weather (among other reasons). This function will return any ground stops currently in effect.

Function GetGroundStops(apiKey As String, Optional page As Long = 1, _
                        Optional resultsPerPage As Long = 30, _
                        Optional forceRequery As Boolean = False) As String()

Dim xml As Object ' MSXML2.XMLHTTP
Dim tempFile As String
Dim tempString() As String
Dim result As String
Dim xmlDoc As Object ' MSXML2.DOMDocument
Dim xmlDocRoot As Object ' MSXML2.IXMLDOMNode
Dim groundStops As Object ' MSXML2.IXMLDOMNodeList
Dim groundStop As Object ' MSXML2.IXMLDOMNode
Dim i As Long, j As Long

Const TEMP_FILENAME As String = "GetGroundStops"
Const XML_FILE_EXTENSION As String = ".xml"

  ' if XML file exists or we force requery, don't requery website
  tempFile = environ("temp") & "\" & TEMP_FILENAME & XML_FILE_EXTENSION

  If Len(Dir(tempFile)) = 0 Or forceRequery Then

    Set xml = CreateObject("MSXML2.XMLHTTP.6.0")

    With xml
      .Open "GET", "http://api.flightcaster.com/ground_stops.xml?api_key=" & _
                   apiKey & "&api_version=0.1.1&page=" & page & "&per_page=" & resultsPerPage, False
      .send
    End With

    result = xml.responseText

    ' save result as temp XML document
    Call CreateFile(tempFile, result)

  End If

  ' load XML file into new XML document
  Set xmlDoc = CreateObject("MSXML2.DOMDocument")

  With xmlDoc
    .async = False
    .validateOnParse = False
    .Load tempFile
  End With

  ' check that the XML doc loaded
  If LoadError(xmlDoc) Then
    Exit Function
  End If

  ' get root node
  Set xmlDocRoot = GetRootNode(xmlDoc)

  ' make sure there are delays
  If xmlDocRoot.Attributes.getNamedItem("total-entries").nodeTypedValue = 0 Then
    MsgBox "No stops found", vbInformation
    Exit Function
  End If

  ' get first level child nodes
  Set groundStops = GetChildNodes(xmlDocRoot)

  ' resize array
  ' each stop has four data points
  ReDim tempString(1 To groundStops.Length, 1 To 4)

  For i = 1 To groundStops.Length
    Set groundStop = groundStops.item(i - 1)

    For j = 1 To groundStop.childNodes.Length
      tempString(i, j) = groundStop.childNodes(j - 1).nodeTypedValue
    Next j
  Next i

  GetGroundStops = tempString

End Function

Sample usage

Sub TestFlightCaster()

Dim apiKey As String
Dim results() As String
Dim i As Long, j As Long

  apiKey = "your API key here"

  results = GetGroundStops(apiKey)
  For i = LBound(results) To UBound(results)
    For j = LBound(results, 2) To UBound(results, 2)
      Debug.Print results(i, j)
    Next j
  Next i
End Sub

An Open Letter to FlightCaster

If anyone from FlightCaster is reading, check your email: Your API documentation stinks.

It's inaccurate in some places, and several links are redundant.

On the Airport Resources page (http://docs.flightcaster.com/airports/), the link to airport arrivals is listed twice, but the first link is just a link to the existing page. In other words, it just reloads the current page.

On the Airport Resources page (http://docs.flightcaster.com/airports/), there is a "FAA Programs" section. The first link says "/airports/:id/programs(.:format)" but when you go to the page (http://docs.flightcaster.com/airports/programs) it shows the link as "/airports/:id/delays(.:format)", i.e. a different description of the method.

The next link is "/airports/:id/programs/ground_stops(.:format)" but that method returns a "Oops we couldn't find that" when I ran this query:

http://api.flightcaster.com/airports/JFK/programs/ground_stops.xml?api_key=&api_version=0.1.1&page=1&per_page=30

The ground delays method also doesn't return anything:

http://api.flightcaster.com/airports/JFK/programs/ground_delays.xml?api_key=&api_version=0.1.1&page=1&per_page=30

There's a redundant link on the Flight Resources page also — the first link under "Flights by Airport" is just a link to the existing page.

On the General Delays page (http://docs.flightcaster.com/faa/general_delays/) there are two methods that start with "/faa/" but if you visit each page, the method doesn't start with "/faa/". But that is beside the point, because any way you call them, both methods (with "/faa/" and without "/faa/") return "Oops we couldn't find that".

The Ground Delays and Ground Stops overview pages have almost the same problem — they both describe the methods as starting with "/faa/", but the individual method pages leave off the "/faa/" part. The difference is that if you leave off the "/faa/" they do work.

Thanks for providing such a great service, but these issues with the documentation made it much harder and take much longer to write code than it should have.

Update 6/24/2010: I finally heard from one of the FlightCaster developers, he let me know that the corrections I suggested have been made. –JP

About JP

I'm just an average guy who writes VBA code for a living. This is my personal blog. Excel and Outlook are my thing, with a sprinkle of Access and Word here and there. Follow this space to learn more about VBA. Keep Reading »



Share This Article:

Share and bookmark this articledelicious buttonfacebook buttonlinkedin buttonstumbleupon buttontwitter button

This article is closed to any future comments.
Random Data Generator