Try this
To start with worksheet looks like this
Excel 2016 (Windows) 32 bit
[Table="width:, class:head"][tr=bgcolor:#E0E0F0][th] [/th][th]A
[/th][th]B
[/th][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]1
[/td][td]17.695367
[/td][td]-94.882509
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]2
[/td][td]22.604667
[/td][td]-89.515209
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]3
[/td][td]20.978867
[/td][td]-89.262209
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]4
[/td][td]19.682367
[/td][td]-87.809709
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]5
[/td][td]19.957467
[/td][td]-91.277409
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]6
[/td][td]20.025367
[/td][td]-86.121809
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]7
[/td][td]21.344367
[/td][td]-93.437609
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]8
[/td][td]26.171767
[/td][td]-90.014609
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]9
[/td][td]27.427167
[/td][td]-93.532009
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]10
[/td][td]20.042567
[/td][td]-87.880009
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]11
[/td][td]24.227967
[/td][td]-88.523609
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]12
[/td][td]24.139467
[/td][td]-93.652109
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]13
[/td][td]25.026667
[/td][td]-86.809209
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]14
[/td][td]19.714567
[/td][td]-91.068309
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]15
[/td][td]27.213467
[/td][td]-87.960409
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]16
[/td][td]24.800967
[/td][td]-92.572709
[/td][/tr]
[/table][Table="width:, class:grid"][tr][td]Sheet:
Sheet1[/td][/tr][/table]
I asked for 10 values to be returned :
Excel 2016 (Windows) 32 bit
[Table="width:, class:head"][tr=bgcolor:#E0E0F0][th] [/th][th]A
[/th][th]B
[/th][th]C
[/th][th]D
[/th][th]E
[/th][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]1
[/td][td]21.50117
[/td][td]-91.1147
[/td][td]21.49797
[/td][td]-91.12
[/td][td]0.406253
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]2
[/td][td]18.94137
[/td][td]-87.4702
[/td][td]18.94487
[/td][td]-87.4756
[/td][td]0.427896
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]3
[/td][td]19.01427
[/td][td]-90.0209
[/td][td]19.01157
[/td][td]-90.0282
[/td][td]0.512166
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]4
[/td][td]21.91217
[/td][td]-93.2721
[/td][td]21.92447
[/td][td]-93.2732
[/td][td]0.85295
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]5
[/td][td]20.12217
[/td][td]-89.9606
[/td][td]20.11197
[/td][td]-89.9746
[/td][td]1.149885
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]6
[/td][td]21.50377
[/td][td]-93.494
[/td][td]21.48577
[/td][td]-93.4935
[/td][td]1.244361
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]7
[/td][td]25.13587
[/td][td]-86.2795
[/td][td]25.13527
[/td][td]-86.2994
[/td][td]1.245712
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]8
[/td][td]20.11167
[/td][td]-87.9784
[/td][td]20.10727
[/td][td]-87.9595
[/td][td]1.263648
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]9
[/td][td]20.23217
[/td][td]-85.3814
[/td][td]20.22367
[/td][td]-85.3998
[/td][td]1.329925
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]10
[/td][td]27.59177
[/td][td]-87.1582
[/td][td]27.59537
[/td][td]-87.1796
[/td][td]1.334098
[/td][/tr]
[tr=bgcolor:#FFFFFF][td=bgcolor:#E0E0F0]11
[/td][td][/td][td][/td][td][/td][td][/td][td][/td][/tr]
[/table][Table="width:, class:grid"][tr][td]Sheet:
Results 190724 10.18 pm[/td][/tr][/table]
Test on a COPY of your workbook!
Place the code in a NEW standard module
Code:
[B][COLOR=#006400]'this goes at TOP of module ABOVE all procedures[/COLOR][/B]
Option Explicit
Private List() As Variant, Pairs() As Double
Const Limit As Long = 500000
Private PairCount As Long, ResultsCount As Long, Results As Worksheet, Data As Worksheet
[B][COLOR=#006400]'procedures [/COLOR][/B]
Sub Strat919()
Dim t As Double: t = Timer
ResultsCount = InputBox("How many items to output ?", "User choice", 100)
Call GeneratePairs
Call GenerateResults
MsgBox Round(Timer - t, 1) & " seconds"
End Sub
Code:
Private Sub GeneratePairs()
Dim a As Long, b As Long, r As Long
Set Data = [COLOR=#ff0000]ActiveSheet[/COLOR]
List = Data.Range("A1", Data.Range("A" & Data.Rows.Count).End(xlUp)).Resize(, 2)
PairCount = (UBound(List) ^ 2 - UBound(List)) / 2
ReDim Pairs(1 To PairCount, 1 To 5)
'place paired values in array and calculate distance
For a = 1 To UBound(List)
For b = 1 To UBound(List)
If b < a Then
r = r + 1
Pairs(r, 1) = List(a, 1)
Pairs(r, 2) = List(a, 2)
Pairs(r, 3) = List(b, 1)
Pairs(r, 4) = List(b, 2)
Pairs(r, 5) = GetDistance(Pairs(r, 1), Pairs(r, 2), Pairs(r, 3), Pairs(r, 4))
End If
Next b
Next a
End Sub
Private Function GetDistance(ByVal Lat1, ByVal Long1, ByVal Lat2, ByVal Long2)
With WorksheetFunction
GetDistance = 6371 * .Acos(Cos(.Radians(90 - Lat1)) * Cos(.Radians(90 - Lat2)) + Sin(.Radians(90 - Lat1)) * Sin(.Radians(90 - Lat2)) * Cos(.Radians(Long1 - Long2))) / 1.609
End With
End Function
Code:
Private Sub GenerateResults()
Dim r2 As Long, r1 As Long, c As Long, LimitCount As Long, Remainder As Long
[I][COLOR=#006400]'insert new worksheet[/COLOR][/I]
Set Results = Sheets.Add(before:=Sheets(1))
Results.Name = "Results " & Format(Now, "yymmdd h.mm am/pm")
[COLOR=#006400][I]'how many times to move subsets of values?, how many items in last subset?[/I][/COLOR]
LimitCount = WorksheetFunction.RoundDown(PairCount / Limit, 0)
Remainder = PairCount Mod Limit
[I][COLOR=#006400]'move each subset in sequence[/COLOR][/I]
r1 = 1
For c = 1 To LimitCount
r2 = r2 + Limit
Call MoveSubset(r1, r2)
r1 = r1 + Limit
Next c
If Remainder > 0 Then
r2 = r2 + Remainder
Call MoveSubset(r1, r2)
End If
End Sub
Private Sub MoveSubset(firstItem As Long, lastItem As Long)
Application.ScreenUpdating = False
Dim rTemp As Long, r As Long, c As Long, tempArr()
ReDim tempArr(1 To lastItem - firstItem + 1, 1 To 5)
[I][COLOR=#006400]'move to temp array[/COLOR][/I]
For r = firstItem To lastItem
rTemp = rTemp + 1
For c = 1 To 5
tempArr(rTemp, c) = Pairs(r, c)
Next c
Next r
[I][COLOR=#006400]'write to worksheet, sort and clear rows not required[/COLOR][/I]
Results.Cells(Results.Rows.Count, 1).End(xlUp).Offset(1).Resize(UBound(tempArr), 5) = tempArr
Results.Range("A:E").Sort Key1:=Results.Range("E1"), Order1:=xlAscending, Header:=xlNo
Results.Range("A1").Offset(ResultsCount).Resize(Limit, 5).ClearContents
End Sub
VBA actions
- the user is asked how many items to return (let's assume user wants
200 )
- co-ordinates in columns A and B of active sheet are written to a 2 column array
- possible pairings are determined, distances calculated and values written to a 5 column array
- results are written to a new worksheet
- a restricted no of items are written to the worksheet, sorted (ascending), and the first
200 rows retained
- the restriction is the value of constant Limit
- then next batch of items are witten to the sheet (now contains Limit + 200), sorted and the first
200 rows retained
etc until all values dealt with
Trapping errors etc
- have not had time to be sophisticated
- what could cause VBA problems with your data ( text instead of values, no values , values that break the formula etc)
- can incorporate error checking later
User Options
- do you always want the shortest distances ?
- what else is required ?
Let me know how you get on