16

Excel for Mac 2011 から Web サービスにクエリ文字列を含む HTTP Get を発行する必要があります GET メソッドではなく、POST メソッドを使用します。また、Windows マシンからは簡単ですが、Mac では行き詰っています。

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

4

3 に答える 3

28

さらに調査を行ったところ、Office 2011 for Mac の VBA シェル関数に関するこの質問に関する Robert Knight のコメントに出会い、彼の execShell 関数を使用して curl を呼び出す HTTPGet 関数を作成しました。Mac OS X 10.8.3 (Mountain Lion) と Excel for Mac 2011 を実行している Mac でこれをテストしました。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-- MoscowA4 は、モスクワの JSON 形式の予測に変更されます。

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

パフォーマンスやスケーラビリティについての主張はありませんが、Excel for Mac 2011 から Web サービスへの単純なワンショット アクセスについては、これでうまくいくようで、元の質問を投稿したニーズを満たしているようです。YMMV !

于 2013-04-13T23:51:02.510 に答える
11

ジョン・スティーブンスからの上記の答えは素晴らしいです(賛成してください!)が、最近のExcel:mac 2016では機能しなくなり、64ビットシステムで使用するにはコードを更新する必要があるというエラーが発生しました。

関連するリポジトリで見つけた問題からいくつかのヒントを得て、John のスクリプトのデータ型を 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
于 2016-10-13T19:41:16.760 に答える