考虑在VBA函数中使用半正向公式(借用here)。然后让它在你的SQL查询中调用。甚至可以按照您的需求通过WHERE
条款按距离过滤您的查询。请注意:此解决方案仅适用于MSAccess.exe程序。您将无法通过ODBC/OLEDB从外部调用它。
而且由于您需要比较地理编码,因此下面的SQL查询使用交叉连接,其中每个记录都与表中的每个其他记录进行比较。另外,查询避免了反向重复和相同匹配的配对,从而减小了大小。但是,如果表格很大,因为交叉连接对自我返回N 记录,即在重复过滤之前。
SQL
SELECT z1.Zipcode, z2.Zipcode,
GetDistance(z1.Lat, z1.Lon, z2.Lat, z2.Lon) As km_distance
FROM tblZip z1, tblZip z2
WHERE z1.Zipcode > z2.Zipcode
AND GetDistance(s1.lat, s1.lon, s1.lat, s2.lon) <= 5;
VBA(具有5 km或更小距离邮政编码配对)(独立模块中保存)
Function GetDistance(lat1Degrees As Double, lon1Degrees As Double, lat2Degrees As Double, lon2Degrees As Double) As Double
Dim earthSphereRadiusKilometers As Double
Dim kilometerConversionToMilesFactor As Double
Dim lat1Radians As Double
Dim lon1Radians As Double
Dim lat2Radians As Double
Dim lon2Radians As Double
Dim AsinBase As Double
Dim DerivedAsin As Double
'Mean radius of the earth (replace with 3443.89849 to get nautical miles)
earthSphereRadiusKilometers = 6371
'Convert kilometers into miles (replace 0.621371 with 1 to keep in kilometers)
kilometerConversionToMilesFactor = 0.621371
'Convert each decimal degree to radians
lat1Radians = (lat1Degrees/180) * (4 * ATN(1))
lon1Radians = (lon1Degrees/180) * (4 * ATN(1))
lat2Radians = (lat2Degrees/180) * (4 * ATN(1))
lon2Radians = (lon2Degrees/180) * (4 * ATN(1))
AsinBase = Sin(Sqr(Sin((lat1Radians - lat2Radians)/2)^2 + Cos(lat1Radians) * Cos(lat2Radians) * Sin((lon1Radians - lon2Radians)/2)^2))
DerivedAsin = (AsinBase/Sqr(-AsinBase * AsinBase + 1))
'Get distance from [lat1,lon1] to [lat2,lon2]
GetMiles = Round(2 * DerivedAsin * (earthSphereRadiusKilometers * kilometerConversionToMilesFactor), 2)
End Function
你会被计算两条记录之间或一条记录与任意点之间的距离?如果前者,那么你如何选择这两点? – toonice
我正在计算特定记录与表tblZip中所有其他记录之间的距离。 –