2017-04-17 60 views
0

我来自巴西,对我的英语感到抱歉,但我的错误真的让我发疯!VBA方向API - 无效请求只能通过代码

我已经键入使用此路线API在VBA守则只是为了从A的距离B(公里数)。 好吧,我已经和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发送往返于和编码做休息。正如我所说,我会测试和所有的作品,现在不能运行。我在这里想念的人是什么?

的ErrorHandler时激活当代码尝试运行的具体线路:

With objDOMDocument 
     If .SelectSingleNode("//status").Text = "OK" Then 

回到这里INVALID_REQUEST。

看装后的网址: https://maps.googleapis.com/maps/api/directions/xml?origin=Porto+Nacional-TO&destination=Silvanópolis-TO,+Brasil&key=MY_API_KEY&sensor=false&units=metric

从浏览器看的IMG browser img, from api url in the code

注:我没有得到宏或负载或VBA代码错误,这是验证XML回报的ErrorHandler ,并且返回显示为invalid_request,但浏览器加载成功时代码中的URL相同。 请拜托,有人帮助我!

回答

0

尝试请求头设置为:

.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT enter code here5.0)" 

不知道这是否会工作虽然..

+0

变量strUnits似乎并没有被初始化 – h2so4

+0

你说得对,我没有注意到,我客串改变“&单位=“&strUnits 到”&units = metric“就可以解决这个问题。 –

+0

嗨,对不起,但我忘了发布......我的strUnits它在模块上的一个常量。 const strUnits =“metric” 这段代码是模块内部的第一行,所以我明白它是一个常量,它的公有一次在模块内已经初始化。 但我会尝试这两个。只需一秒! – dEhzin

0

正如我在回答前评论。当我写这行代码时发现问题:

.SelectSingleNode("/").text 

*显然在.Send命令之后。

这个返回给我,我发送一个包含非utf-8字符的无效参数。

所以在XML代码“/”它就像根结构,这一点,我能得到ERROR_MESSAGE更准确地理解错误。

因此,正如我说,我来自巴西,我们的城市有很多的(”,I,A,E,O ...),所以我会测试并拿到最后的正确状态。

现在我的问题是如何将任何字符转换,但容易,如果我们比较:d

相关问题