简体   繁体   中英

VBA code not returning values larger than 999

I'm trying get Excel to return the driving distance between to addresses, zip codes, etc. I've got everything setup with the Google API, but I'm not familiar with VBA at all, so I'm not sure what is wrong with this code.

Whenever the distance between 2 points is greater than 999 miles, the code will only return the first number. So if it's 1,284 miles, it only returns a 1. If it's 2,817 miles, it only returns a 2, and so forth. The code that I'm running is below if someone could look at it and tell me what I'm missing, or what I'm doing wrong.

And just so I'm being as transparent as possible, I did not write any of this myself. I got it from a site called analystcave.com , and I've posted about this issue on there before, and the only response back I got didn't correct the issue. I've posted again, but I thought StackOverflow was a better place to find the correct answer, and much quicker.

Thank you in advance for your help!

'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&units=imperial&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 regex = CreateObject("VBScript.RegExp"): regex.Pattern = """text"".*?([0-9]+)": regex.Global = False

    Set matches = regex.Execute(objHTTP.responseText)

    tmpVal = Replace(matches(0).SubMatches(0), ".", Application.International(xlListSeparator))

    Debug.Print matches(0).SubMatches(0)

    GetDistance = CDbl(tmpVal)

    Exit Function
ErrorHandl:
    GetDistance = -1
End Function

The issue is fairly obvious if you look at what is being returned by your request (using inputs "Los Angeles, CA 90001", "New York, NY 10001"):

     "elements" : [
        {
           "distance" : {
              "text" : "2 796 mil",
              "value" : 4499875
           },
           "duration" : {
              "text" : "1 dzien 16 godz.",
              "value" : 144859
           },
           "status" : "OK"
        }
     ]

Note that you are requesting the text with a Polish localization here (language= pl ):

lastVal = "&mode=car&language=pl&units=imperial&sensor=false"

This is localizing the distance text with a space for a thousands separator. Note that the "value" is not localized (and is given in meters) - it gives this when given language=en for the localization and units=metric :

     "elements" : [
        {
           "distance" : {
              "text" : "4,500 km",
              "value" : 4499875
           },
           "duration" : {
              "text" : "1 day 16 hours",
              "value" : 144859
           },
           "status" : "OK"
        }
     ]

The quick fix is to change the regex pattern as mentioned in the comments to...

regex.Pattern = """text"".*?([0-9,]+)" 

...and the request to:

lastVal = "&mode=car&language=en&units=imperial&sensor=false"

Although I would actually recommend pulling the non-localized "value" instead of the localized "text", and then converting to miles if you need imperial units.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM