5k Aufrufe
Gefragt in Datenbanken von
Habe eine Abfrage an eine MDB-Tabelle:

SELECT PLZ, Ort, Lat, Lon
FROM Deutschland
WHERE SQR(((Lat - 52)^2) + ((Lon - 10)^2))<= 1;

Leider funzt diese nicht, da die Felder Lat und Lon als Text in der Tabelle definiert sind.
Wie kann ich mit den Werten der Felder trotzdem rechnen?
Kann man diese konvertieren?
Mit Val oder WERT komme ich hier nicht weiter.

Danke für einen Tipp
luet

24 Antworten

0 Punkte
Beantwortet von
versuchs mal mit CDbl

cdblWert = CDbl("123,04") ' ergibt 123.04
cdblWert = CDbl(123.04) ' ergibt 123.04
cdblWert = CDbl("123.04") ' ergibt 12304
0 Punkte
Beantwortet von
Danke für den guten Tipp.

Meine Daten im Feld Lat/Lon liegen in diesem Format ( Text ) vor:

52.9874563
10.7667809
53.9866466
8.99877477
etc.

Kommt CDbl damit klar?
Es sollte dann mit 52, 987 oder mit 10, 766..
rechnen. Wie ist das mit dem Komma?

thx
luet
0 Punkte
Beantwortet von
Hat keiner eine Idee?
thx
luet
0 Punkte
Beantwortet von
schon mal ausprobiert?

wo liegt das problem. komma oder punkt hängt von der ländereinstellung ab ( currency )
0 Punkte
Beantwortet von rahi Experte (1.5k Punkte)
Hallo luet,

hier ein funktionierender (wenn auch nicht schöner) SQL:
SELECT PLZ, Ort, Lat, Lon
FROM Deutschland
WHERE SQR(((CDbl(Replace(Lat,".",",")) - 52)^2) + ((CDbl(Replace(Lon,".",",")) - 10)^2))<= 1;
Wenn die diesen SQL auf viele Datensätze anwenden willst, ist eine Konvertierung von lat und lon nicht verkehrt. Füge zwei Felder als Double ein und setze die Textfelder um mit Bsp.:
UPDATE Deutschland set LatDbl = CDbl(Replace(lat,".",","))
Noch ein Tipp: Deine Formel ist für kurze Abstände noch o.k., für größere Entfernungen benötigst du eine andere Formel verwenden, die näherungsweise viel bessere Ergebnisse, sprich Abstände, liefert. Du muss immer daran denken: Dein "Dreieck liegt auf einer (abgeflachten) Kugel! Falls du die Formel benötigst, melde dich noch mal oder google danach.

Gruß
Ralf
0 Punkte
Beantwortet von
Hallo Ralf,
dickes Danke für deine Hilfe :-)

Das Problem habe ich auch schon festgestellt, alles zu ungenau!
Ich stehe vor einem unüberwindlichem Hindernis.
Möchte unten genannte Funktion in eine SQL-Abfrage (DAO360) umwandeln.
Kannst du helfen ?

Private Function DistanceInKM(LaA, LoA, LaB, LoB) 'Calculate the distance in km between two points
Dim hn As Double, he As Double, n As Double, e As Double, co As Double, ca As Double
hn = CDbl(LaA * 3.14159265358979 / 180)
he = CDbl(LoA* 3.14159265358979 / 180)
n = CDbl(LaB* 3.14159265358979 / 180)
e = CDbl(LoB * 3.14159265358979 / 180)

co = Cos(he - e) * Cos(hn) * Cos(n) + Sin(hn) * Sin(n)
ca = Atn(Abs(Sqr(1 - co * co) / co))
If (co < 0) Then ca = 3.14159265358979 - ca
DistanceInKM = 6367 * ca
End Function
0 Punkte
Beantwortet von rahi Experte (1.5k Punkte)
Hallo luet,

wieso benötigst du eine SQL-Abfrage dafür? Beschreibe mal dein Problem damit. Meine Funktion sieht so ähnlich aus, wobei ich ein r für unsere Breiten gewählt habe:
Public Function abstand(a_lat As Double, a_lon As Double, b_lat As Double, b_lon As Double)
Const pi = 3.14159265358979
Dim r As Double
r = 6380
a_lat = a_lat * pi / 180
a_lon = a_lon * pi / 180
b_lat = b_lat * pi / 180
b_lon = b_lon * pi / 180

