VBA-tools / VBA-Web

VBA-Web: Connect VBA, Excel, Access, and Office for Windows and Mac to web services and the web
http://vba-tools.github.io/VBA-Web/
MIT License
2k stars 492 forks source link

Mac Compatibility #65

Closed abennett2014 closed 9 years ago

abennett2014 commented 9 years ago

This has been a great help. Unfortunately i am running into a compatibility issue on Mac OS due to the instantiation of the ActiveX Control MSXML2.ServerXMLHTTP.6.0.

Is there an alternative that is available that would be cross-platform?

ruudvh commented 9 years ago

I do not believe Mac supports MSXML.ServerXMLHTTP.

Stackoverflow mentions using Query Tables or a VBA Shell function: http://stackoverflow.com/questions/15981960/how-do-i-issue-an-http-get-from-excel-vba-for-mac-2011 http://stackoverflow.com/questions/18282443/winhttprequest-on-mac-osx-excel-2011-vba http://stackoverflow.com/questions/158633/how-can-i-send-an-http-post-request-to-a-server-from-excel-using-vba/4617566#4617566

Hope this helps.

timhall commented 9 years ago

@abennett2014 As is Mac is not supported due to lack of ServerXMLHTTP (and in V4.0 WinHttpRequest)

@RuudvH Wow, hadn't seen the VBA Shell function before, definitely need to check that out! I looked into Query Tables, but that only supports only fairly simple GET/POST requests, so I hadn't pursued it much further, but I'll prototype some VBA Shell work and see what I can find.

timhall commented 9 years ago

Just did some prototyping with VBA Shell and it's looking very promising! Just added it as an item for V4.0 (#64)

timhall commented 9 years ago

(Should have waited to close once v4.0 had been released)

timhall commented 9 years ago

I've released v4.0.0-beta.1 which adds Mac support! It's still in beta phase as there are other (possibly breaking) changes being added before v4.0.0, but if you're able to help beta test on Mac it'd be very helpful.

/cc @fatabass @abennett2014

abennett2014 commented 9 years ago

no worries Tim, i will do some testing over the next few days and let you know the results

agazendam commented 9 years ago

After a few challenges I was able to successfully test the GetJSON example on the project's home page on my Mac. In order to get this working I had to:

  1. Download latest Mac capable version of Excel-REST (v4.0.0-beta.1 in my case)
  2. Download drop-in alternative for Microsoft Dictionary (see VBA-Dictionary)
  3. Unzip both zip files
  4. Open "Excel-REST - Blank.xlsm” from Excel-REST folder
  5. Right click on Excel for Mac 2011 ribbon and activate Developer tools
  6. Click on Editor and remove all classes from the VBAProject
  7. Right click on VBAProject and “import file” dictionary.cls from Dictionary archive, and all files from src folder in Excel-REST archive
  8. Change instancing of all Class Modules to PublicNotCreatable
  9. Modify StringToBytes in RestHelpers as follows:
    Modified by Albert Gazendam because Mac does not support vbFromUnicode - see http://msdn.microsoft.com/en-us/library/office/gg264628(v=office.15).aspx
    #If Mac Then
    StringToBytes = Text
    #Else
    StringToBytes = StrConv(Text, vbFromUnicode)
    #End If

Then do the following:

  1. Good idea to also modify BytesToString similarly, except here it is Bytes and vbUnicode
  2. Tools-References… unselect the missing Microsoft Scripting Runtime
  3. Copy-paste the GETJSON example from project homepage into the ThisWorkbook in the Editor
  4. Paste the following just before End Function in ThisWorkbook where the example was previously pasted
    If Response.StatusCode = Ok Then
    Dim Route As Dictionary
    Set Route = Response.Data("routes")(1)("legs")(1)
    GetDirections = "It will take " & Route("duration")("text") & _
            " to travel " & Route("distance")("text") & _
            " from " & Route("start_address") & _
            " to " & Route("end_address")
    Else
    Debug.Print "Error: " & Response.Content
    End If

And lastly...

  1. Exit Editor and add a button, selecting new macro for it
  2. Add Range("A1").Value = ThisWorkbook.GetDirections(Range("B1"), Range("B2”)) into the new Sub Routine that was defined in the new Module
  3. Ensure that all spaces are replaced by %20 in B1 and B2, which is where the source and destination addresses are entered
  4. Click the button and see result appear in A1
timhall commented 9 years ago

@agazendam Thanks for doing all of that! I'll be releasing beta.2 soon and will make sure the beta testing story is much more fleshed out so you don't have to go through all of this again.

I had noticed that the VBA documentation says that StrConv(..., vbUnicode) isn't supported on Mac, but it worked locally so I figured it was an old reference, but I'll replace that just in case. I had some issues with Byte-handling differences between Windows and Mac so I'll keep digging.

agazendam commented 9 years ago

My use case requires XML support on Mac. It appears like ParseXML requires MSXML2, which is not available on Mac. I have also not been able to track down an alternative solution yet. A swop-out class similar to VBA-Dictionary (which removed the dependency on the Microsoft Scripting Runtime) would be brilliant... Dead-end streets that I considered were:

  1. QueryTables - too simplistic in functionality and aimed at populating Excel cells
  2. importXML - Appears to do great job at HTTP GET (I need more), but only for Google Sheets
  3. cREST local - a class with useful functions created by Bruce McPherson, but also depends on MSXML2
  4. cREST Google Apps Script - Public web service for XML to JSON conversion. Most promising, but calling this web service with Excel-REST fails due to HTTP redirection, even after adding '-L' to cURL

Does anybody have any ideas?

dgaff commented 9 years ago

I have a case that's working on Windows, but not on Mac. This makes a call to the Google translate API. (Obviously insert your own API key in the code below.) I've included your Dictionary class and removed MS Scripting Runtime reference. The https call runs fine, and the return looks good, but an empty string comes back from ("data")("translations")(1)("translatedText") on Mac. Windows returns the correct translation text. This is a sample JSON return format for Google translate:

{
    "data": {
        "translations": [
            {
                "translatedText": "Hallo Welt"
            }
        ]
    }
}
Function Translate(Text As String, Source As String, Target As String) As String

    ' Create a RestClient for executing requests and set a base url that all requests will be appended to
    Dim TranslateClient As New RestClient
    TranslateClient.BaseUrl = "https://www.googleapis.com/"

    ' Use GetJSON helper to execute simple request and work with response
    Dim Resource As String
    Dim Response As RestResponse
    Resource = "language/translate/v2?key=XXXXXXXX&source=" & Source & "&target=" & Target & "&q=" & Text
    Set Response = TranslateClient.GetJSON(Resource)

    ' Extract translated text from JSON response
    If Response.StatusCode = Ok Then
        Translate = Response.Data("data")("translations")(1)("translatedText")
    Else
        Translate = "ERROR"
    End If

End Function
timhall commented 9 years ago

@dgaff Thanks for the feedback, I'll check that and see if I can figure out what's happening

timhall commented 9 years ago

@dgaff I tested it locally and got the same issue, it looks like it was a variable naming issue in JSONConverter although it was definitely a strange bug.

I've released v4.0.0-beta.4 if you want to give it a try to see if it resolves your issue.

timhall commented 9 years ago

Merged 4.0.0 RC, giving Mac support! Any additional testing is appreciated