Excel VBA Course
Excel VBA Course - From Beginner to Expert

200+ Video Lessons
50+ Hours of Video
200+ Excel Guides

Become a master of VBA and Macros in Excel and learn how to automate all of your tasks in Excel with this online course. (No VBA experience required.)

View Course

Macro for calculating Inter location distances

0

Hello,

I have a set of data ( as enclosed) where there are various locations with latitudes and longitudes against each location. I want to calculate inter locations distances and analyse how many of them ( for each location) are located within 100mtrs of that location. I want to calculate this for each location. Secondly for each of these location, I need to know which are these locations which are within 100mtrs of that particular location separated by comma. So I need to populate Column D (count) and E (Locations separated by comma). The excel sheet is enclosed for you reference

Answer
Discuss

Discussion

Are all the places in your sheets all in close proximity to each other, or all far apart?
I can create code to populate your sheet, but the distances all seem  to be similar.
Are you sure that the code for calculating the required distances is correct as I have found an alernative method which produces a smaller distance.
wjwestcott Jan 24, '22 at 6:25 am
I had randomly selected some locations which may be located nearby. The formula seems to be OK which gives distsnces in meters. Could you please check whether the unit is in meter or miles. 
Thanks for your interest
mailtoskt (rep: 2) Jan 24, '22 at 7:22 am
mailtoskt- you gave the formula in your sheet- this is a Forum to solve Excel  problems (not to check geography/ arithmetical formulas!).

My macro implements the formula (in VBA) but where did you get the formula? If it's in miles, not metres then the difference will only be the divisor (6371000)
John_Ru (rep: 6142) Jan 24, '22 at 8:10 am
John_Ru- The above comment was made in reference to the solution proposed by wjwestcott ( Actual code was shared later, hence I had made suggestion as above to check the units). 
mailtoskt (rep: 2) Jan 24, '22 at 11:16 am
If "Actual code was shared later" by wjwestcott (rather than me, below) then I haven't seen it. My point remains that I have worked with your formula and believe it is correctly implemented in my macro. If the formula is wrong, the results will be wrong.

I've made another comment in the discussion below my Answer but you haven't responded yet. I won't do any more on this until I hear from you.
John_Ru (rep: 6142) Jan 24, '22 at 11:28 am
"Are all the places in your sheets all in close proximity to each other, or all far apart? I can create code to populate your sheet, but the distances all seem  to be similar.
Are you sure that the code for calculating the required distances is correct as I have found an alernative method which produces a smaller distance.
wjwestcott Jan 24, '22 at 3:55 pm"
I had made comments on the inputs shared by wjwestcott  as he had mentioned that he is getting smaller distances. Hope this clarifies
mailtoskt (rep: 2) Jan 24, '22 at 2:23 pm
mailtoskt- it seems likely that wjwestcott  "is getting smaller distances" by virtue of using a different formula. Whether that formula is right (or the one you gave is right) I cannot say but my method works (with the correct formula).

Accordingly I will now do nothing more (and probably delete my Answer tomorrow since you can't judge if it's right or wrong!)
John_Ru (rep: 6142) Jan 24, '22 at 3:55 pm
@mailtoskt - I've now deleted my Answer (as I said above) since I don't want my working VBA code associated with your seemingly suspect formula- that might mar my good reputation on the Forum.

