Entfernungsberechnung über die PLZ

Antwort erstellen


BBCode ist eingeschaltet
[img] ist ausgeschaltet
[url] ist eingeschaltet
Smileys sind ausgeschaltet

Die letzten Beiträge des Themas
   

Ansicht erweitern Die letzten Beiträge des Themas: Entfernungsberechnung über die PLZ

Re: Entfernungsberechnung über die PLZ

von marcel_at_work » Fr, 14.05.2010 20:17

Hey, mein Freund. :D

O... o... o........ welch´Pein! :? :shock: Ich geh´in die Ecke und schäm mich erst einmal ne Runde! (bei mir gibt´s leider keinen Scham-Smiley - ja, warum eigentlich??! :lol:)
Man, WARUM ist mir DAS nicht in den Sinn gekommen?!?()(//"%§$"87385§&$"§%"/§&" NATÜRLICH geht OHNE den Key NIX... *grübel*

Die Annäherungssuche überprüft "im Vorhinein" die sortierte DB, aufwärts, in 500er-Schritten nach der PLZ (max. 20 Schritte). Und bei der späteren Abfrage (in der Entfernungsberechnung) sind es dann eben nur noch max. 500 Datensätze, die durchsucht werden müssen. Eben effizienter, als 50.000 Datensätze nacheinander zu durchsuchen. :)
Ich hatte vorher fast einen halben Tag daran gesessen, eine "Suchroutine per Eingrenzung (Berechnung)" (in insgesamt max. 30 Schritten bei 50.000 Datensätzen zur Übereinstimmung) zu schreiben, aber diese war im Endeffekt durch die RowSet-Methode ".absolute()" auf mehrere Sekunden Prozedur-Durchlauf angestiegen (wie du schon sagtest, RowSet ist Sch*** :lol: ).
Wird sich aber in Kürze eh erledigt haben, da ich seit zwei Stunden in meinem MySQL-Buch "Tabellenoptimierung" schmöker und auch schon erste Indizes gesetzt habe (ich bin dir da diesmal schon voraus gekommen :D ). Ich werde wohl auch auf SQL zurückgreifen müssen, da dies einfach am effektivsten scheint (ich brauche nämlich für das Eingabe-Formular meiner Adress-Datenbank mehrere komplexe Abfragen über 100.000e Tabellenzeilen, wofür ich nur ein max. zwei, drei Sekunden langes Zeitfenster offen habe).

Da hast du Recht: WARUM soll ICH denn arbeiten, wenn DU das machen kannst. :lol:
Na, Schmarrn. Ganz einfach: Ich mag Funktionen, die ich benutze, gern verstehen, damit ich sie auch weiterverwenden (bearbeiten) kann. Beim ersten Auftreten eines Problems damit, hab´ich nämlich sonst den "Zonk" gezogen. :lol:

Ooooooooooo, ich werd´verrückt. Der DPunch schickt mir mal einen Verweis auf eine "deutsche" Site!?!! Der Wahnsinn. :lol:
DANKE!!! Kann ich gut gebrauchen. Und wie gesagt, in meinem Buch werd ich wohl auch darüber stolpern. Zudem habe ich vorhin auch gesehen, dass man über phpMyAdmin schon vorher Abfragen anlegen/abspeichern kann.

GlG, Marci

Re: Entfernungsberechnung über die PLZ

von DPunch » Fr, 14.05.2010 19:03

Aloha
marcel_at_work hat geschrieben:Ich hatte das RowSet schon von Beginn an mit den selben Methoden, wie du schriebst, bedient! Du wirst den Fehler niemals erraten: Im SQL-Command habe ich die erste MySQL-Tabellenspalte, die "ID", weggelassen - und DESSHALB wollte Basic den Prozedurabschnitt nicht akzeptieren. So ein Schmarrn.
Nunja, eigentlich ist das kein Schmarrn ;)
Ohne den PrimaryKey kann der Datensatz, den Du gerade updaten willst, nicht eindeutig identifiziert werden.
Wenn Du die Abfrage, die Deinem RowSet zugrunde liegt, sortierst und dann den 5. Datensatz davon verändern willst - woher soll das DBMS ohne eindeutige Identifikation wissen, welcher Datensatz tatsächlich derjenige ist, den Du gerade verändern willst?
Ich hab´s sogar mittels einer "Annäherungssuche" geschafft, die Überprüfung der Start-PLZ (über 50.000 Datensätze) für die Entfernungsberechnung, auf weit unter eine halbe Sekunde zu beschränken.
Der Zweck erschliesst sich mir ehrlich gesagt nicht ganz :oops:
Beschränkst Du die Suche dann nur auf die +/-500 Postleitzahlen um die Start-PLZ herum?
Der Grund, warum ich diese Standard-"Arkuskosinus-Funktion" bevorzugte, war, weil ich ausschließlich SIE noch nachvollziehen konnte!!! :lol: Und dies ist mir eben sehr wichtig, wenn ich schon per Copy/Paste eine vorgefertigte Funktion bekomme.
Grundsätzlich erstmal sehr löblich, aber die Umsetzung der mathematischen Gegebenheiten ist nunmal reine Fleissarbeit und minimalster Denkaufwand - sowas kann man auch guten Gewissens kopieren, es muss ja nicht sein, dass Du die gleiche stumpfe Arbeit machst, die ich mir schonmal gemacht habe ;)
Sobald man eine SQL-Abfrage gestartet hat, wird diese ja zwischengespeichert, und somit jede folgende Abfrage in einem Bruchteil der Zeit möglich.
Prinzipiell ja - normalerweise merkt sich das DBMS die Abfragen, die durchgeführt wurden und schaut bei jeder neuen Abfrage erstmal, ob die Abfrage nicht möglicherweise schonmal haargenau so getätigt wurde, und wenn ja, kennt es sozusagen "den Weg".
Dazu brauchst Du keine Variable, sondern das macht jedes halbwegs vernünftige DMBS schon von sich aus.
Wenn Du Dich da wirklich einarbeiten willst, solltest Du hier:
MySql Query Cache anfangen und dann bei Google in die (Un-)Tiefen der DB-Optimierung eintauchen ;)

