Formular: Per Macro zu Datensatz springen

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

laura36
**
Beiträge: 27
Registriert: Fr, 24.03.2006 16:29

Formular: Per Macro zu Datensatz springen

Beitrag von laura36 »

Liebe ListenleserInnen,

ich habe vergeblich eine Möglichkeit gesucht, um in einem Formular zu einem Datensatz zu springen. Weiß jemand wie das geht?

Hintergrund: In einem Formular gebe ich neue Daten ein. Über ein Listenfeld trage ich Daten aus einer anderen Tabelle ein. Wenn aber in die andere Tabelle erst noch ein neuer Datensatz eingefügt werden muß, müsste das Formular neu geladen werden, damit die Daten aus der anderen Tabelle im Listenfeld auszuwählen sind.

Ich würde jetzt gerne über einen Button ein Reload des Formulars ermöglichen, dann aber sofort wieder zu dem Datensatz springen, den ich gerade bearbeitet hatte.

Wenn ich ein normales Reload mache, bin ich immer wieder am Anfang der Tabelle.

Das Makro könnte so aussehen (einzig die Methode Gehe-Zu-Datensatz-Nr(x) fehlt... ;-)

Code: Alles auswählen

Sub reloadForm
	DIM oForm AS OBJECT
	oForm = ThisComponent.Drawpage.Forms.getByName("Form1")
	AktuelleID=oForm.getstring(1)
'	oForm.reload
	oForm.Gehe-Zu-Datensatz-Nr(AktuelleID)
End Sub
Gefunden habe ich nur moveToCurrentRow(). Aber das funktioniert nicht...

Jemand eine Idee?
Danke und Grüße
laura

Gibt es eine Möglichkeit gezielt nach solchen Befehlen zu suchen?
Toxitom
********
Beiträge: 3769
Registriert: Di, 12.08.2003 18:07
Wohnort: Wiesbaden
Kontaktdaten:

Beitrag von Toxitom »

Hey Laura,
dann aber sofort wieder zu dem Datensatz springen, den ich gerade bearbeitet hatte.
Weisst du denn, welchen du gerade bearbeitet hast?

Natürlich gibt es ganz einfache Methoden, zu einem bestimmten Datensatz zu springen:

Code: Alles auswählen

oform.absolute(nZe)
. wobei mit nZe eine absolute zeilennummer im Rowset (also z.B. der 10. Datensatz -> 10) übergeben wird.
Mit

Code: Alles auswählen

oForm.relative(nZe)
gehst du vom aktuellen Datensatz um nZe Datensätze weiter .
Also, da gibt es genug Methoden - vorausgesetzt, dein Daten-Resultset unterstützt den wahlfreine Zugriff.
Gibt es eine Möglichkeit gezielt nach solchen Befehlen zu suchen?
Na, alles steht in der API. in der Objektstruktur und Erläuterung.
Startseite : -> hier
Aber:
Woher weisst du eigentlich die Datensatz-Nummer? das ist immer mit Risko verbunden. Eigentlich solltest du ein Suchkriterium definierern (SQL-Abfrage) und den dadurch erzeugten Datensatz anzeigen :-)

Gruss
Thomas
Unterstützer LibreOffice, zertifizierter Trainer und Berater
Bücher: LibreOffice 6- Einstieg und Umstieg
Makros Grundlagen - LibreOffice / OpenOffice Basic
Bratmatzen
**
Beiträge: 27
Registriert: So, 05.03.2006 15:12
Wohnort: Schwoiga

Beitrag von Bratmatzen »

Hallo,
soryy das ich nochmal auf diesen alten Beitrag poste. Ich hatte das gleiche probelm und recht einfach wie folgt gelöst:

Code: Alles auswählen

Sub Relaod
Dim Book%, oForm as Object
      oForm = ThisComponent.DrawPage.Forms(0)
      Book = oForm.getBookmark
      oForm.reload
      oForm.moveToBookmark (Book)
End Sub
Hab jetzt aber ein anderes Problem weswegen ich eigendlich poste. Im Formular werden Datensätze mit verschiedenen Datums angeziegt. Ich möchte das nach dem Starten automatisch der Datensatz mit dem aktuellste Datum angezeigt wird.
Ich möchte dann aber beliebig blättern können, also ohne Filter arbeiten.

@Toxitom: Wie meinst du das mit dem erstellen eines Suchkriteriums. Vielleicht kann ich diese Suche für mein Vorhaben verwenden. Wie funktioniert die Suche inerhalb von Formular Datensätzen über ein Makro ?

Vielen Dank im voraus,
Matze
Toxitom
********
Beiträge: 3769
Registriert: Di, 12.08.2003 18:07
Wohnort: Wiesbaden
Kontaktdaten:

