Joh*_*ens 12 excel vba http-get excel-vba excel-vba-mac
我需要从Excel for Mac 2011向Web服务发出带有查询字符串的HTTP Get.我已经看到了使用QueryTables的答案(如何使用VBA从Excel向服务器发送HTTP POST请求?)但是使用POST方法,而不是GET方法.我也看到从Windows机器上很容易,但我被卡在了Mac上.
有什么建议,还是没有希望?
Joh*_*ens 23
进一步研究,我遇到了Robert Knight 在Office 2011 for Mac中对VBA Shell函数的这个问题的评论,并使用他的execShell函数构建了一个HTTPGet函数来调用curl.我已经在运行Mac OS X 10.8.3(Mountain Lion)的Mac上使用Excel for Mac 2011测试了这个.这是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
Run Code Online (Sandbox Code Playgroud)
要使用它,请复制上面的代码,在Excel for Mac 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为Moscow- A4将更改为莫斯科的JSON格式预测.
显然,使用VBA,您可以解析并重新格式化JSON数据,并将其放在工作表中所需的位置.
没有对性能或可扩展性的要求,但是对于从Excel for Mac 2011进行简单的一次性访问Web服务,这似乎可以解决问题并满足我发布原始问题的需要.YMMV!
John Stephens的上述答案非常棒(请注意它!),但是在最新的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
Run Code Online (Sandbox Code Playgroud)