Re: Entfernungsberechnung über die PLZ

von marcel_at_work » Fr, 14.05.2010 15:04

Hallöchen, DPunch. :D

Dank dir!!! Vielmals!

Ich kann übrigens deine Affinität zu OOo gut verstehen - mich nervt es nämlich langsam auch. :lol:

Es ist wirklich zum Heulen, wenn man selbst in den Basis-Referenzen keine ausreichenden Beschreibungen zu standardisierten Funktionsabläufen finden kann. Das ist zumindest MEIN Problem:

Ich hatte das RowSet schon von Beginn an mit den selben Methoden, wie du schriebst, bedient! Du wirst den Fehler niemals erraten: Im SQL-Command habe ich die erste MySQL-Tabellenspalte, die "ID" (weil ich sie für die Abfrage nicht brauchte), weggelassen - und DESSHALB wollte Basic den Prozedurabschnitt nicht akzeptieren. So ein Schmarrn.
Naja... jedenfalls sind somit alle Probleme mit der SQL-Kommunikation gelöst. ENDLICH. :)

Ich hab´s sogar mittels einer "Annäherungssuche" geschafft, die Überprüfung der Start-PLZ (über 50.000 Datensätze) für die Entfernungsberechnung, auf weit unter eine halbe Sekunde zu beschränken. Es geht bestimmt noch schneller, aber temporär ist´s erstmal ausreichend für mich: :o

Code: Alles auswählen

'Annäherungssuche an die "Start-PLZ" (optimale Einstellung: 500er-Schritte bei 50.000 Einträgen/500ms)
Sub precisionCount()
	For i = 500 To 52000
		oResultPLZ.absolute(i)
		If textGeoPLZ.text >= oResultPLZ.getString(1) Then
			nPrecisionCount = i
		Else Exit Sub
		End If
		i = i + 499
	Next i
End Sub
Das mit RowSet.next() hab´ich, zu meinem Leid, letztens auch schon gemerkt. Ich brauchte aber (zwecks Wiederholung der Prozedur) genau an dieser Stelle irgendeine Cursor-Positionierung. Ich hab´dies nun gegen RowSet.beforFirst() getauscht und es funzt so ganz gut.

Jepp, da hast du Recht...
Der Grund, warum ich diese Standard-"Arkuskosinus-Funktion" bevorzugte, war, weil ich ausschließlich SIE noch nachvollziehen konnte!!! :lol: Und dies ist mir eben sehr wichtig, wenn ich schon per Copy/Paste eine vorgefertigte Funktion bekomme.
Aber ich werde mir die Tuning-Version jetzt auch mal genauer anschauen. :D

Ich danke dir jedenfalls RIEßIG, dass du mir soweit geholfen hast. Durch dich (und über 100h Wikis/in zwei Wochen) bin ich nun bald ein Profi in "OOo & SQL"... :lol:

GlG, Marci

Ps.: A scheen´s Weekend!

EDIT:

Naja,... eine Frage hab´ich dann doch noch, verzeih´: :)

Sobald man eine SQL-Abfrage gestartet hat, wird diese ja zwischengespeichert, und somit jede folgende Abfrage in einem Bruchteil der Zeit möglich.
Ich würde gern wissen, ob man diese Zwischenspeicherung (Abfrage) irgendwie in einer Variablen ablegen kann, um somit schon beim Start meines Programmes mit Dieser arbeiten zu können? Oder kann man vielleicht die ganze Prozedur von Anfang an schon so schreiben, dass sozusagen eine zur Zwischenspeicherung equivalenten Abfrage gleich mit eingebaut ist???
Häng´ich mich da grad zu weit aus dem Fenster? :D

Re: Entfernungsberechnung über die PLZ

von DPunch » Do, 13.05.2010 17:20

Aloha
DU benutzt ja selbst gelegentlich den RowSet-Service... könntest du mir denn eventuell mal ein einfaches Script von dir posten, wo man die "Abfragen und Updates" der DB sieht? Wie speicherst DU denn dann mit diesem Service in die DB?
Ich arbeite wie gesagt eigentlich nur mit SQL-Anweisungen für Updates / Inserts.

Code: Alles auswählen

oStatement = oConnection.createStatement
sSQL = "UPDATE meineTabelle SET meineSpalte = 'neuerWert'"
REM oder auch sSql = "INSERT INTO meineTabelle (""meineSpalte1"",""meineSpalte2"") VALUES ('Wert1','Wert2')"
oStatement.executeUpdate(sSQL)
Der RowSet-Service ist insgesamt vermutlich deutlich komfortabler, aber ich habe irgendwo (weiss nicht mehr genau, wo - entweder in der API oder im englischen Forum) gelesen, dass die Arbeit mit einem RowSet aufgrund der Navigierbarkeit langsamer sein soll, deshalb bin ich von Anfang an mit puren SQL-Anweisungen an die Sache gegangen

Die Funktionen vom RowSet sind eigentlich sehr einfach zu bedienen (XRowUpdate / XResultSetUpdate)

Code: Alles auswählen

