Excel for Mac2011からWebサービスにクエリ文字列を含むHTTPGetを発行する必要があります。QueryTablesを使用するための回答を見てきました( HTTPを送信するにはどうすればよいですかPOST = VBAを使用してExcelからサーバーにリクエストしますか? )しかし、彼らはGETメソッドではなくPOSTメソッドを使用します。Windowsマシンからは簡単だと思いますが、私はMacで立ち往生。
何か提案がありますか、それとも絶望的ですか?
さらに調査を行ったところ、この質問に対するRobert Knightのコメントに出くわしました Office 2011 for MacのVBAシェル関数 そして彼のexecShell関数を使用してcurlを呼び出すHTTPGet関数を作成しました。 Mac OS X 10.8.3(Mountain Lion)を実行しているMacでExcel for Mac2011を使用してこれをテストしました。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
_
これを使用するには、上記のコードをコピーし、Excel for Mac 2011でVBAエディターを開きます。モジュールがない場合は、[挿入]-> [モジュール]をクリックします。コードをモジュールファイルに貼り付けます。 VBAエディター(clover-Q)を終了します。
天気予報Webサービスを使用した特定の例を次に示します( http://openweathermap.org/wiki/API/JSON_API )
セルA1は都市の名前のために予約されます。
セルA2に、URL文字列を入力します:_http://api.openweathermap.org/data/2.1/forecast/city
_
クエリ文字列を作成するセルA3に、次のように入力します。_="q=" & A1
_
セルA4に、次のように入力します。=HTTPGet(A2, A3)
ここで、セルA1に都市名を入力します(例:London
)。セルA4には、ロンドンの天気予報を含むJSON応答が表示されます。 A1の値をLondon
からMoscow
に変更します-A4はモスクワのJSON形式の予測に変更されます。
もちろん、VBAを使用すると、JSONデータを解析して再フォーマットし、ワークシートの必要な場所に配置できます。
パフォーマンスやスケーラビリティについての主張はありませんが、Excel for Mac 2011からWebサービスへの簡単なワンショットアクセスの場合、これでうまくいくようで、元の質問を投稿したニーズに応えました。 [〜#〜] ymmv [〜#〜] !
John Stephensからの上記の回答は素晴らしいですが(賛成してください!)、最近のExcel:mac 2016では機能しなくなり、64ビットシステムで使用するにはコードを更新する必要があるというエラーが発生しました。
関連するリポジトリで見つけた問題 からいくつかのヒントを得て、Excel:mac2016で正しく機能するようにJohnのスクリプトのデータ型を調整することができました。
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
別のオプション(カールが/ opt/local/bin/curlにない場合は、それに応じて更新します):
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