2013-04-12 14 views

risposta

18

Facendo ulteriori ricerche, mi sono imbattuto nel commento di Robert Knight su questa domanda VBA Shell function in Office 2011 for Mac e ho creato una funzione HTTPGet usando la sua funzione execShell per chiamare curl. Ho provato questo su un Mac con Mac OS X 10.8.3 (Mountain Lion) con Excel per Mac 2011. Ecco il codice VBA:

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  

Per utilizzare questo, copiare il codice di cui sopra, aprire il VBA editor in Excel per Mac 2011. Se non si dispone di un modulo, fare clic su Inserisci-> Modulo. Incolla il codice nel file del modulo. Lascia l'editor VBA (clover-Q).

Ecco un esempio specifico utilizzando un servizio web previsioni del tempo (http://openweathermap.org/wiki/API/JSON_API)

cellulare A1 sarà riservato per il nome della città.

nella cella A2, digitare la stringa URL: http://api.openweathermap.org/data/2.1/forecast/city

Nella cella A3 che si baserà la stringa di query, digitare: ="q=" & A1

Nella cella A4, immettere: =HTTPGet(A2, A3)

Ora, tipo un nome della città nella cella A1, ad esempio London, la cella A4 ti mostrerà la risposta JSON contenente le previsioni del tempo per Londra. Modificare il valore in A1 da London a Moscow - A4 passerà alla previsione in formato JSON per Mosca.

Ovviamente, utilizzando VBA, è possibile analizzare e riformattare i dati JSON e posizionarli dove necessario nel foglio di lavoro.

Nessun reclamo per prestazioni o scalabilità, ma per un semplice accesso one-shot a un servizio Web da Excel per Mac 2011, questo sembra fare il trucco e ha soddisfatto la necessità per cui ho postato la mia domanda originale. YMMV!

0

Un'altra opzione (aggiornare di conseguenza se la vostra arricciatura non si trova in/opt/local/bin/ricciolo):

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 

noti che si dovrà assicurare che getUrl.sh è eseguibile:

chmod u+x getUrl.sh 
1

La risposta sopra da John Stephens è fantastica (si prega di inversione di tendenza!), Ma non ha più funzionato per me nel più recente Excel: mac 2016, con un errore che il codice deve essere aggiornato per l'uso su sistemi a 64 bit .

Prendendo alcuni suggerimenti da an issue I found in a related repository, sono stato in grado di regolare i tipi di dati nello script di John per funzionare correttamente in Excel: 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