Q:

Where is the error in my MS ACCESS VBA function to calculate a new latitude/longitude co-ordinate?

I have written a MS Access VBA function to calculate new latitude/longitude co-ordinates from a bearing and distance. However it is returning the wrong results and I can't see why. I used the formulae on https://www.movable-type.co.uk/scripts/latlong.html However when I test it against the calculator on that page, it gives the wrong results. For example NewLatLong(0, 0, 500, "K", 45) gives a latitude of 5.54656612024095E-02 and a longitude of 0. The latitude is correct after converting to degrees to compare with the calculator on the page, but why does the longitude come back as zero? The parameters for NewLatLong are original latitude and longitude in degrees, distance, distance unit (K = kilometers) and bearing clockwise from north in degrees.
MS Access does not have all the trigonometric fuctions required. I have provided new ones. These have been separately tested and appear to function correct.
I can't see what is wrong with my code. Can anyone help.
Public Function NewLatLong(latD As Double, longD As Double, distance As Double, unit As String, bearingD As Double) As Double()
    Dim latlong(2) As Double
    Dim latR As Double, bearingR As Double
    latR = Radians(latD)
    bearingR = Radians(bearingD)
    Dim cosAngDistance As Double, sinAngDistance As Double
    cosAngDistance = Cos(distance / EarthRadius(unit))
    sinAngDistance = Sin(distance / EarthRadius(unit))
    latlong(0) = ArcSine(Sin(latR) * cosAngDistance + Cos(latR) * sinAngDistance * Cos(bearingR))
    latlong(1) = (Radians(longD) + ArcTan2(Sin(bearingR) * sinAngDistance * Cos(latR), cosAngDistance - Sin(latR) * Sin(latlong(0))) + 540) Mod 360 - 180
    NewLatLong = latlong
    Debug.Print latlong(0) & " " & latlong(1)
End Function

Public Function EarthRadius(unit As String) As Double
    If (unit = "M") Then
        EarthRadius = 3963
    ElseIf (unit = "K") Then
        EarthRadius = 6371
    Else
        EarthRadius = 3443.753
    End If
End Function

Public Function Pi() As Double
    Pi = 4 * Atn(1)
End Function

Public Function ArcCosine(value As Double) As Double
    ArcCosine = Atn(-value / Sqr(-value * value + 1)) + 2 * Atn(1)
End Function

Public Function ArcSine(value As Double) As Double
    ArcSine = Atn(value / Sqr(-value * value + 1))
End Function

Public Function ArcTan2(y As Double, x As Double) As Double
    If x > 0 Then
        ArcTan2 = Atn(y / x)
    ElseIf x < 0 Then
        ArcTan2 = Sgn(y) * (Pi() - Atn(Abs(y / x)))
    ElseIf y = 0 Then
        ArcTan2 = 0
    Else
        ArcTan2 = Sgn(y) * Pi() / 2
    End If
End Function

Public Function Radians(degrees As Double) As Double
    Radians = degrees * Pi() / 180
End Function

A:

Good news and bad news. The good news is your code works almost perfectly, the bad news is the Mod operator always returns an integer regardless of the types of its parameters (why Microsoft!? why!?).
Instead of latlong(1) = (Radians(longD) + ArcTan2(Sin(bearingR) * sinAngDistance * Cos(latR), cosAngDistance - Sin(latR) * Sin(latlong(0))) + 540) Mod 360 - 180, use the code below to find the longitude
Dim tempLong As Double
tempLong = Radians(longD) + ArcTan2(Sin(bearingR) * sinAngDistance * Cos(latR), cosAngDistance - Sin(latR) * Sin(latlong(0)))
' set longitude if calculated value less than 1
If tempLong < 1 Then
    latlong(1) = tempLong
' if greater than 1, add decimal part back to modulus result
Else
    Dim decLong As Double
    decLong = tempLong
    While decLong > 1
        decLong = decLong - 1
    Wend
    latlong(1) = ((tempLong + 540) Mod 360 - 180) + decLong
End If