Beitrag von Toxitom »

Hey Matze,
Wie meinst du das mit dem erstellen eines Suchkriteriums.
Jedes Formular ist eigentlich "nur" eine Abfrage, also ein SQL-Select Befehl, der beliebig eingegrenzt werden kann. Aus der Abfrage ergibt sich dann ein "Resultset", also eine Tabelle mit den passenden Datensätzen. Das Formular wiederum zeigt dann immer einen dieser Datensätze an und du kannst mit der Navigation diese durchscrollen.
Insofern kannst du auch eine direkte Select-Abfrage mit dem Formular verknüpfen und dort das entsprechende Suchkriterium eingeben., also z.B. SELECT * FROM Tabelle1 WHERE ID = 4 - liefert dir den Datensatz deiner ürsprünglichen Datenbank mit der ID 4 - und nur der wird dann im Formular angezeigt.
Im Formular werden Datensätze mit verschiedenen Datums angeziegt. Ich möchte das nach dem Starten automatisch der Datensatz mit dem aktuellste Datum angezeigt wird.
Im Fromular wird immer automatisch der erste Datensatz des Resultsets angezeigt. Da hst du zunächst keinen Einfluss darauf. Nun köntest du natürlich mit dem Formular ein Makro starten, dass deine Datensätze zuerst durchsucht, das "aktuelleste" herausfindet und den entsprechenden Datensatz "läd". Wenn du gleichzeitig die Controller blockiertst, wird der Bildschirm nicht neu aufgebaut - das alles geschieht also im Hintergrund. Ist aber wahrscheinlich zu aufwendig.
Einfacher:
Erzeuge dir eine Abfrage und sortiere die nach der Datumsspalte, so dass der aktuelleste Datensatz dann auch gleichzeitig der erste ist. Auf diese Abfrage läst du nun dein Formular basieren. Jetzt wird immer der erste Datensatz (der aktuellste) angezeigt. Alle anderen sind ebenfalls noch da un du kannst durchscrollen mit den Navigationsbuttons.

Gruss
Thomas
Unterstützer LibreOffice, zertifizierter Trainer und Berater
Bücher: LibreOffice 6- Einstieg und Umstieg
Makros Grundlagen - LibreOffice / OpenOffice Basic
Bratmatzen
**
Beiträge: 27
Registriert: So, 05.03.2006 15:12
Wohnort: Schwoiga

Beitrag von Bratmatzen »

Hallo Toxitom,
danke für deine schnelle Antwort.
Das Problem ist, dass es sich um eine art Terminkalender handelt, in dem Termine für das laufende Jahr stehen, also auch Termine die in der Zukunft liegen. Deshalb kann ich die Datensätze nicht einfach nach dem Datum sortieren.

Wenn ich es richtig sehe besteht die einzigste möglichkeit darin in dem resultset zu Blättern und das gespeicherte Datum mit dem aktuellen zu vergeleichen.
Um die Prozedur zuz beschleunigen müsste ich vielleicht eine Prozedur entwickeln, die in großen schritten vorwärts Blättert, bis das Datum in der Zukunft liegt um sich dann rückwärts anzunähern.
Ich glaub ich werd mal n bisschen basteln.

Wie kann ich die Controller blockieren um ein neuladen des Bildschirms zu verhindern?

Gruß Matze
Bratmatzen
**
Beiträge: 27
Registriert: So, 05.03.2006 15:12
Wohnort: Schwoiga

Beitrag von Bratmatzen »

Hallo,
einige werden mich jetzt zwar wahrscheinlich für verrückt erklären, aber ich hab in der lezten Stunde mal bissle rum probiert und bin zu folgendem (sogar funktionierendem) Ergebnis gekommen :lol:

Code: Alles auswählen

Sub Aktuell
dim Datum as Date, oForm as Object, FDatum as Date, a%, last%	'FDatum = Datum im Formular

	oForm = ThisComponent.DrawPage.Forms.getByName("Veranstaltung")
	datum = date
	a = 60
	oForm.last
	last = oForm.getBookmark
	oForm.first
	msgBox "Anzahl Seiten: " +last+ " ."
	oForm. moveToBookmark(60)
	Do
		FDatum = oForm.getByName("txtDatum").string
		msgBox "Formular Datum: " +FDatum +" Heute: "+ Datum + " ."
		If FDatum < datum then				'Überprüfe ob FDatum älter und blättre weiter
			If a > last then
				print "Zu weit"
				a = a - 1
				oForm.moveToBookmark(a)
				print a
			else
				a = a + 5
				print "Blätter 5 vorwärts"
				oForm.moveToBookmark(a)
			End If
		else
			If FDatum = Datum then			'Aktuell gefunden
				print "aktuell gedunden"
			else
				If a = 0 then				'kein alter Eintrag vorhanden, aktuellstes DAtum erreicht
					msgbox "Aktuellstes Datum (keine alten Vorhanden)"
					Exit Do
				else
					Do
						If FDatum > Datum then
							oForm.previous 		'Rückwärts Blättern bis FDatum älter als Datum
							print "Blättere rückwärts"
							FDatum = oForm.getByName("txtDatum").string
						else
							If FDatum = Datum then
								print "Heutiges Datum erreicht"
								Exit do
							Else
								print "leztes Altes Datum erreicht"
								oForm.next 			'nächstes Datum in der Zukunft
								Exit Do
							End IF
						End IF
					loop
				End If
			End If
			Exit Do
		End If
	loop while FDatum <> 0