RowSet = createUnoService("com.sun.star.sdb.RowSet")
RowSet.DataSourceName = "geoPersonality"
RowSet.CommandType = com.sun.star.sdb.CommandType.COMMAND
sSQLCommand = "SELECT Unternehmen, Zusatz, Anschrift, PLZ, Ort, Land, Bundesland, Geschlecht, Titel, Vorname, Nachname, "
sSQLCommand = sSQLCommand & "Position, Tel1, Tel2, Tel3, Fax, eMail, Web, Tags, Anmerkungen, Erstellungsdatum, Änderungsdatum "
sSQLCommand = sSQLCommand & "FROM kvpm.kvpm_adresses"
RowSet.Command = sSQLCommand
RowSet.Execute
RowSet.Next
nColumnIndex = RowSet.findColumn("Anmerkungen") REM Spaltenindex der Spalte "Anmerkungen" finden
RowSet.updateString(nColumnIndex,"meineAnmerkung") REM Den String des RowSet an der aktuellen Cursorposition in der Spalte "Anmerkungen" mit "meineAnmerkung" überschreiben
RowSet.updateRow REM Die Änderung in die Datenbank schreiben
Damit solltest Du problemlos Änderungen an der DB durchführen können.

Übrigens noch zwei Anmerkungen:
Aus Deinem Code

Code: Alles auswählen

oResultGeo.Execute
oResultGeo.next()
(...)
Do While oResultGeo.Next
(...)
Ich weiss nicht, ob das beabsichtigt ist, aber so ignorierst Du immer den ersten Datensatz. Das erste oResultGeo.next() setzt den Cursor auf die erste Zeile.
Im Schleifenkopf setzt Du den Cursor dann wieder eine Zeile weiter und kommst in den Schleifenkörper, wenn die Navigation erfolgreich war.
Hast Du z.B. nur einen Datensatz in der Tabelle, kommst Du nie in den Schleifenkörper, weil das oResultGeo.next() aus dem Schleifenkopf den Cursor auf die zweite Zeile setzt, dies aber kein regulärer Datensatz ist und "Next()" somit ein False zurückliefert.

Für die Entfernungsberechnung benutzt Du ausserdem die veraltete Funktion.
Ich würde Dir eher zu der schnelleren und genaueren Version aus der Calc-Datei raten:

Code: Alles auswählen

Function CalculateDistance(nGeoLat as Double, nGeoLon as Double) as Integer
	On Error Resume Next
	Dim F as Double, G as Double, L as Double
	Dim S as Double, C as Double, W as Double
	Dim D as Double, R as Double
	Dim H1 as Double, H2 as Double

	F = (nLatitudeStart+nGeoLat) / 2
	G = (nLatitudeStart-nGeoLat) / 2
	If G = 0 Then G = 0.000000000001
	L = (nLongitudeStart-nGeoLon) / 2
	If L = 0 Then L = 0.000000000001

	S = (sin(G))^2 * (cos(l))^2 + (cos(F))^2 * (sin(l))^2
	C = (cos(G))^2 * (cos(l))^2 + (sin(F))^2 * (sin(l))^2
	W = ArcTan((sqr(S/C)))
	D = 2 * W * constA
	R = Sqr(S*C) / W
	H1 = (3 * R - 1) / (2 * C)
	H2 = (3 * R + 1) / (2 * S)
	S = D * (1 + constF*H1*(sin(F))^2 * (cos(G))^2 - constF *H2 * (cos(F))^2 * (sin(G))^2)
	
	CalculateDistance = S
End Function

Function ArcTan(x as Double) as Double
	ArcTan = (x + 0.43157974*x^3)/(1 + 0.76443945*x^2 + 0.05831938*x^4)
End Function
Du musst dann noch die Variablen nLatitudeStart, nLongitudeStart, constF und constA modulweit als Double deklarieren und vor der Schleife mit den entsprechenden Werten belegen (Koordinaten des Ausgangspunktes, constF = 1 / 298.257223563, constA = 6378.137).

Schau mal, ob Dir das weiterhilft.
Newbiebuh2010 hat geschrieben:Hm. Ich hoffe doch, dass das lediglich eine Affektäußerung war aufgrund irgendeines Problems.
Dass ich die Äußerung überhaupt getroffen habe, war zwar mehr oder weniger im Affekt und entsprechend überflüssig, weil hier nunmal niemand etwas dafür kann, aber die Meinung an sich ist sicherlich nicht aus dem Affekt heraus entstanden.
Aber egal, solche Diskussionen gehören hier definitv nicht hin und helfen erst Recht niemandem weiter.

Re: Entfernungsberechnung über die PLZ

von Newbiebuh2010 » Mi, 12.05.2010 23:31

@ DPunch
Hi !
DPunch hat geschrieben:, andererseits habe ich nicht vor, jemals wieder mit OOo bzw OOo Basic zu arbeiten sobald meine Arbeit hier im Betrieb abgeschlossen ist, weil es einfach eine unfertige und mies zusammengeschusterte Sache ist.
Hm. Ich hoffe doch, dass das lediglich eine Affektäußerung war aufgrund irgendeines Problems.
Denn unfertig und mies zusammengeschustert kann man diverse Softwareprodukte auf dem Markt finden - aber welche Alternativen gibt es denn zu OO ?
Klar - SO und MS auf jeden Fall. Aber sind die besser ? Ich glaube nicht. Maximal genauso gut. Und selbst das bezweifle ich. Auf jeden Fall muss man sich nicht über ein Preis-Leistungs-Verhältnis streiten (ein großer Vorteil eines Open-Source-Projects).

Wie auch immer, mit jeder Software kann man irgendwann an einen Punkt kommen, an dem man sagt: LMAA
Aber das kann einem auch mit jedem Auto, mit jedem Haus, mit jedem Swimmingpool, mit jedem Partner passieren.
Deshalb sollte man nich zwingend alles aufgeben.

