Speculative thinking, say you have a list of 615 addresses. How do you find the nearest three locations to each address?

RockandGrohl

Well-known Member
Joined
Aug 1, 2018
Messages
790
Office Version
  1. 365
Platform
  1. Windows
Let's say you have 1,400 postcodes that correspond to a point on a map. Using a location local(ish) to me, in the UK I have 615 locations across England. I want to find the nearest three for each of the 615 locations, in that same list.

So as an example we choose Gloucester. Geographically near Gloucester in my list of 615 addresses, we have Cheltenham, Stroud, Tewkesbury, and then further afield are Cirencester, Ross-on-Wye, Ledbury.

The closest three are Cheltenham, Stroud & Tewkesbury and I would like this to be reflected. The only information I have is postcode, so this would need to link in to mapping functionality somehow. I'm just wondering if anyone does anything similar and whether this technique is used in anyone's existing processes.

Thanks!
 

Excel Facts

Test for Multiple Conditions in IF?
Use AND(test, test, test, test) or OR(test, test, test, ...) as the logical_test argument of IF.
EDIT: Oh-ohoho, this is transforming into an SQL level question. I have the Lat/Long of each postcode on our database. In case anyone stumbles upont this, I think you may even be able to work this out using Excel, if I'm correct in assuming that the Haversine Formula is multiplying the Long/Lat values to find close matches.

SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;


So as long as you convert acos, cos, radians into formula... I guess this can work. BRB, let me keep working on this.
 
Last edited:
Upvote 0
First of all, woow, nice.
I would get all 1400 (615) postal code UTM (in mm), i guess its available online somewhere. Then use a simple subtraction for N and E values from your location UTM coordinate. The smallest cumulative is closest, in straigth line.

yourlocation: YL
postalcodelocaton: PL

North: PLN-YLN = ND (north distance)
East: PLE-YLN = ED (east distance)
ND^2+ED^2= D^2 (distance)


Love to see your result! :)


ps.: my colleagaue said: use google darnit :D
 
Last edited:
Upvote 0
this work for a small sample of 20, should work for a larger date.
you can get the lat & longit here


Book1
ABCDEFGHIJ
1idpostcodelatitudelongitudelatitudelongitude
21AB10 1XG57.14416516-2.1148477680.145679Nearest toAB12 5GL57.08193792-2.246567389
32AB10 6RN57.13787976-2.1214866880.1370211AB14 0TQ
43AB10 7JB57.12427377-2.1271896440.1266622AB15 8UF
54AB11 5QN57.14270109-2.0932950.1648773AB15 9SE
65AB11 6UL57.13754663-2.1122330.145389
76AB11 8RQ57.13597762-2.0721147840.182631
87AB12 3FJ57.0980029-2.0774380.169891
98AB12 4NA57.06427275-2.1300180150.117881
109AB12 5GL57.08193792-2.2465673890
1110AB12 9SP57.14870708-2.0978060270.163058
1211AB14 0TQ57.10155692-2.2684857520.029416
1312AB15 5HB57.147428-2.14726620.118952
1413AB15 6NA57.151797-2.1853980.092855
1515AB15 8UF57.15400596-2.224401880.0754
1616AB15 9SE57.11864762-2.1742506070.081101
1717AB16 5ST57.16346588-2.159333430.119401
1818AB16 6SZ57.15875117-2.1652148610.111886
1919AB16 7NX57.1684384-2.1616360.121226
2020AB21 0AL57.26342-2.1586050.201676
Sheet1
Cell Formulas
RangeFormula
I2:J2I2=INDEX(C2:C20,MATCH($H2,$B$2:$B$20,0))
H3:H5H3=INDEX($B$2:$B$20,MATCH(ROUND(SMALL($E$2:$E$20,G3+1),6),$E$2:$E$20,0))
E2:E20E2=ROUND(((C2-$I$2)^2+(D2-$J$2)^2)^0.5,6)
 
Upvote 0
Seems like it will work, but I have no idea how to get the closest three results for each line. So I have 615 lines and each has a Lat & Long value. So each line needs to check against 614 lines and find the 1st, 2nd and 3rd closest location and then display them.

=ACOS(COS(RADIANS(90-$E$2)) *COS(RADIANS(90-E3)) +SIN(RADIANS(90-$E$2)) *SIN(RADIANS(90-E3)) *COS(RADIANS($F$2-F3))) *3958.756


My cords are in column E and F, and placenames are in column C.

So I need to take the cords of the first row of data (2), then calculate the entire column and get the min 1, then the min 2 in the next cell and min 3 in the next cell.

Thinking this might evolve to VBA as I need to effectively calculate the whole set of data for each line and then grab the min.
 
Upvote 0
Seems like it will work, but I have no idea how to get the closest three results for each line. So I have 615 lines and each has a Lat & Long value. So each line needs to check against 614 lines and find the 1st, 2nd and 3rd closest location and then display them.

=ACOS(COS(RADIANS(90-$E$2)) *COS(RADIANS(90-E3)) +SIN(RADIANS(90-$E$2)) *SIN(RADIANS(90-E3)) *COS(RADIANS($F$2-F3))) *3958.756


My cords are in column E and F, and placenames are in column C.

So I need to take the cords of the first row of data (2), then calculate the entire column and get the min 1, then the min 2 in the next cell and min 3 in the next cell.

Thinking this might evolve to VBA as I need to effectively calculate the whole set of data for each line and then grab the min.

Column E calculated the distance from AB12 5GL in H2, simply by A^2 = B^2 + C^2.
H3 to H5 are the 3 closest

 
Upvote 0
Column E calculated the distance from AB12 5GL in H2, simply by A^2 = B^2 + C^2.
H3 to H5 are the 3 closest