End Sub
Ich hoff mal ihr könnt mit den Kommentaren was anfangen. Sind grad noch einige Nachrichtenfenster zur Kontrolle drin und hab die Startpostion zum Testen auf 60 gestellt, da ich sonst so oft blätteern müsste.
Bin immer offen für Verbesserungsvorschläge....

Noch etwas: Ich hatte beim auslesen des FormularDatums aus einem Datumsfeld (.date Methode) porbeleme, da immer ein falsches Datum (z.B. 01.05.-8795) gelesen wurde. Nach dem Umwandeln in ein Textfeld und mit der .string methode ging alles Problemlos. Hatte jemand schon ein ähnliches Problem??

Gruß Matze
Toxitom
********
Beiträge: 3769
Registriert: Di, 12.08.2003 18:07
Wohnort: Wiesbaden
Kontaktdaten:

Beitrag von Toxitom »

Hey Matze,

nun ja, wenn es denn funktioniert....

Mir erscheint die Lösung als sehr umständlich und aufwendig - aber wenn es geht ;-)

Ich hab mir den ganzen Thread nochmals durchgelesen - aber so ganz klar, was du eigentlich erreichen möchtest, ist mir die Sache noch nicht. Aber egal.

Die kleinen Fragen kann ich dir beantworten :-)
Wie kann ich die Controller blockieren um ein neuladen des Bildschirms zu verhindern?
mit der Methode "lockcontrollers()" und zum entsperren mit "unlockcontrollers()" - jeweils angewendet auf das Dokumentenobjekt. Bei dir also:

Code: Alles auswählen

ThisComponent.lockcontrollers()
....
thisComponent.unlockControllers()
Ich hatte beim auslesen des FormularDatums aus einem Datumsfeld (.date Methode) porbeleme, da immer ein falsches Datum (z.B. 01.05.-8795) gelesen wurde. Nach dem Umwandeln in ein Textfeld und mit der .string methode ging alles Problemlos. Hatte jemand schon ein ähnliches Problem??
Nein (weil es kein Problem ist) und ja (weil man es beim Nichtwissen als Problem sehen könnte ;-) )
Ein Datumsfeld im Formular liefert als Date-Wert ein Datum im ISO-Format! Das ist anders, als das übliche Basic oder Calc Datumsformat: JJJJMMTT - 8 Stellen, als "long", das ist das Datum im Iso-Format. Um das zu erzeugen oder umzuwandeln, bietet OOo Basic die Funktionen "CDateToISO(dVar)" bzw. "CDateFromISO(dISO)", wobei "dVar" eine interen Datevaraible sein muss und diese dann die entsprechende ISO Varaible erzeugt und umgekehrt. Und dann klappt es auch mit den Datumsvariablen :-)

Viele Grüße
Thomas
Unterstützer LibreOffice, zertifizierter Trainer und Berater
Bücher: LibreOffice 6- Einstieg und Umstieg
Makros Grundlagen - LibreOffice / OpenOffice Basic
Mihilist
****
Beiträge: 120
Registriert: Di, 25.04.2006 15:27
Wohnort: Nürnberg
Kontaktdaten:

Beitrag von Mihilist »

Toxitom hat geschrieben:Ich hab mir den ganzen Thread nochmals durchgelesen - aber so ganz klar, was du eigentlich erreichen möchtest, ist mir die Sache noch nicht. Aber egal.
Sein Problem ist, dass die Einträge zwar sortiert sind, aber er nicht beim obersten oder untersten element anfangen will ;)

Zum Problem: Hab dein Makro nur überflogen, aber vermutlich findest du schneller ein Ergebnis, wenn du wie folgt vorgehst (Pseudocode, weil keine Zeit *g*)

Code: Alles auswählen

zeile1 = 1
zeile2 = letzte_zeile
do
    if [(zeile1 + zeile2) / 2].datum > heute then
        zeile2 = (zeile1 + zeile2) / 2
    else
        zeile1 = (zeile1 + zeile2) / 2
    end if
