Excel vba-谷歌地图超限查询
我正试图通过VBA从谷歌地图获取距离。这部分代码处于循环中,因此它在短时间内计算了相当多的距离,这就是为什么我尝试添加一种方法来处理随时间变化的查询。 我正在使用Desmond Oshiwambo的部分代码Excel vba-谷歌地图超限查询,excel,vba,Excel,Vba,我正试图通过VBA从谷歌地图获取距离。这部分代码处于循环中,因此它在短时间内计算了相当多的距离,这就是为什么我尝试添加一种方法来处理随时间变化的查询。 我正在使用Desmond Oshiwambo的部分代码 Option Explicit Const strUnits = "metric" ' imperial/metric (miles/km) Const strTransportMode = "driving" ' alternative = 'walking' Const strDeli
Option Explicit
Const strUnits = "metric" ' imperial/metric (miles/km)
Const strTransportMode = "driving" ' alternative = 'walking'
Const strDelimeter = "|" 'for lists of via points
Const MAX_GOOGLE_RETRIES = 10
第一个函数是一个helper函数,它从googlemaps获取数据
Function gglDirectionsResponse(ByVal strStartLocation, ByVal strEndLocation, ByRef strTravelTime, ByRef strDistance, ByRef strInstructions, Optional ByRef strError = "") As Boolean
On Error GoTo ErrorHandler
Dim strURL As String
Dim objXMLHttp As Object
Dim objDOMDocument As Object
Dim nodeRoute As Object
Dim lngDistance As Long
Dim strThisLegDuration As String
Dim legRoute
Dim lngSeconds As Long
Set objXMLHttp = CreateObject("MSXML2.XMLHTTP")
Set objDOMDocument = CreateObject("MSXML2.DOMDocument.6.0")
strStartLocation = Replace(strStartLocation, " ", "+")
strEndLocation = Replace(strEndLocation, " ", "+")
strTravelTime = "00:00"
strURL = "http://maps.googleapis.com/maps/api/directions/xml" & _
"?origin=" & strStartLocation & _
"&destination=" & strEndLocation & _
"&sensor=false" & _
"&units=" & strUnits
With objXMLHttp
.Open "GET", strURL, False
.setRequestHeader "Content-Type", "application/x-www-form-URLEncoded"
.send
objDOMDocument.LoadXML .responseText
End With
With objDOMDocument
If .SelectSingleNode("//status").Text = "OK" Then
'Iterate through each leg
For Each legRoute In .SelectSingleNode("//route").ChildNodes
If legRoute.BaseName = "leg" Then 'SelectSingleNode("/distance/value").Text
For Each nodeRoute In legRoute.ChildNodes
If nodeRoute.BaseName = "step" Then
lngDistance = lngDistance + nodeRoute.SelectSingleNode("distance/value").Text ' Retrieves distance in meters
lngSeconds = lngSeconds + Val(nodeRoute.SelectSingleNode("duration/value").Text)
End If
Next
End If
Next
strTravelTime = formatGoogleTime(lngSeconds) ' Retrieves distance in meters
Select Case strUnits
Case "imperial": strDistance = Round(lngDistance * 0.00062137, 1) 'Convert meters to miles
Case "metric": strDistance = Round(lngDistance / 1000, 1) 'Convert meters to miles
End Select
Else
strError = .SelectSingleNode("//status").Text
GoTo ErrorHandler
End If
End With
gglDirectionsResponse = True
GoTo CleanExit
ErrorHandler:
If strError = "" Then strError = Err.Description
strDistance = -1
strTravelTime = "00:00"
strInstructions = ""
gglDirectionsResponse = False
CleanExit:
Set objDOMDocument = Nothing
Set objXMLHttp = Nothing
End Function
第二个函数是我试图实现的“等待直到查询限制结束”。这不起作用,因为函数返回给我的值中有70%是-1(错误值)
函数getGoogleDistance(ByVal strFrom,ByVal strTo)作为字符串
作为字符串的Dim strDistance
作为字符串的Dim strTravelTime
Dim blnOverLimit作为布尔值
调暗lngStartTimer的长度
Dim lngQueryCount尽可能长
暗淡的lngQueryPauses尽可能长
作为字符串的模糊指令
朦胧如弦
暗灰色和长灰色一样
lngStartTimer=计时器
lngQueryCount=0
灰度=0
Application.DisplayStatusBar=True
如果是方向响应(strFrom、strTo、strTravelTime、strInstance、strInstructions、strError),则
做
blnOverLimit=False
如果(strInstance=“OVER\u QUERY\u LIMIT”),则
谷歌已经用完了,等几秒钟再试一次。
Application.StatusBar=“等待谷歌过载3秒”
应用程序。立即等待+时间值(“00:00:03”)'暂停2秒
Application.StatusBar=“重试”
lngQueryPauses=lngQueryPauses+1
blnOverLimit=True
lngreetries=lngreetries+1
其他的
如果(strError=”“)和(Val(strInstance)>0),则
Application.StatusBar=“已处理”
lngQueryCount=lngQueryCount+1
如果结束
如果结束
如果lngreetries>MAX\u GOOGLE\u重试,则
谷歌每日津贴已经达到
GoTo GoogleTooManyQueries
如果结束
循环直到Not blnOverLimit“超出限制”要么意味着查询太多太快,要么意味着已达到每日限额
如果(标准状态“无效请求”),则
getGoogleDistance=标准距离
如果结束
其他的
getGoogleDistance=-1
如果结束
清洁出口:
Application.StatusBar=“完成”
退出功能
GoogleTooManyQueries:
MsgBox“很抱歉,谷歌每天的查询限制已达到2000次。这可能需要24小时才能重置”,vbCritical
退出功能
错误处理程序:
MsgBox“错误:&错误说明,vbCritical
退出功能
端函数
如果有人能理解为什么代码没有被“减速”,我将不胜感激 我从这个链接输入了一个地址列表 在T430 Thinkpad上完成计算的时间约为60秒(这是一款非常古老的产品)
您是在问还是在问什么?是的,我试图通过在函数达到查询限制时停止函数来摆脱查询限制。我的尝试不起作用,因为它返回了一些有效距离,然后是一行“-1”,然后又返回了一些有效距离。我尝试了一下,也得到了“-1”。最后我做了一个循环,看看范围中是否还有“-1”,删除它们,然后重新开始。这很慢,但我最终得到了一些东西!
Function getGoogleDistance(ByVal strFrom, ByVal strTo) As String
Dim strDistance As String
Dim strTravelTime As String
Dim blnOverLimit As Boolean
Dim lngStartTimer As Long
Dim lngQueryCount As Long
Dim lngQueryPauses As Long
Dim strInstructions As String
Dim strError As String
Dim lngRetries As Long
lngStartTimer = Timer
lngQueryCount = 0
lngRetries = 0
Application.DisplayStatusBar = True
If gglDirectionsResponse(strFrom, strTo, strTravelTime, strDistance, strInstructions, strError) Then
Do
blnOverLimit = False
If (strDistance = "OVER_QUERY_LIMIT") Then
' Google has maxed out, wait a couple of seconds and try again.
Application.StatusBar = "Waiting 3 second for Google overload"
Application.Wait Now + TimeValue("00:00:03") ' pause 2 seconds
Application.StatusBar = "Try again"
lngQueryPauses = lngQueryPauses + 1
blnOverLimit = True
lngRetries = lngRetries + 1
Else
If (strError = "") And (Val(strDistance) > 0) Then
Application.StatusBar = "Processed "
lngQueryCount = lngQueryCount + 1
End If
End If
If lngRetries > MAX_GOOGLE_RETRIES Then
' the Google per day allowance hase been reached
GoTo GoogleTooManyQueries
End If
Loop Until Not blnOverLimit ' Over Limit either means too many queries too fast, or that the per day allowance has been reached
If (strDistance <> "INVALID_REQUEST") Then
getGoogleDistance = strDistance
End If
Else
getGoogleDistance = -1
End If
CleanExit:
Application.StatusBar = "Finished"
Exit Function
GoogleTooManyQueries:
MsgBox "Sorry, Google limit of 2000 queries per day has been reached. This may take upto 24 hours to reset", vbCritical
Exit Function
ErrorHandler:
MsgBox "Error :" & Err.Description, vbCritical
Exit Function
End Function
'Calculate Google Maps distance between two addresses
Public Function GetDistance(start As String, dest As String)
Dim firstVal As String, secondVal As String, lastVal As String
firstVal = "http://maps.googleapis.com/maps/api/distancematrix/json?origins="
secondVal = "&destinations="
lastVal = "&mode=car&language=pl&sensor=false"
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
URL = firstVal & Replace(start, " ", "+") & secondVal & Replace(dest, " ", "+") & lastVal
objHTTP.Open "GET", URL, False
objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
objHTTP.send ("")
If InStr(objHTTP.responseText, """distance"" : {") = 0 Then GoTo ErrorHandl
Set regex = CreateObject("VBScript.RegExp"): regex.Pattern = """value"".*?([0-9]+)": regex.Global = False
Set matches = regex.Execute(objHTTP.responseText)
tmpVal = Replace(matches(0).SubMatches(0), ".", Application.International(xlListSeparator))
GetDistance = CDbl(tmpVal)
Exit Function
ErrorHandl:
GetDistance = -1
End Function