2017-04-17 73 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

相關問題