Seite 1 von 1
Formular: Per Macro zu Datensatz springen
Verfasst: Mi, 19.07.2006 20:22
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?
Verfasst: Do, 20.07.2006 13:17
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:
. wobei mit nZe eine absolute zeilennummer im Rowset (also z.B. der 10. Datensatz -> 10) übergeben wird.
Mit
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
Verfasst: So, 13.08.2006 14:23
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
Verfasst: So, 13.08.2006 17:13
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
Verfasst: Mo, 14.08.2006 18:53
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
Verfasst: Mo, 14.08.2006 20:29
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
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
Verfasst: Di, 15.08.2006 09:12
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
Verfasst: Di, 15.08.2006 14:13
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

Verfasst: Mi, 16.08.2006 18:09
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.

Verfasst: Do, 17.08.2006 14:22
von Mihilist
Bratmatzen hat geschrieben:Man müsste allerdings noch etwas einbauen um Probleme beim runden zu vermeiden.

Nicht unbedingt. Integervariablen kennen den /-Operator, ist identisch mit DIV. Zumindest isses in QBasic so

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

Verfasst: Do, 14.09.2006 16:32
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
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
RowSetClone
Verfasst: Di, 19.09.2006 16:50
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:

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?

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