2013-04-12 17 views
11

MacのExcel 2011からWebサービスにクエリ文字列を取得する必要があります.QueryTables(How can I send an HTTP POST request to a server from Excel using VBA?)を使用した場合の回答を見ましたが、 GETメソッドではなくPOSTメソッドを使用します。また、Windowsマシンからは簡単だとわかりますが、私はMacで動かないです。MacのExcel VBAからHTTP GETを発行する方法

提案がありますか、それとも絶望的ですか?

答えて

18

さらに詳しい研究をして、この質問VBA Shell function in Office 2011 for Macに関するRobert Knightのコメントを見つけ、彼のexecShell関数を使ってcurlを呼び出すHTTPGet関数を作成しました。 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  

は、これを使用する上記のコードをコピーするには:私は、Mac 2011ここではVBAコードがあるために、Excelを搭載したMac OS X 10.8.3(マウンテンライオン)を実行しているMacでこれをテストしてみましたエディターをMac 2011用Excelで実行します。モジュールがない場合は、[挿入] - > [モジュール]をクリックします。コードをモジュールファイルに貼り付けます。 VBAエディタ(clover-Q)のままにします。

ここでは、天気予報Webサービスを使用して、特定の例(http://openweathermap.org/wiki/API/JSON_API)です

セルA1は、都市の名前のために予約されます。セルA2に

、URL文字列を入力します。入力し、セルA4に="q=" & A1

:入力し、クエリ文字列を構築しますセルA3でhttp://api.openweathermap.org/data/2.1/forecast/city

を今すぐ=HTTPGet(A2, A3)

、タイプAたとえば、LondonのようにセルA1の都市名を入力すると、ロンドンの天気予報を含むJSONレスポンスがセルA4に表示されます。 A1の値をLondonからMoscowに変更します - A4はJSON形式のモスクワの予測に変更されます。

明らかに、VBAを使用すると、JSONデータを解析して再フォーマットし、ワークシートに必要な場所に配置できます。

パフォーマンスやスケーラビリティについての主張はしていませんが、Excel for Mac 2011のWebサービスへのシンプルなワンショットアクセスでは、これはトリックではないかと思われ、元の質問を投稿しました。 YMMV

0

別のオプション(あなたのカールが/ opt/local/binに/カールに配置されていない場合はそれに応じて更新):

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 

あなたはgetUrl.shが実行可能であることを確認する必要があります。注:

chmod u+x getUrl.sh 
1

上記のJohn Stephensの答えは素晴らしいです(アップしてください!)が、最近のExcel:mac 2016ではもう機能しませんでした.64ビットシステムで使用するためにコードを更新する必要があります。 。

an issue I found in a related repositoryからいくつかのヒントを取って、私は、Excelで正しく動作するようにジョンのスクリプトでデータ型を調整することが可能であった:マック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 
関連する問題