abstand = CLng(acos(Sin(b_lat) * Sin(a_lat) + Cos(b_lat) * Cos(a_lat) * Cos(b_lon - a_lon)) * r)
End Function

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


Gruß
Ralf
0 Punkte
Beantwortet von
Hallo Ralf,

Habe bereits was erarbeitet ( siehe unten, funzt), nur klappt die Eingrenzung mit der WHERE-Klausel nicht.

"FROM Deutschland Where DistanceInKM < 200;"

Es geht so mit der Where-Klausel nicht, da nur vorhandene Spalten eingrenzt werden können.
Mit Having habe ich auch nicht hinbekommen.
Hast du hierzu den entscheidenen Tipp?


Function SelectStatement(LaB As String, LoB As String, Entfernung As String, Operator As String) As String

SelectStatement = "SELECT PLZ, Ort, KFZKennz, Bundesland, Lat, Lon, " + _
"3.14159265358979 AS PI, " + _
"Cdbl(iif(instr(1, lat, ""."") = 0, lat, left(lat, instr(1, lat, ""."") - 1) & "","" & mid(lat, instr(1, lat, ""."")+1))) * PI / 180 AS hn, " + _
"Cdbl(iif(instr(1, lon, ""."") = 0, lat, left(lon, instr(1, lon, ""."") - 1) & "","" & mid(lon, instr(1, lon, ""."")+1))) * PI / 180 AS he, " + _
LaB + " * PI / 180 AS n, " + _
LoB + " * PI / 180 AS e, " + _
"COS(he - e) * COS(hn) * COS(n) + SIN(hn) * SIN(n) AS co, " + _
"atn(ABS(sqr(1 - co * co) / co)) AS ca, " + _
"6367 * iif(co < 0, PI - ca, ca) AS DistanceInKM " + _
"FROM Deutschland;"
End Function
0 Punkte
Beantwortet von rahi Experte (1.5k Punkte)
Hallo luet,

das Problem liegt in den Variablen in der Where-Klausel, das geht so nicht! Das SQL-Statement sieht schrecklich aus, daran sollten wir arbeiten ;-) Eine Lösung für dein SQL-String (warum machst du das so?) könnte so aussehen. @all: Bitte nicht schlagen ;-)

SelectStatement = "SELECT * FROM (SELECT PLZ, Ort, KFZKennz, Bundesland, Lat, Lon, " + _
"3.14159265358979 AS PI, " + _
"Cdbl(iif(instr(1, lat, ""."") = 0, lat, left(lat, instr(1, lat, ""."") - 1) & "","" & mid(lat, instr(1, lat, ""."")+1))) * PI / 180 AS hn, " + _
"Cdbl(iif(instr(1, lon, ""."") = 0, lat, left(lon, instr(1, lon, ""."") - 1) & "","" & mid(lon, instr(1, lon, ""."")+1))) * PI / 180 AS he, " + _
LaB + " * PI / 180 AS n, " + _
LoB + " * PI / 180 AS e, " + _
"COS(he - e) * COS(hn) * COS(n) + SIN(hn) * SIN(n) AS co, " + _
"atn(ABS(sqr(1 - co * co) / co)) AS ca, " + _
"6367 * iif(co < 0, PI - ca, ca) AS DistanceInKM " + _
"FROM Deutschland) as innertab WHERE DistanceInKM " & operator & " " & entfernung

Gruß
Ralf
0 Punkte
Beantwortet von
Hallo Ralf,

das war ja wohl ein 1a Tipp!!! DAS KLAPPT!
Kannte ich noch gar nicht "innertab".

Weltklasse :-)))

Jetzt wäre nur noch zu klären, wie ich die überflüssigen Spalten wie PI, hn, he, ca co, etc ausblende / nicht anzeige?

Kann DistanceInKM auf drei Stellen hinter dem Komma formatiert werden?

thx a lot
luet
...