Voici la feuille de calcul, dans une archive zip, dont il est question dans le document ci-dessus. Elle permet de convertir un code Locator vers des coordonnées latitude longitude, ainsi que le calcul de l’azimut pour orienter une antenne et la distance entre deux points Locator. Pour que le calcul fonctionne, il faut activer le contenu actif pour autoriser l’exécution des macro dans Excel. Un bouton apparait pour ce type de document, il faut cliquer sur activer le contenu :

Le code Visual Basic permettant les conversions :
Function FindLat(ByVal Locator As String) As Double
Dim Field As String
Dim Square As String
Dim SubSquare As String
Dim ExtendedSquare As String
Dim SuperExtendedSquare As String
Dim CodeLength As Integer
Dim Sum As Double
' Extraction des caractères de la latitude
Field = Mid(Locator, 2, 1)
Square = Mid(Locator, 4, 1)
SubSquare = Mid(Locator, 6, 1)
ExtendedSquare = Mid(Locator, 8, 1)
SuperExtendedSquare = Mid(Locator, 10, 1)
' Détection de la longueur du code (nombre de paires)
If Field <> "" Then CodeLength = 1
If Square <> "" Then CodeLength = 2
If SubSquare <> "" Then CodeLength = 3
If ExtendedSquare <> "" Then CodeLength = 4
If SuperExtendedSquare <> "" Then CodeLength = 5
' Conversion en majuscules pour les paires en lettres
Field = UCase(Field)
SubSquare = UCase(SubSquare)
SuperExtendedSquare = UCase(SuperExtendedSquare)
' Conversion des codes ASCII en valeurs décimales, si nécessaire
If CodeLength >= 1 Then Field = Asc(Field) - Asc("A")
If CodeLength >= 2 Then Square = Asc(Square) - Asc("0")
If CodeLength >= 3 Then SubSquare = Asc(SubSquare) - Asc("A")
If CodeLength >= 4 Then ExtendedSquare = Asc(ExtendedSquare) - Asc("0")
If CodeLength >= 5 Then SuperExtendedSquare = Asc(SuperExtendedSquare) - Asc("A")
' Calcul de la somme des paires de codage, plus la moitié d'un carreau de la plus petite paire de codage
Select Case CodeLength
Case 1
Sum = 10 * Field + 5
Case 2
Sum = 10 * Field + Square * 0.5
Case 3
Sum = 10 * Field + Square + SubSquare / 24 + 0.5 / 24
Case 4
Sum = 10 * Field + Square + SubSquare / 24 + ExtendedSquare / 240 + 0.5 / 240
Case 5
Sum = 10 * Field + Square + SubSquare / 24 + ExtendedSquare / 240 + SuperExtendedSquare / 5760 + 0.5 / 5760
End Select
' Retourner la latitude
If CodeLength >= 1 Then FindLat = Round(Sum - 90, 6)
End Function
Function FindLong(ByVal Locator As String) As Double
Dim Field As String
Dim Square As String
Dim SubSquare As String
Dim ExtendedSquare As String
Dim SuperExtendedSquare As String
Dim CodeLength As Integer
Dim Sum As Double
' Extraction des caractères de la longitude
Field = Mid(Locator, 1, 1)
Square = Mid(Locator, 3, 1)
SubSquare = Mid(Locator, 5, 1)
ExtendedSquare = Mid(Locator, 7, 1)
SuperExtendedSquare = Mid(Locator, 9, 1)
' Détection de la longueur du code (nombre de paires)
If Field <> "" Then CodeLength = 1
If Square <> "" Then CodeLength = 2
If SubSquare <> "" Then CodeLength = 3
If ExtendedSquare <> "" Then CodeLength = 4
If SuperExtendedSquare <> "" Then CodeLength = 5
' Conversion en majuscules pour les paires en lettres
Field = UCase(Field)
SubSquare = UCase(SubSquare)
SuperExtendedSquare = UCase(SuperExtendedSquare)
' Conversion des codes ASCII en valeurs décimales, si nécessaire
If CodeLength >= 1 Then Field = Asc(Field) - Asc("A")
If CodeLength >= 2 Then Square = Asc(Square) - Asc("0")
If CodeLength >= 3 Then SubSquare = Asc(SubSquare) - Asc("A")
If CodeLength >= 4 Then ExtendedSquare = Asc(ExtendedSquare) - Asc("0")
If CodeLength >= 5 Then SuperExtendedSquare = Asc(SuperExtendedSquare) - Asc("A")
' Calcul de la somme des paires de codage, plus la moitié d'un carreau de la plus petite paire de codage
Select Case CodeLength
Case 1
Sum = 20 * Field + 5
Case 2
Sum = 20 * Field + 2 * Square + 0.5 * 2
Case 3
Sum = 20 * Field + 2 * Square + SubSquare / 12 + 0.5 / 12
Case 4
Sum = 20 * Field + 2 * Square + SubSquare / 12 + ExtendedSquare / 120 + 0.5 / 120
Case 5
Sum = 20 * Field + 2 * Square + SubSquare / 12 + ExtendedSquare / 120 + SuperExtendedSquare / 2880 + 0.5 / 2880
End Select
' Retourner la longitude
If CodeLength >= 1 Then FindLong = Round(Sum - 180, 6)
End Function
Function FindDistance(ByVal Lat1 As Double, ByVal Long1 As Double, ByVal Lat2 As Double, ByVal Long2 As Double) As Double
Dim r As Double
Dim p As Double
Dim angle As Double
'rayon de la terre en km
r = 6371
'pi / 180, pour conversion en radian
p = WorksheetFunction.Pi / 180
'conversions en radians
Lat1 = Lat1 * p
Lat2 = Lat2 * p
Long1 = Long1 * p
Long2 = Long2 * p
'calcul de l'angle solide au centre, loi des cosinus sphériques
angle = WorksheetFunction.Acos(Sin(Lat1) * Sin(Lat2) + Cos(Lat1) * Cos(Lat2) * Cos(Long2 - Long1))
FindDistance = r * angle
End Function
Function FindDistanceHaversine(ByVal Lat1 As Double, ByVal Long1 As Double, ByVal Lat2 As Double, ByVal Long2 As Double) As Double
Dim r As Double
Dim p As Double
Dim calc As Double
Dim angle As Double
Dim DeltaLat As Double
Dim DeltaLong As Double
'rayon de la terre en km
r = 6371
'pi / 180, pour conversion en radian
p = WorksheetFunction.Pi / 180
'conversions en radians
Lat1 = Lat1 * p
Lat2 = Lat2 * p
Long1 = Long1 * p
Long2 = Long2 * p
DeltaLat = Lat2 - Lat1
DeltaLong = Long2 - Long1
'calcul de l'angle solide au centre, formule de Haversine
calc = Sin(DeltaLat / 2) ^ 2 + Cos(Lat1) * Cos(Lat2) * Sin(DeltaLong / 2) ^ 2
angle = 2 * WorksheetFunction.Atan2(Sqr(1 - calc), Sqr(calc))
FindDistanceHaversine = r * angle
End Function
Function FindStartAzimut(ByVal Lat1 As Double, ByVal Long1 As Double, ByVal Lat2 As Double, ByVal Long2 As Double) As Double
Dim p As Double
Dim calc As Double
Dim angle As Double
Dim DeltaLat As Double
Dim DeltaLong As Double
'pi / 180, pour conversion en radian
p = WorksheetFunction.Pi / 180
'conversions en radians
Lat1 = Lat1 * p
Lat2 = Lat2 * p
Long1 = Long1 * p
Long2 = Long2 * p
DeltaLong = Long2 - Long1
'calcul de l'azimut de départ
FindStartAzimut = WorksheetFunction.Atan2(Cos(Lat1) * Sin(Lat2) - Sin(Lat1) * Cos(Lat2) * Cos(DeltaLong), Sin(DeltaLong) * Cos(Lat2))
'conversion -180° à +180° vers 0 à 360°
FindStartAzimut = ModuloFP((FindStartAzimut / p), 360)
End Function
Function FindEndAzimut(ByVal Lat2 As Double, ByVal Long2 As Double, ByVal Lat1 As Double, ByVal Long1 As Double) As Double
Dim p As Double
Dim calc As Double
Dim angle As Double
Dim DeltaLat As Double
Dim DeltaLong As Double
'pi / 180, pour conversion en radian
p = WorksheetFunction.Pi / 180
'conversions en radians
Lat1 = Lat1 * p
Lat2 = Lat2 * p
Long1 = Long1 * p
Long2 = Long2 * p
DeltaLong = Long2 - Long1
'calcul de l'azimut de départ
FindEndAzimut = WorksheetFunction.Atan2(Cos(Lat1) * Sin(Lat2) - Sin(Lat1) * Cos(Lat2) * Cos(DeltaLong), Sin(DeltaLong) * Cos(Lat2))
'conversion -180° à +180° vers 0 à 360°
FindEndAzimut = ModuloFP((FindEndAzimut / p - 180), 360)
End Function
Function FindReturnAzimut(ByVal Lat2 As Double, ByVal Long2 As Double, ByVal Lat1 As Double, ByVal Long1 As Double) As Double
Dim p As Double
Dim calc As Double
Dim angle As Double
Dim DeltaLat As Double
Dim DeltaLong As Double
'pi / 180, pour conversion en radian
p = WorksheetFunction.Pi / 180
'conversions en radians
Lat1 = Lat1 * p
Lat2 = Lat2 * p
Long1 = Long1 * p
Long2 = Long2 * p
DeltaLong = Long2 - Long1
'calcul de l'azimut de départ
FindReturnAzimut = WorksheetFunction.Atan2(Cos(Lat1) * Sin(Lat2) - Sin(Lat1) * Cos(Lat2) * Cos(DeltaLong), Sin(DeltaLong) * Cos(Lat2))
'conversion -180° à +180° vers 0 à 360°
FindReturnAzimut = ModuloFP((FindReturnAzimut / p), 360)
End Function
Function DD_to_DMS(ByVal DD As Double, ByVal Precision As Integer) As String
Dim Partie_decimale_degres
Dim Partie_decimale_minutes
Dim Partie_entiere_degres
Dim Partie_entiere_minutes
Dim Minutes
Dim Secondes
Dim DD_abs
Dim Signe
'supression du signe
DD_abs = Abs(DD)
'Séparation des parties entière et décimale des degrés
Partie_decimale_degres = DD_abs - Int(DD_abs)
Partie_entiere_degres = Int(DD_abs)
'Ajout d'un ou deux zéro non significatifs si besoin sur les degrés
If Partie_entiere_degres < 10 Then
Partie_entiere_degres = "00" & Partie_entiere_degres
ElseIf Partie_entiere_degres < 100 Then
Partie_entiere_degres = "0" & Partie_entiere_degres
End If
'conversion en minutes
Minutes = Partie_decimale_degres * 60
'Séparation des parties entière et décimale des minutes
Partie_decimale_minutes = Minutes - Int(Minutes)
Partie_entiere_minutes = Int(Minutes)
'Ajout d'un zéro non significatif si besoin sur les minutes
If Partie_entiere_minutes < 10 Then Partie_entiere_minutes = "0" & Partie_entiere_minutes
'Conversion en secondes et arrondi
Secondes = WorksheetFunction.RoundDown(Partie_decimale_minutes * 60, Precision)
'Ajout d'un zéro non significatif si besoin sur les secondes
If Secondes < 10 Then Secondes = "0" & Secondes
'Remise en place du signe et concatenation
If Sgn(DD) = -1 Then Signe = "-"
DD_to_DMS = Signe & Partie_entiere_degres & "° " & Partie_entiere_minutes & "' " & Secondes & """"
End Function
Function ModuloFP(Numerateur As Double, Denominateur As Double) As Double
ModuloFP = Numerateur - Denominateur * Int(Numerateur / Denominateur)
End Function