Search code examples
excelvbaxmlhttprequest

VBA - Late Binding vs. Early Binding Error - Difference in xml responses


I wrote some code to GET a response from a server using early binding (first statement when mbEARLY_BINDING_FSO = True

Option Explicit
Option Private Module


#Const mbEARLY_BINDING_FSO = False
Private Const msMODULE_NAME As String = "Controls"

Public Sub refresh_database()

Const sPROC_NAME As String = "refresh_database()"
If Not gbDEBUG Then On Error GoTo errExitLL

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'LOWER LEVEL PROCEDURE

'Comments: Refresh the database from call to app.longtrend.com/api/seach?map=tickers
'Agurments: None
'Dependencies: None
'Returns: JSON object of available companies listed to Company List sheet
'----------------------------------------------------------------------------------------------------------------------

Dim base_url As String
Dim successMsg As Variant
Dim Json As Object
Dim account_key As Variant
Dim dict_key As Variant
Dim item As Variant
Dim sheet_ticker As Worksheet
Dim lrow As Long
Dim lcol As Long
Dim rng As Range

#If mbEARLY_BINDING_FSO Then
    Dim xml_obj As MSXML2.XMLHTTP60
    Set xml_obj = New MSXML2.XMLHTTP60
#Else
    Dim xml_obj As Object
    Set xml_obj = CreateObject("MSXML2.XMLHTTP.6.0")
#End If

Set sheet_ticker = Sheets("Admin_Control")

       UserFormProgress.Display 5, False
       UserFormProgress.SetText "Checking stuff XX ..."
       Application.Wait Now + #12:00:01 AM#

base_url = "https://app.longtrend.com/api/search?map=tickers"

'Open a new get request using URL
xml_obj.Open bstrMethod:="GET", bstrURL:=base_url
xml_obj.send

'set up the object and parse the response
Set Json = JsonConverter.ParseJson(xml_obj.responseText)

' Status code router - 200 is Success, all else will print error in range("STATUS") and exit sub
If xml_obj.Status <> 200 Then
    With Range("STATUS")
        .Value = xml_obj.Status & ": " & Json("Error")
        .Font.Color = RGB(255, 143, 143)
    End With

    Application.ScreenUpdating = True
    End
End If

'Parse Json object
Dim i As Long
Dim key As Variant

i = rng.Row + 1
For Each key In Json
    sheet_ticker.Cells(i, rng.Column) = key
    sheet_ticker.Cells(i, rng.Column + 1) = Json(key)("name")
    sheet_ticker.Cells(i, rng.Column + 2) = Json(key)("sector")
    sheet_ticker.Cells(i, rng.Column + 3) = Json(key)("industry")
    sheet_ticker.Cells(i, rng.Column + 4) = Json(key)("marketCap")
    sheet_ticker.Cells(i, rng.Column + 5) = Json(key)("lastFY")
    i = i + 1
Next

Exit Sub
errExitLL:
       Application.ScreenUpdating = True
       ErrorHandling.LowLevel msMODULE_NAME, sPROC_NAME, "url", base_url, "last row", lrow

End Sub

With early binding, my xml_obj response is as exptected. The responseText stores all values to be parsed in the JSON converter. Now, prior to release I'd like to set to late binding. I've created the object as shown in the second statement however the responseText in the locals window says: this method cannot be called until the send method has been called. The xml_obj is sent prior to this local response.

I have tried the following so far:

Set xml_obj = CreateObject("Microsoft.XMLHTTP")
Set xml_obj = CreateObject("MSXML2.XMLHTTP60")
Set xml_obj = CreateObject("MSXML2.XMLHTTP.6.0")
Set xml_obj = CreateObject("MSXML2.ServerXMLHTTP")

To no avail! An error occur either when I attempt to create the object CreateObject(XX) and there is no associated ActiveX available, or as mentioned above, the response request isn't correct once the request is sent. I'm not sure what I'm missing as this should be a simple enough activity. Any help is much appreciated.

Running Office 365 (build 14228) for Windows (64 bit, VBA7)

Thanks, Scott


Solution

  • If you don't specify a value, then the third argument to Open (asynchronous) defaults to True, so you should pass False there.

    If you run asynchronously your code will not wait until the response is complete.