He/she need a 2D matrix for all postal code. and tag(condition format) the 3 smallest of each row and colum
Maybe i confuse you. When i wrote yourlocation i meant for the actual/desired postalcodelocation. YL = PL1 and PL = PL2 -> PL1N-PL2N and PL1E-PL2E
 
Last edited:
Upvote 0
apology, the distance calculation is rubbish, but found this on other forum should do the job

 
Upvote 0
this work for a small sample of 20, should work for a larger date.
you can get the lat & longit here


Book1
ABCDEFGHIJ
1idpostcodelatitudelongitudelatitudelongitude
21AB10 1XG57.14416516-2.1148477680.145679Nearest toAB12 5GL57.08193792-2.246567389
32AB10 6RN57.13787976-2.1214866880.1370211AB14 0TQ
43AB10 7JB57.12427377-2.1271896440.1266622AB15 8UF
54AB11 5QN57.14270109-2.0932950.1648773AB15 9SE
65AB11 6UL57.13754663-2.1122330.145389
76AB11 8RQ57.13597762-2.0721147840.182631
87AB12 3FJ57.0980029-2.0774380.169891
98AB12 4NA57.06427275-2.1300180150.117881
109AB12 5GL57.08193792-2.2465673890
1110AB12 9SP57.14870708-2.0978060270.163058
1211AB14 0TQ57.10155692-2.2684857520.029416
1312AB15 5HB57.147428-2.14726620.118952
1413AB15 6NA57.151797-2.1853980.092855
1515AB15 8UF57.15400596-2.224401880.0754
1616AB15 9SE57.11864762-2.1742506070.081101
1717AB16 5ST57.16346588-2.159333430.119401
1818AB16 6SZ57.15875117-2.1652148610.111886
1919AB16 7NX57.1684384-2.1616360.121226
2020AB21 0AL57.26342-2.1586050.201676
Sheet1
Cell Formulas
RangeFormula
I2:J2I2=INDEX(C2:C20,MATCH($H2,$B$2:$B$20,0))
H3:H5H3=INDEX($B$2:$B$20,MATCH(ROUND(SMALL($E$2:$E$20,G3+1),6),$E$2:$E$20,0))
E2:E20E2=ROUND(((C2-$I$2)^2+(D2-$J$2)^2)^0.5,6)


Hi bud,

so if I do this, but use a different way to calculate distance in miles, the formula doesn't work.

Instead of Distance being calculated like this:

VBA Code:
=ROUND(((E2-$M$2)^2+(F2-$N$2)^2)^0.5,6)

I have it like this

VBA Code:
=ACOS(COS(RADIANS(90-$E$2)) *COS(RADIANS(90-E2)) +SIN(RADIANS(90-$E$2)) *SIN(RADIANS(90-E2)) *COS(RADIANS($F$2-F2))) *3958.756

What I'm doing is dragging this formula down and it's comparing row 2 (the starting position) to the coordinates on that row.

Then there's the formula which determines the 1st, 2nd and 3rd set:

VBA Code:
=INDEX($C$2:$C$1160,MATCH(ROUND(SMALL($H$2:$H$1160,I1+1),6),$H$2:$H$1160,0))
This returns "Mountain Ash" - which is expected as this appears to be the closest in the list. However! This is using your distance calculation formula in column H. If I swap it, to use my distance calculation formula in column G as below:

VBA Code:
=INDEX($C$2:$C$1160,MATCH(ROUND(SMALL($G$2:$G$1160,I1+1),6),$G$2:$G$1160,0))
It then shows up as #N/A

There are numerical values only in both columns, however, yours looks like "3.87532" or "0.94214" etc, and mine is distance in miles and is always >0 (whether it's 310 or 0.06)

Really not sure why yours works but mine doesn't, on a different column.
 
Upvote 0
Hi bud,

so if I do this, but use a different way to calculate distance in miles, the formula doesn't work.

Instead of Distance being calculated like this:

VBA Code:
=ROUND(((E2-$M$2)^2+(F2-$N$2)^2)^0.5,6)

I have it like this

VBA Code:
=ACOS(COS(RADIANS(90-$E$2)) *COS(RADIANS(90-E2)) +SIN(RADIANS(90-$E$2)) *SIN(RADIANS(90-E2)) *COS(RADIANS($F$2-F2))) *3958.756

What I'm doing is dragging this formula down and it's comparing row 2 (the starting position) to the coordinates on that row.

Then there's the formula which determines the 1st, 2nd and 3rd set:

VBA Code:
=INDEX($C$2:$C$1160,MATCH(ROUND(SMALL($H$2:$H$1160,I1+1),6),$H$2:$H$1160,0))
This returns "Mountain Ash" - which is expected as this appears to be the closest in the list. However! This is using your distance calculation formula in column H. If I swap it, to use my distance calculation formula in column G as below:

VBA Code:
=INDEX($C$2:$C$1160,MATCH(ROUND(SMALL($G$2:$G$1160,I1+1),6),$G$2:$G$1160,0))
It then shows up as #N/A

There are numerical values only in both columns, however, yours looks like "3.87532" or "0.94214" etc, and mine is distance in miles and is always >0 (whether it's 310 or 0.06)

Really not sure why yours works but mine doesn't, on a different column.
it's most likely the rounding off errors, as you can see I rounded off Col. E and the 3 min distances to the same ROUND(...,6) so that they can be matched by the index/match function
 
Upvote 0

Forum statistics

Threads
1,215,030
Messages
6,122,762
Members
449,095
Latest member
m_smith_solihull

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top