我来自巴西并对我的英语感到抱歉,但我的错误让我疯狂!
我已经使用此Directions API在VBA中输入代码,只是为了获得从A到B的距离(以km为单位)。 好吧,我已经和IT安全公司讨论了允许我的API请求并获得许可和测试。
所以今天我设置我的宏运行完美,我发现我的代码返回INVALID_REQUEST,但更疯狂的是,如果我把URL放在浏览器中我得到完美的响应但是当Excel尝试运行编码时,我从XML返回中获得了INVALID_REQUEST。
查看我的代码:
Function gglDirectionsResponse(ByVal strStartLocation, ByVal strEndLocation, ByRef strTravelTime, ByRef strDistance, ByRef strInstructions, Optional ByRef strError = "") As Boolean
On Error GoTo errorHandler
' Helper function to request and process XML generated by Google Maps.
Dim strURL As String
Dim objXMLHttp As Object
Dim objDOMDocument As Object
Dim nodeRoute As Object
Dim lngDistance As Long
Set objXMLHttp = CreateObject("MSXML2.XMLHTTP")
Set objDOMDocument = CreateObject("MSXML2.DOMDocument.6.0")
strStartLocation = Replace(strStartLocation, " ", "+")
strEndLocation = Replace(strEndLocation, " ", "+")
strURL = "https://maps.googleapis.com/maps/api/directions/xml" & _
"?origin=" & strStartLocation & _
"&destination=" & strEndLocation & _
"&key=MY_API_KEY" & _
"&sensor=false" & _
"&units=" & strUnits
'Send XML request
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
'Get Distance
lngDistance = .SelectSingleNode("/DirectionsResponse/route/leg/distance/value").Text ' 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
'Get Travel Time
strTravelTime = .SelectSingleNode("/DirectionsResponse/route/leg/duration/value").Text 'returns in seconds from google
strTravelTime = formatGoogleTime(strTravelTime) 'converts seconds to hh:mm
'Get Directions
For Each nodeRoute In .SelectSingleNode("//route/leg").ChildNodes
If nodeRoute.BaseName = "step" Then
strInstructions = strInstructions & nodeRoute.SelectSingleNode("html_instructions").Text & " - " & nodeRoute.SelectSingleNode("distance/text").Text & vbCrLf
End If
Next
strInstructions = CleanHTML(strInstructions) 'Removes MetaTag information from HTML result to convert to plain text.
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
Function getGoogleDistance(ByVal strFrom, ByVal strTo) As String
'Returns the distance between strFrom and strTo
'where strFrom/To are address search terms recognisable by Google
'i.e. Postcode, address etc.
Dim strTravelTime As String
Dim strDistance As String
Dim strError As String
Dim strInstructions As String
If gglDirectionsResponse(strFrom, strTo, strTravelTime, strDistance, strInstructions, strError) Then
getGoogleDistance = strDistance
Else
getGoogleDistance = strError
End If
End Function
所以,我只是调用函数gglDirectionsResponse发送,FROM和TO,编码完成其余的工作。正如我所说的,我会测试并且一切正常,现在无法运行。我在这里想念的是什么?
当代码尝试运行特定行时,将激活errorHandler:
With objDOMDocument
If .SelectSingleNode("//status").Text = "OK" Then
这里返回INVALID_REQUEST。
从浏览器中查看img browser img, from api url in the code
注意:我没有得到宏或加载或VBA代码错误,它是一个errorHandler来验证XML返回,并且Return显示为invalid_request但浏览器加载成功的代码中的相同URL。 拜托,有人帮助我!
答案 0 :(得分:0)
尝试将请求标头设置为:
.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT enter code here5.0)"
不知道它是否会起作用..
答案 1 :(得分:0)
正如我之前在答案中评论的那样。当我写下这句话时发现了问题:
.SelectSingleNode("/").text
*显然是在.Send命令之后。
对我而言,我发送了一个包含非utf-8字符的无效参数。
所以XML中的代码“/”就像根结构一样,有了这个,我可以得到error_message来更正确地理解错误。
正如我所说,我来自巴西,我们的城市有很多(',í,á,é,ó......)所以我会测试并最终获得正确的状态。
现在我的问题是如何转换任何角色,但如果我们比较那么容易:D