Und für uns wäre es natürlich auch schön, wenn du dabei bleiben würdest :?

Viele Grüße

Re: Entfernungsberechnung über die PLZ

von Newbiebuh2010 » Mi, 12.05.2010 22:44

Bitte nicht böse sein - dies ist kein Hilfsbeitrag... :shock:

Ich verfolge nur gerne Diskussionen hier im Forum und musste einfach gerade laut lachen - marcel ist schuld :D wie gesagt: nicht böse sein !

ABER:
marcel_at_work hat geschrieben: >Heute ist "ökomenischer Kirchentag" und die Hoffnung ist deshalb gerade wieder sehr präsent, dass ein Wunder geschieht und sich mir vielleicht doch noch der ein oder andere offenbahrt!!! :shock: :lol:
Kirchentag, offenbaren gemeint und offenbahren geschrieben hat einfach was - und dann auch noch als Wunder :lol: :lol:
und dann auch noch "der eine oder andere" 8)

Junge, das hat was Romanreifes !

Aber, na ja, nun mal zurück ins Leben -
ich verfolge zwar,, kann aber leider nicht mit hilfreichen Tipps hier dienen.

Macht's gut und schönen Abend noch !

Re: Entfernungsberechnung über die PLZ

von marcel_at_work » Mi, 12.05.2010 20:59

Hallllllllööööööchen DPunch, :D

dessen bin ich mir doch ABSOLUT bewußt!!! Und das DU MIR schon so ausgiebig geholfen hast, finde ich äußerst bewundernswert! :)

Ich sitze die letzte Zeit echt Tag und Nacht am Rechner, um selbst zu den Lösungen zu kommen. Ich bin aber am Verzweifeln, weil anscheinend auch niemand anders eine Lösung zu diesem Service hat.

Wie du schon schriebst, habe ich sogar auch schon die englische Referenz dazu durchgearbeitet (und soweit ich es verstanden habe, auch angewendet). Der Erfolg blieb mir aber trotzallem verwährt.

Der Service RowSet von XResultSet... unterstützt bis auf die Navigation anscheinend andere Methoden wie z.B. auch refreshRow, etc. Leider habe ich aber beim Implementieren versagt. Egal, was ich auch versuchte.

Die Gute Nachricht (ja, die gibt es :lol: ): Ich habe indessen mein komplettes Programm auf RowSet/XResult... bzw. allg. SQL-Abfragen umgestellt, und es ENDLICH geschafft, die Basis deiner Entfernungs-Berechnung einzubinden. (ich mußte dazu jedoch ziemlich viele Website zu diesem Thema überfliegen und gar, über verschiedene Wikis, Mathematische Funktionsgleichungen der Oberstufe studieren, bis ich irgendwelche Zusammenhänge verstand :lol: :D )

Schau doch mal...
(Edit: "Initialisierung der DB-Verbindung" findet an andere Stelle im Programmablauf statt)

Code: Alles auswählen

OPTION EXPLICIT

Sub geoCoords()
	Dim nGeoLatStart, nGeoLonStart, nGeoLatTarget, nGeoLonTarget as Double
	Dim nLatitudeStart, nLongitudeStart, nLatitudeTarget, nLongitudeTarget as Double
	Dim nDistance, nMaxDistance
	Dim sEntry, sListSpace
	Dim startTime, endTime, countTime, nHits
	
	startTime = GetSystemTicks 'Abrufen der Systemzeit für den Funktions-Counter
	nHits = 0
	nMaxDistance = 6000
	
	oResultGeo.Command = "SELECT Unternehmen, Zusatz, Anschrift, PLZ, Ort, Land, Bundesland, Latitude, Longitude, Geschlecht, Titel, Vorname, Nachname, Position, Tel1, Tel2, Tel3, Fax, eMail, Web, Tags, Anmerkungen, Erstellungsdatum, Änderungsdatum FROM geopersonality.adresses"
	oResultGeo.Execute
	oResultGeo.next()
	
	nGeoLatStart = 50.11222 'Frankfurt
	nGeoLonStart = 08.68194
	'nGeoLatTarget = 52.52222 'Berlin
	'nGeoLonTarget = 13.29750
	
	nLatitudeStart = nGeoLatStart / 180 * Pi
	nLongitudeStart = nGeoLonStart / 180 * Pi
	
	Do While oResultGeo.Next
		If oResultGeo.getDouble(8) <> 0 Then 'Wenn Feld "PLZ" nicht leer,...
			'... Abrufen der Koordinaten aus dem ResultSet
			nGeoLatTarget = oResultGeo.getDouble(8)
			nGeoLonTarget = oResultGeo.getDouble(9)
			'Vorbereitung der Koordinaten für die Arkuskosinus-Funktion
			nLatitudeTarget = nGeoLatTarget / 180 * Pi
			nLongitudeTarget = nGeoLonTarget / 180 * Pi
			nDistance = ArcCos(Sin(nLatitudeStart) * Sin(nLatitudeTarget) + Cos(nLatitudeStart) * Cos(nLatitudeTarget) * Cos(nLongitudeTarget - nLongitudeStart)) * 6378.137
			If nDistance <= nMaxDistance Then
				nDistance = Left(nDistance, Instr(nDistance,",") + 1) 'Die Entfernungsangabe (nDistance) bis auf eine Stelle nach dem Komma abschneiden
				'Vervollständigung von "nDistance" mit Leerzeichen, um in der Listbox eine gleichförmige Ansicht in Spalten zu gewährleisten
				If Len(nDistance) = 3 Then
					sListSpace = "      "
				ElseIf Len(nDistance) = 4 Then
					sListSpace = "    "
				ElseIf Len(nDistance) = 5 Then
					sListSpace = "  "
				End If
				
				sEntry = "[→" & sListSpace & nDistance & " Km] " & oResultGeo.getString(4) & " " & oResultGeo.getString(5)
				If oResultGeo.getString(19) <> "" Then sEntry = sEntry & "    → " & oResultGeo.getString(19)
				
				'Übertragung in das Listbox-Element
				listGeoResults.additem(sEntry, 0)
				
				nHits = nHits + 1 'Aktualisierung der Ergebnis-Anzeige
			End If
		End If
	Loop
	
	'listGeoResults.removeitems(0,1) 'Einen Eintrag ab Eintrag 1(0) löschen oder...
	'EmptyListBox(listGeoResults)

	endTime = GetSystemTicks 'Erneutes Abrufen der Systemzeit für den Funktions-Counter
	countTime = (endTime - startTime)/1000 'Differenz zwischen den Counter-Zeiten berechnen
	'If Instr(countTime,"-") > 0 Then
	'	countTime = replaceString(countTime,"",",")
	'	countTime = replaceString(countTime,"","E")
	'End If
	textGeoInfo.text = nHits & " Ergebnisse (" & countTime & " Sekunden)"
