programing

Mac용 Excel VBA에서 HTTP GET를 발급하는 방법

i4 2023. 6. 30. 22:04
반응형

Mac용 Excel VBA에서 HTTP GET를 발급하는 방법

맥용 엑셀 2011에서 웹 서비스로 HTTP Get with query string을 발급해야 합니다.QueryTables(VBA를 사용하여 Excel에서 서버로 HTTP POST 요청을 전송하려면 어떻게 해야 합니까?)를 사용하는 답변을 봤지만 GET 방법이 아닌 POST 방법을 사용합니다.또한 Windows 컴퓨터에서 쉽게 사용할 수 있다는 것을 알 수 있지만, Mac에서는 사용할 수 없습니다.

어떤 제안이라도 있습니까, 아니면 희망이 없습니까?

추가 연구를 하면서 Mac용 Office 2011의 VBA Shell 기능에 대한 Robert Knight의 의견을 우연히 알게 되었고 그의 execShell 기능을 사용하여 curl을 호출하는 HTTPGet 기능을 구축했습니다.Mac용 Excel 2011을 사용하여 Mac OS X 10.8.3(Mountain Lion)을 실행하는 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    

이를 사용하려면 위의 코드를 복사하여 Mac용 Excel 2011에서 VBA 편집기를 엽니다.모듈이 없는 경우 삽입->모듈을 클릭합니다.코드를 모듈 파일에 붙여넣습니다.VBA 편집기(clover-Q)를 그대로 둡니다.

일기예보 웹 서비스(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 데이터를 구문 분석하고 다시 포맷하여 워크시트에 필요한 위치에 배치할 수 있습니다.

성능이나 확장성에 대한 요구는 없지만, Mac용 Excel 2011에서 웹 서비스에 한 번에 액세스하는 것이 효과적이며 원래 질문을 올린 필요성을 충족시키는 것 같습니다.YMMV!

위의 John Stephens의 답변은 환상적이지만(업데이트 부탁드립니다!), 64비트 시스템에서 사용하기 위해 코드를 업데이트해야 한다는 오류와 함께 최신 Excel:mac 2016에서는 더 이상 작동하지 않았습니다.

관련 저장소에서 발견한 문제에 대한 몇 가지 팁을 활용하여 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

다른 옵션(컬이 /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

언급URL : https://stackoverflow.com/questions/15981960/how-do-i-issue-an-http-get-from-excel-vba-for-mac

반응형