2013-04-12 12 views
11

Ich muss eine HTTP Get mit einer Abfragezeichenfolge zu einem Webdienst von Excel für Mac 2011 ausgeben. Ich habe die Antworten für die Verwendung von QueryTables (How can I send an HTTP POST request to a server from Excel using VBA?) aber gesehen Sie verwenden die POST-Methode, keine GET-Methode. Ich sehe auch, dass es von einer Windows-Maschine aus einfach ist, aber ich stecke auf einem Mac fest.Wie erstelle ich einen HTTP GET von Excel VBA für Mac 2011

Irgendwelche Vorschläge, oder ist es hoffnungslos?

Antwort

18

Bei weiteren Recherchen stieß ich auf Robert Knights Kommentar zu dieser Frage VBA Shell function in Office 2011 for Mac und baute eine HTTPGet-Funktion mit seiner execShell-Funktion, um curl aufzurufen. Ich habe dies auf einem Mac mit Mac OS X 10.8.3 (Mountain Lion) mit Excel für Mac getestet 2011. Hier ist der VBA-Code:

Option Explicit 

' execShell() function courtesy of Robert Knight via StackOverflow 
' https://stackoverflow.com/questions/6136798/vba-shell-function-in-office-2011-for-mac 

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 
     Exit Function 
    End If 

    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 
     End If 
    Wend 

    exitCode = pclose(file) 
End Function 

Function HTTPGet(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 

    HTTPGet = sResult 

End Function  

Um dies zu nutzen, kopieren Sie den Code oben, öffnen Sie die VBA Editor in Excel für Mac 2011. Wenn Sie kein Modul haben, klicken Sie auf Einfügen-> Modul. Fügen Sie den Code in die Moduldatei ein. Belassen Sie den VBA-Editor (Clover-Q).

Hier ist ein konkretes Beispiel eine Wettervorhersage Web-Service (http://openweathermap.org/wiki/API/JSON_API)

Zelle A1 verwendet, wird für den Namen der Stadt reserviert werden.

in der Zelle A2 geben Sie die URL-Zeichenfolge: http://api.openweathermap.org/data/2.1/forecast/city

In Zelle A3, die die Query-String bauen, geben Sie: ="q=" & A1

in Zelle A4 ein: =HTTPGet(A2, A3)

nun eine Art Name der Stadt in Zelle A1, zum Beispiel London, Zelle A4 zeigt Ihnen die JSON-Antwort, die die Wettervorhersage für London enthält. Ändern Sie den Wert in A1 von London in Moscow - A4 wird in die JSON-formatierte Prognose für Moskau geändert.

Mit VBA können Sie die JSON-Daten natürlich analysieren und neu formatieren und in Ihrem Arbeitsblatt platzieren.

Kein Anspruch auf Leistung oder Skalierbarkeit, aber für einen einfachen One-Shot-Zugriff auf einen Web-Service von Excel für Mac 2011, scheint dies den Trick zu tun und erfüllt die Notwendigkeit, für die ich meine ursprüngliche Frage posten. YMMV!

0

Eine weitere Option (entsprechend aktualisieren, wenn Ihre curl nicht in/opt/local/bin/curl befindet):

VBA:

Public Function getUrlContents(url) As String 
    Dim command As String 
    command = "do shell script ""/path_to/getUrl.sh " + url + """" 
    getUrlContents = VBA.MacScript(command) 
End Function 

/path_to/getUrl.sh:

#!/bin/sh 

if [ -z "$1" ] 
    then 
    echo "missing url argument" 
else 
    /opt/local/bin/curl "$1" 
fi 

Beachten Sie, dass Sie müssen sicherstellen, dass getUrl.sh ausführbar ist:

chmod u+x getUrl.sh 
1

Die obige Antwort von John Stephens ist fantastisch (bitte upvote es!), Aber es funktionierte nicht mehr für mich in der neueren Excel: mac 2016, mit einem Fehler, dass der Code für die Verwendung auf 64-Bit-Systemen aktualisiert werden muss .

paar Tipps von an issue I found in a related repository machen, ich war in der Lage, die Datentypen in Johns Skript anpassen korrekt in Excel zu arbeiten: mac 2016:

Option Explicit 

' execShell() function courtesy of Robert Knight via StackOverflow 
' http://stackoverflow.com/questions/6136798/vba-shell-function-in-office-2011-for-mac 

Private Declare PtrSafe Function popen Lib "libc.dylib" (ByVal command As String, ByVal mode As String) As LongPtr 
Private Declare PtrSafe Function pclose Lib "libc.dylib" (ByVal file As LongPtr) As Long 
Private Declare PtrSafe Function fread Lib "libc.dylib" (ByVal outStr As String, ByVal size As LongPtr, ByVal items As LongPtr, ByVal stream As LongPtr) As Long 
Private Declare PtrSafe Function feof Lib "libc.dylib" (ByVal file As LongPtr) As LongPtr 

Function execShell(command As String, Optional ByRef exitCode As Long) As String 
    Dim file As LongPtr 
    file = popen(command, "r") 

    If file = 0 Then 
     Exit Function 
    End If 

    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 
     End If 
    Wend 

    exitCode = pclose(file) 
End Function 

Function HTTPGet(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 

    HTTPGet = sResult 

End Function