End Sub

'Experimentelle Arkussinus-Funktion für OpenOffice.org-Basic
Function ArcSin(x)
	Dim nNumer, nDenom, nFrac, nResult, nNewTerm
	nNumer = 1
	nDenom = 2
	nFrac = 1
	nResult = x

	For i = 1 To 100
		nFrac = nFrac * nNumer / nDenom
		nNumer = nDenom + 1
		nDenom = nNumer + 1

		nNewTerm = nFrac * ((x^nNumer)/nNumer)
		nResult = nResult + nNewTerm

		If nNewTerm < 1.0E-60 Then
			Exit For
		EndIf
	Next i

	ArcSin = nResult
End Function

'Experimentelle Arkuskosinus-Funktion für OpenOffice.org-Basic
Function ArcCos(x)
	ArcCos = ArcSin(Sqr(1 - x^2))
End Function
Das einzige, wozu ich eben immer noch keinen Zugriff habe, ist das "Schreiben IN die DB". *heul*

DU benutzt ja selbst gelegentlich den RowSet-Service... könntest du mir denn eventuell mal ein einfaches Script von dir posten, wo man die "Abfragen und Updates" der DB sieht? Wie speicherst DU denn dann mit diesem Service in die DB?

ODER hat vielleicht jemand ANDERS ein Bsp.-Script zur Veranschaulichung?

>Heute ist "ökomenischer Kirchentag" und die Hoffnung ist deshalb gerade wieder sehr präsent, dass ein Wunder geschieht und sich mir vielleicht doch noch der ein oder andere offenbahrt!!! :shock: :lol:

GlG, Marci

Re: Entfernungsberechnung über die PLZ

von DPunch » Mi, 12.05.2010 19:45

Aloha

Ich kann Dir auch nur sagen, dass UpdateRow eigentlich(!) funktionieren sollte.
Zum Service wirst Du Wohl oder Übel irgendwie aus der englischen API Deine Infos ziehen müsssen.

Und verlass Dich bitte nicht auf mich, einerseits stammen meine Tips nämlich nur aus persönlichen Erfahrungen. die natürlich nicht immer 1:1 auf Deine Probleme anwendbar sind, andererseits habe ich nicht vor, jemals wieder mit OOo bzw OOo Basic zu arbeiten sobald meine Arbeit hier im Betrieb abgeschlossen ist, weil es einfach eine unfertige und mies zusammengeschusterte Sache ist.

Bei konkreten Sachen, dir mir im Code o.Ä. ins Auge springen, helfe ich natürlich gern, aber ich kann Dir leider keine Rundumbetreuung bieten ;)

Re: Entfernungsberechnung über die PLZ

von marcel_at_work » Di, 11.05.2010 18:48

Aloooooha DPunch,