until (zeile1.datum = heute ODER zeile1 = zeile2)
zeile1 sollte nun entweder das heutige Datum haben, oder - falls kein aktueller eintrag existiert - zumindest nah dran sein.

Nur so eine spontane Idee. Kannst ja mal ausprobieren ;)
Bratmatzen
**
Beiträge: 27
Registriert: So, 05.03.2006 15:12
Wohnort: Schwoiga

Beitrag von Bratmatzen »

Vilene Dank für eure antworten
mit der Methode "lockcontrollers()" und zum entsperren mit "unlockcontrollers()" - jeweils angewendet auf das Dokumentenobjekt.
Hab das bei mit mal getest, aber keinen Vorteil gesehen, man sieht immer noch wie die Datensätze durchgeblättert werden.:?:
Ein Datumsfeld im Formular liefert als Date-Wert ein Datum im ISO-Format! Das ist anders, als das übliche Basic oder Calc Datumsformat: JJJJMMTT - 8 Stellen, als "long", das ist das Datum im Iso-Format.
Das wusste ich bis jetzt nicht. Werd ich bei gelegenheit mal beil mir einbauen :)
Zum Problem: Hab dein Makro nur überflogen, aber vermutlich findest du schneller ein Ergebnis, wenn du wie folgt vorgehst (Pseudocode, weil keine Zeit *g*)
Werd das mal ausprobieren wenn ich Zeit hab. Mein aktuelles Makro braucht bei 72 Datensätzen ca. 2s um den 71. als aktuellsten zu finden (im vergleich zum Starten von OOO sehr schnell). :)
Man müsste allerdings noch etwas einbauen um Probleme beim runden zu vermeiden. :wink:
Mihilist
****
Beiträge: 120
Registriert: Di, 25.04.2006 15:27
Wohnort: Nürnberg
Kontaktdaten:

Beitrag von Mihilist »

Bratmatzen hat geschrieben:Man müsste allerdings noch etwas einbauen um Probleme beim runden zu vermeiden. :wink:
Nicht unbedingt. Integervariablen kennen den /-Operator, ist identisch mit DIV. Zumindest isses in QBasic so :D
Also: (2+3)/2 = 2

Ich hab eben diese Rechnung in StarBasic mal zu Probe ausprobiert, und es kommt 3 raus. Aber immerhin wieder eine Integerzahl :)
Mihilist
****
Beiträge: 120
Registriert: Di, 25.04.2006 15:27
Wohnort: Nürnberg
Kontaktdaten:

Beitrag von Mihilist »

Bratmatzen hat geschrieben:
mit der Methode "lockcontrollers()" und zum entsperren mit "unlockcontrollers()" - jeweils angewendet auf das Dokumentenobjekt.
Hab das bei mit mal getest, aber keinen Vorteil gesehen, man sieht immer noch wie die Datensätze durchgeblättert werden.:?:
Ich glaube ich weiß, was du meinst und hab das selbe Problem eben gelöst =)

Du willst, dass nicht im Formular sichtbar durch die Datensätze geblättert wird, oder? Das ist ganz einfach: Indem du nicht im Set des Formulars herumpfuschst :D

Code: Alles auswählen

Dim oForm As Object
Dim ds As Object

oForm = ThisComponent.undSoWeiter()
ds = oForm.createResultSet
In ds sollten nun genau die gleichen Datensätze wie in oForm sein (inklusive Filter!), du kannst also nun in rset herumsuchen, ohne dass in oForm die Anzeige ständig geändert wird.

Hoffe das war es, was du meintest!

Grüße
Thomas
Mihilist
****
Beiträge: 120
Registriert: Di, 25.04.2006 15:27
Wohnort: Nürnberg
Kontaktdaten:

RowSetClone

Beitrag von Mihilist »

Hallöle

Nun hab ich so toll diese .createResultSet() entdeckt, und hab mich schon gefreut, dass ich nun alles viel schöner machen kann... aaaber: Großes Problem. Diese Methode produziert mir ein RowSetClone, und das Ding kann ich nicht filtern...
Fragen:

:?: Warum nicht? *g*
:?: Wie kann ich das umgehen?

Konkreter:
:arrow: Ich habe ein gefiltertes Set im Formular. Kann ich nun irgendwie das ungefilterte Set herbekommen, ohne im Formular den Filter aufzuheben und .reload() auszuführen?
:arrow: Andersrum: Ich hab keinen Filter im Formular, will aber mein Set im Makro filtern, ohne dass der Anwender das sieht (das Gewackel im Formular nervt nämlich...)

Grüße
Thomas
Antworten