@wjwestcott - suggest you provide now your Answer citing the source of your formula and preferably using at least 2 known locations/1 known distance between (maybe verified by Google Maps or similar. Not sure why the user didn't do that for some of his Delhi convenience store co-ordinates before posing the question!
John_Ru (rep: 6142) Jan 25, '22 at 8:14 am
@John_Ru : I could not respond to your earlier message as I was not available. My formula is OK which can be compared with the distances on Goggle Map. 
I regret that I could not judge this yesterday.Thanks for your effort
mailtoskt (rep: 2) Jan 25, '22 at 11:40 am
If that's the case none of your cited locations are within 100m of each other but I will restore my Answer now. Hope you will mark it as Selected.
John_Ru (rep: 6142) Jan 25, '22 at 12:59 pm
Add to Discussion

Answers

0
Selected Answer

Hi and welcome to the Forum

In the revised (macro-enabled) file, I've moved your formula information (in A18;A19) one cell to the right. This lets VBA calculate the last row used in column A and you to make the table 15 rows, 250 rows or whatever (up to the Excel limit).

There's a button in row 1 called "Calculate interlocation distances"- click that and it will call the macro below. Note that the message box offers a default value of 4,000m (which you can change) which will give meaningful results since, if your formula is correct, for the first 15 (original) locations there were no locations within 100m of each other as your question requests. Using 1,500 gives 1 "neighbour" for most locations.

Note that I've set the output to also show the interlocation distances (to two decimal places) in column E so you can check that the calculations have be done correctly.

REVISION: in a file you posted as an Answer, you had about 5,000 rows of data. Turns out some rows had the same latitude and longitude (e.g. rows 16 and 19) which caused the ACOS function to fail (I think it was a divide by zero error so you were asking for the arc cosine of an indeterminate number. I've added a new IF trap to avoid performing than calculation when the co-ordinates are the same. (As the revised file leaves me, Targ is set to 100 and you'll see lots of location pairs where the distance between is zero)

The code below is commented for your guidance about VBA actions. Note that the first line is important for the way the array is handled:

Option Base 1

Sub LessThanTarg()

Dim DataArray() As Variant, Rw As Long, LstRw As Long, Rw2 As Long
Dim Dist As Double, Pi As Double, Targ As String

'get threshold from user
Targ = InputBox("Maximum interlocation distance?", "What threshold do you want?", 4000)
    If Targ = "" Or Not IsNumeric(Targ) Then Exit Sub

' set Pi (not a VBA Constant)
Pi = WorksheetFunction.Pi
' get last row in column A
LstRw = Range("A" & Rows.Count).End(xlUp).Row
' clear results columns
Range("D2:E" & LstRw).ClearContents
'grab data to array
DataArray = Range("A2:E" & LstRw).Value

'Loop first set of co-ordinates
For Rw = 1 To LstRw - 1
    'Loop second sets of co-ordinates
    For Rw2 = Rw + 1 To LstRw - 1
            'set values for formula
            Lat1 = DataArray(Rw, 2)
            Lon1 = DataArray(Rw, 3)
            Lat2 = DataArray(Rw2, 2)
            Lon2 = DataArray(Rw2, 3)
        If (Lat1 = Lat2) And (Lon1 = Lon2) Then
            'same place so avoid 0/0 error in calculation
            Dist = 0
            Else
            ' calculate distance from data above using VBA functions and worksheet function ACOS (not covered by VBA)
            Dist = WorksheetFunction.Acos(Sin(Lat1 * Pi / 180) * Sin(Lat2 * Pi / 180) + Cos(Lat1 * Pi / 180) * Cos(Lat2 * Pi / 180) * Cos(Lon2 * Pi / 180 - Lon1 * Pi / 180)) * 6371000
        End If
        'compare distance with threshold
        
        If Dist < CDbl(Targ) Then
            'If less, write/add to the array
            DataArray(Rw, 4) = DataArray(Rw, 4) + 1
            DataArray(Rw, 5) = DataArray(Rw, 5) & DataArray(Rw2, 1) & " (" & Format(Dist, "#,##0.00") & "m), "
            DataArray(Rw2, 4) = DataArray(Rw2, 4) + 1
            DataArray(Rw2, 5) = DataArray(Rw2, 5) & DataArray(Rw, 1) & " (" & Format(Dist, "#,##0.00") & "m), "
        End If
        
    Next Rw2

Next Rw

'write data back to worksheet
Range("A2:E" & LstRw).Value = DataArray()
' revised column D heading
Range("D1").Value = "Count of locations within " & Targ & " meters of other locations"

MsgBox "Data written and cell D1 revised to " & Targ & "m"

End Sub

Incidentally, your sheet had thousands and thousands of blank rows and columns so I copied your data to another sheet (and deleted the first sheet) so that the used range was reset to something like normal ($A$1:$J$20 for me).

Hope this helps.

Discuss

Discussion

p.s. you'll see I added a note (in yellow cells in the file) about a website which verifies your formula- perhaps that's where you got the Excel version mentioned.
John_Ru (rep: 6142) Jan 25, '22 at 1:07 pm
Hi @John_Ru- Please review my comments in response to your last revert. There is some error which needs to be corrected.
mailtoskt (rep: 2) Jan 29, '22 at 2:44 pm
Sorry butI declared Targ incorrectly- it should be a String (since that's what an InputBox returns) - my error. Commenting it out just makes it undeclared (so VBA assumes it's a Variant). I my revised Answer/file, I've corrected that and made these changes to cater for you putting the same co-ordinates in many rows:
        If (Lat1 = Lat2) And (Lon1 = Lon2) Then
        'same place so avoid 0/0 error in calculation
            Dist = 0
            Else
            ' calculate distance from data above using VBA functions and worksheet function ACOS (not covered by VBA)
            Dist = WorksheetFunction.Acos(Sin(Lat1 * Pi / 180) * Sin(Lat2 * Pi / 180) + Cos(Lat1 * Pi / 180) * Cos(Lat2 * Pi / 180) * Cos(Lon2 * Pi / 180 - Lon1 * Pi / 180)) * 6371000
        End If
        'compare distance with threshold
        
        If Dist < CDbl(Targ) Then
I can't guarantee that the code will work perfectly since you're asking it to do many calculations but then your purpose doesn't seem too important to avoid the aoccasional hang up (to me at least!)
John_Ru (rep: 6142) Jan 29, '22 at 5:34 pm
Add to Discussion
0

 @John_Ru- Thanks for your notings regarding the formula. 

I wanted to generalise this program by adding another set of say 4985 locations ( plus/minus 0.001 in lat-longs from each other) and it is throwing exception. Possibly related to some declaration of variable "Targ" in the code. I tried changing the declaration of this variable "Targ" ( ie putting this variable as comment by placing a comma), then it works with the original set of data of 15 lines,not with this 5000 lines. It needs some review at your end. 

Discuss

Discussion

Please note that Answers should be used for solutions to problems- comments like this should be under the Discussion below the Answer.

I've responded to you via a revision to my answer and a comment in the Discussion for that.
John_Ru (rep: 6142) Jan 29, '22 at 5:31 pm
Add to Discussion


Answer the Question

You must create an account to use the forum. Create an Account or Login