... WO BIST DU NUR? :(

Ich brauche DRINGEND HILFE bei dem RowSet-Service!!!

Ich hab´nun das gesamte Wiki zum Thema ResultSet durchgeforstet und alles mögliche ausprobiert, aber ich komm´einfach ned zum Ziel... HELLLLPPPPP MEEEEE, PLEEEAAAAASE! :shock:

Lg, Marci

Re: Entfernungsberechnung über die PLZ

von marcel_at_work » Sa, 08.05.2010 16:52

Schon, gelle. Mich nämlich auch! :D

Ich kann dir auch jetzt nicht sagen, woran das mit .last() gelegen hat. Aber seltsamerweise hat die Funktion dbOpen auch auf resultRefresh (und somit auch .getString) zugegriffen, als der verweisende Aufruf nicht mehr da war... naja...

Der Service RowSet gefällt mir und funktioniert super. Er ist zudem auch übersichtlicher. Danke! :D
Und WIE komm ich mit diesem nun zum Update der DB? Die updateRow-Methode scheint da ja nicht dafür zuständig zu sein. :o
Zudem: Wo, in Gottes Namen, kann man sich über "RowSet" informieren? Ich kann weder in OOo noch in SQL etwas darüber finden??!?(&/§&"2736%376473 :shock:

LG, Marci

EDIT: Ich hab´jetzt auch mal deinem Link Aufmerksamkeit geschenkt. :lol: Zu meinem Bedauern (ich könnt heulen!) komm ich mit der Site aber absolut nicht klar. Ein paar Kleinigkeiten kann ich zwar nachvollziehen, aber mein Englisch ist sehr mager und ich versteh´es einfach nicht! :(
Gibt´s das nicht auch irgendwo in deutscher Form?


Ps.:

Da ich jetzt nach eigenen Erfahrungen selbst so sehr über die "Einfachheit" verblüfft bin, hier noch ein Zusatz für Volker und alle anderen Hilfesuchenden zu dem Thema: :D
Anleitung: "Wie richte ich mir in fünf Minuten eine MySQL-Datenbankanbindung für OpenOffice.org-Module ein?"

Tags: "OpenOffice und MySQL", "Calc-Frontend und MySQL", "MySQL-Datenbank unter OpenOffice"

Anmerkung: Voraussetzung hierfür ist natürlich eine schon bestehende MySQL-Datenbank. Die Software dafür kann man sich aber ebenfalls in ein paar Minuten auf dem PC installieren/einrichten, wobei HIER auch noch eine ganz tolle Einführung zur "Erstellung von Tabellen in einer MySQL-Datenbank" (über die Schnittstelle "PhpMyAdmin") zu finden ist.
Mit OpenOffice.org können MySQL-Datenbanken über einen der beiden Datenbanksystem-Konnektoren ODBC oder JDBC verbunden werden und dazu müssen lediglich drei kleine Schritte erfolgen:

1. Installation des ODBC-Subsystems
2. Registrierung der MySQL-Datenbank unter ODBC
3. Verbinden der MySQL/ODBC-Datenbank mit OOo-Base

Anmerkung: Erst nach der Verbindung mit OpenOffice.org Base steht die Datenbank auch in den anderen Modulen als DatenQuelle zur Verfügung (s.u.).

1. Installation des ODBC-Subsystems

Der MySQL-Konnektor (Windows x86 und 32/64bit), der das Registrieren von MySQL-Datenbanken unter ODBC erlaubt, muss installiert werden.

2. MySQL-Datenbank im ODBC-Subsystem registrieren

Ab Windows® 2000 findet sich die Konfiguration des ODBC-Subsystems unter Programme → Zubehör → Verwaltung → Datenquellen (ODBC). Hier können die MySQL-Datenbanken als "Benutzer-DSN" registriert werden. Achtung, MySQL erscheint nur dann in der Liste der Treiber, wenn es zuvor installiert worden ist (s.o.).

3. Datenbank in OpenOffice.org Base einbinden

In OpenOffice.org, ab Version 2.0, wird der Datenbank-Dialog mit Datei → Neu → Datenbank geöffnet. Dort kann nach dem Anklicken von Verbindung zu einer bestehenden Datenbank herstellen der benötigte Treiber (hier: MySQL) ausgewählt werden.

Im nächsten Schritt kann zwischen JDBC und ODBC gewählt werden, hier wird die Anbindung über ODBC ausgewählt. Dann die ODBC-Quelle auswählen. Die MySQL-Datenbank muss zuvor als solche registriert worden sein (s.o.) Im letzten Schritt den Nutzernamen der Datenbank angeben und die Option "Kennwort erforderlich" auswählen. Die Verbindungseinstellungen werden als Datei gespeichert, daher muss nun noch ein Dateiname gewählt werden.

Eine verständliche Übersicht von den SQL-Anweisungen, mit denen man dann z.B. in OpenOffice den Kontakt mit dem MySQL-Server (der Datenbank) aufnehmen kann, findet sich im StarBasic-Programmierhandbuch (.pdf), unter "Datenbanken".
Und für alle, die es immernoch scheuen, sich mit Datenbanken (ext. oder HSQL(Base)) zu beschäftigen, soll an dieser Stelle gesagt sein: Der Programmieraufwand, den man durch die damit verbundenen SQL-Anweisungen hat, ist zum einen geringer, viel verständlicher und als letztes auch um ein vielfaches übersichtlicher als mit OpenOffice-Basic. Es lohnt sich also auf jeden Fall, einmal einen Blick darauf zu riskieren! Zumal die Installationen von Datenbankmanagementsystemen (DBMS) und deren Anbindung, heutzutage, scheinbar alle sehr "einfach und verständlich" dokumentiert sind.

Re: Entfernungsberechnung über die PLZ

von DPunch » Sa, 08.05.2010 02:59

Aloha

Freut mich zu hören, dass es vorwärts geht :)
marcel_at_work hat geschrieben:Aber z.b. bei der SQL-Methode "last()" zickt OOo herum. Ich bekomm da die Meldung "Ungültiger Cursorstatus". :(
Die Fehlermeldung kommt glaube ich nicht von der XResultSet-Methode ( ;) ) "Last()", sondern wird durch Deine resultRefresh - Prozedur verursacht. Das ".Last" setzt den Cursor (zumindest bei mir und anscheinend auch bei Dir) *hinter* die letzte Zeile, beim Aufruf von "ResultSet.getString(1)" führt dies aufgrund des ungültigen Cursorstatus demzufolge zur gleichlautenden Fehlermeldung.
Zudem kann ich auch das ResultSet nicht auf UPDATABLE umstellen, obwohl ich die Anweisungen nach DIN aus der Basic-Referenz entnommen habe?!??? :(
Das ist mir auch noch nicht gelungen, aber solche Dinge mache ich sowieso lieber über UPDATE Statements. Warum auch immer, aber ich fühle mich da einfach sicherer.

Die einfache Lösung für Deine beiden Probleme wäre die Arbeit mit einem RowSet.

Dafür müsstest Du Deine dbOpen Prozedur wie folgt anpassen (und ResultSet noch Global bzw. Modulweit bekannt machen):

Code: Alles auswählen

Sub dbOpen()

Dim sSQLCommand as String
RowSet = createUnoService("com.sun.star.sdb.RowSet")
RowSet.DataSourceName = "geoPersonality"
RowSet.CommandType = com.sun.star.sdb.CommandType.COMMAND
sSQLCommand = "SELECT Unternehmen, Zusatz, Anschrift, PLZ, Ort, Land, Bundesland, Geschlecht, Titel, Vorname, Nachname, "
sSQLCommand = sSQLCommand & "Position, Tel1, Tel2, Tel3, Fax, eMail, Web, Tags, Anmerkungen, Erstellungsdatum, Änderungsdatum "
sSQLCommand = sSQLCommand & "FROM kvpm.kvpm_adresses"
RowSet.Command = sSQLCommand
RowSet.Execute
If RowSet.Last Then
	resultRefresh	
End If

End Sub
Bitte, Bitte hilf mir!!!
Okay, einen hätte ich da noch:

Code: Alles auswählen

ResultSet = Statement.executeQuery(...)
If Not IsNull(ResultSet) Then (...)
Ein solche ResultSet kann nie Null sein ;)


Was die Sache mit dem Webservice für die Koordinaten betrifft:
Nette Idee, aber für die Webservices, bei denen man die Koordinaten auslesen konnte, musste man überall einen Developer-Key beantragen, da hatte ich keine Lust drauf. ;)

Re: Entfernungsberechnung über die PLZ

von marcel_at_work » Fr, 07.05.2010 23:18

Aloooooha DPunch,

... well done! :D

Nach unzählbaren Energie-Drinks, mehreren Stangen Zigaretten, einer ganzen Palette Knabberzeugs und nun mehr als einer Woche bis jeweils in die frühen Morgenstunden studieren & probieren, hab´ich es nun endlich geschafft - mein bestehender Calc-Dialog ist nun das Frontend zu einem prof. MySQL-Datenbankmanagementsystem! :lol: :D

Und ich muß ehrlich sagen: Am längsten hat es gedauert, zu erfahren, dass man das Ding auch noch im Windows-System anmelden muß. :o

Also,... die Verbindung steht nun und einige Basic-Abfragen sind schon umgestellt. Aber z.b. bei der SQL-Methode "last()" zickt OOo herum. Ich bekomm da die Meldung "Ungültiger Cursorstatus". :(
Zudem kann ich auch das ResultSet nicht auf UPDATABLE umstellen, obwohl ich die Anweisungen nach DIN aus der Basic-Referenz entnommen habe?!??? :(

So sieht der Teil der Update-Funktion jetzt aus:

Code: Alles auswählen

OPTION EXPLICIT

'Deklarationen für die MySQL-Datenbankanbindung
Public DatabaseContext As Object
Public DataSource As Object
Public Connection As Object
Public InteractionHandler as Object
Public Statement As Object
Public ResultSet As Object

Sub dbOpen()
	'... Initialisierung des Datenbankobjektes und Herstellen der MySQL-Verbindung
	DatabaseContext = createUnoService("com.sun.star.sdb.DatabaseContext")
	DataSource = DatabaseContext.getByName("geoPersonality")
	
	If Not DataSource.IsPasswordRequired Then
		Connection = DataSource.GetConnection("","")
	Else
		InteractionHandler = createUnoService("com.sun.star.sdb.InteractionHandler")
		Connection = DataSource.ConnectWithCompletion(InteractionHandler)
	End If
	
	Statement = Connection.createStatement()
	Statement.ResultSetConcurrency = com.sun.star.sdbc.ResultSetConcurrency.UPDATABLE
	Statement.setPropertyValue("ResultSetConcurrency", 1008) 
	Statement.ResultSetType = com.sun.star.sdbc.ResultSetType.SCROLL_SENSITIVE
	ResultSet = Statement.executeQuery("SELECT Unternehmen, Zusatz, Anschrift, PLZ, Ort, Land, Bundesland, Geschlecht, Titel, Vorname, Nachname, Position, Tel1, Tel2, Tel3, Fax, eMail, Web, Tags, Anmerkungen, Erstellungsdatum, Änderungsdatum FROM kvpm.kvpm_adresses")

	If Not IsNull(ResultSet) Then
		ResultSet.last()
		call resultRefresh()
	End If
End Sub

Sub dbFirst()
	ResultSet.first()
	call resultRefresh()
End Sub

Sub dbPrevious()
	If ResultSet.isFirst() = 0 Then
		ResultSet.previous()
		call resultRefresh()
	End If
End Sub

Sub dbSave()
	ResultSet.getString(1, txt_zeitung.text)
	ResultSet.getString(2, txt_verlag.text)
	ResultSet.getString(3, txt_anschrift.text)
	ResultSet.getString(4, txt_plz.text)
	ResultSet.getString(5, txt_ort.text)
	ResultSet.getString(6, txt_land.text)
	ResultSet.getString(7, txt_bundesland.text)
	ResultSet.getString(8, txt_geschlecht.text)
	ResultSet.getString(9, txt_titel.text)
	ResultSet.getString(10, txt_kontaktperson.text)
	ResultSet.getString(11, txt_kontaktperson2.text)
	ResultSet.getString(12, txt_position.text)
	ResultSet.getString(13, txt_telefon.text)
	ResultSet.getString(14, txt_tel2.text)
	
	ResultSet.getString(16, txt_fax.text)
	ResultSet.getString(17, txt_email.text)
	ResultSet.getString(18, txt_web.text)
	ResultSet.getString(19, txt_tags.text)
	ResultSet.getString(20, txt_anmerkungen.text)
	
	ResultSet.updateRow()
End Sub

Sub dbNext()
	If ResultSet.isLast() = 0 Then
		ResultSet.next()
		call resultRefresh()
	End If
End Sub

Sub dbWarning_del()
	If MsgBox("Eintrag wirklich löschen?",16 + 1,"Datenbank-Meldung...") = 1 Then
		call dbDelete()
	end if
End Sub

Sub dbDelete()
	
	MsgBox("Datensatz wurde gelöscht.",64,"Datenbank-Meldung...")
End Sub

Sub resultRefresh()
	str_zeitung = ResultSet.getString(1)
	str_verlag = ResultSet.getString(2)
	str_anschrift = ResultSet.getString(3)
	str_plz = ResultSet.getString(4)
	str_ort = ResultSet.getString(5)
	str_land = ResultSet.getString(6)
	str_bundesland = ResultSet.getString(7)
	str_geschlecht = ResultSet.getString(8)
	str_titel = ResultSet.getString(9)
	str_kontaktperson = ResultSet.getString(10)
	str_kontaktperson2 = ResultSet.getString(11)
	str_position = ResultSet.getString(12)
	str_telefon = ResultSet.getString(13)
	str_tel2 = ResultSet.getString(14)
	
	str_fax = ResultSet.getString(16)
	str_email = ResultSet.getString(17)
	str_web = ResultSet.getString(18)
	str_tags = ResultSet.getString(19)
	str_anmerkungen = ResultSet.getString(20)
	
	call actuallyText()
End Sub
Bitte, Bitte hilf mir!!! :D

GlG, Marci

Ps.: @Mobbi

Klingt sehr, sehr interessant und ich werde mir das die Tage gleich mal genauer anschauen! :)

Re: Entfernungsberechnung über die PLZ

von Mobbi » Fr, 07.05.2010 13:05

Hallo Zusammen,
zu dem Problem mit den Koordinaten für die Orte habe ich vielleicht eine Lösung.

Ich hab da mal was für Excel (*schauder*) gefunden, das war von Jörg Napp aus Weingarten, damit kann man sich für einen beliebigen Ort die Koordinaten Yahoo-API bestimmen lassen.
Damit lassen sich für die x-Tausend Orte in der Datenbank ohne Probleme die Koordinaten bestimmen. Das 'Tool läuft mit Genauigkeiten bis zur Hausnummer - aber leider nur unter Excel.
Ich nutze bisher das Excel-Tool um mein Navi mit Koordinaten füttern zu können und wollte es deshalbe in OOO umsetzen
Habe es leider bisher nicht geschafft das Ganze ins OOO umzusetzen und scheitere immer bei der Erzeugung der Definitionen für
Dim Request AsXMLHTTP
Dim Response As DOMDocument
Dim Section As IXMLDOMNode
Dim Node As IXMLDOMNode
Wird warscheinlich in OOO noch nicht unterstütz
Anbei der Link zum Urheber und zu seiner ausführbare Excel-Datei (*schauder*)
http://joergnapp.de/geocoding_mit_excel/
http://joergnapp.de/wp-content/uploads/ ... coding.xls

Wenn Ihr ne Idee habt wie man das Tool umsetzen kann wäre ich dankbar.

Aber jetzt weiter zu eurem Problem:
Als Anregung für die Suche im Zielbereich:
Wenn man in einem 1. Schritt statt einem Umkreis ein Rechteck verwendet, kann mann die Grenzkoordinaten ausrechnen und muss dann nur prüfen ob der Ort der DB drin liegt.
z.B linke untere Ecke 12E 50N
rechte obere Ecke 13E 51N
dann sind alle orte 12E < OrtE <13E and 50N < OrtN < 51N im gesuchten Rechteckbereich.
Und für die kann man dann in einem 2. Schritt nochmal genauer nachrechnen

Die umsetzung des Tools ins OOO könnte also zur Lösung führen
Viele grüße
Mobbi

Re: Entfernungsberechnung über die PLZ

von marcel_at_work » Mo, 03.05.2010 16:04

Hi Volker,

jepp, der Open-Source-Gedanke ist einfach prima. Es macht doch einen Unterschied, wenn man für ein Programm kostspielige Erweiterungen kaufen muß, oder man sie auch selbst schreiben kann, wie z.B. in Blender, Gimp oder eben auch OOo. :D

Ich denke, dass das mit den Datenbanken auf jeden Fall eine gute Investition ist. Für deine eigenen Projekte brauchst du dann zudem auch nur eine einzige davon. Tabellen kannst du ja unendlich viele darin anlegen. :D

Viel Spaß noch...

LG, Marci

Re: Entfernungsberechnung über die PLZ

von vollkern » Mo, 03.05.2010 14:14

Hallo Marci,

danke für die Einblicke in Deine Hackerei (Hut ab vor der Vielfalt)! Mein Projekt ist etwas 'kleiner': Bäckerei-Organisations-Software mit Rezeptverwaltung, Produktionsaufträgen, Lieferscheine, Rechnungen, Tourenlisten. Gibts alles am Markt, aber kostet ca. 10 TEUR und ist NIE so wie ich es will. Also hab ichs selbst gebaut. Läuft auch ganz gut. Nur (um Dein PS zu beantworten) ist eben MS und davon wollte ich weg. Nicht daß ich mit dem Programm unzufrieden wäre, aber die update-Kosten sind zu hoch, bin jetzt seit 10 Jahren bei XP und Office 2000 und will einfach kein Geld in die Hand nehmen dafür.
Außerdem finde ich den Open-Source-Gedanken toll. Wollte mein Programm jetzt auf Calc umschreiben und dann hier irgendwo reinstellen, damit andere (Bäcker) da mitmachen können.

Auf jeden Fall danke für die Liste. Da mir keine 'Stündchen' sondern nur durchschnittlich eine Stunde täglich zur Verfügung steht, denke ich, daß ich in zwei Monaten so weit bin.

Gut Ding braucht Weile.

Liebe Grüße
Volker

Nach oben