Untertabellen ohne Verbindungsspalte

Aus FreiBier
Wechseln zu: Navigation, Suche

Ich möchte eine Tabelle mit einer Untertabelle verbinden, ohne dazu eine normale Verbindungsspalte zu benutzen.

Inhaltsverzeichnis

mein konkretes Beispiel

Ich möchte meine Veranstaltungen (für die Leihgüterverwaltung) nach Kalenderwochen sortieren. Mein erster Schritt war, das ich ein View erzeugt habe, das mir die kommenden Kalenderwochen in einer Tabelle abgezeigt hat. Nun kann ich also ein Fenster öffnen, in dem ich im ersten Register alle Kalenderwochen aufliste. So weit so gut. Nun möchte ich aber im nächsten Register alle Veranstaltungen aufgelistet haben, die in dieser Woche stattfinden.

Wo ist das Problem?

Das Problem ist, das die Veranstaltungen keine feste Kalenderwoche im Datensatz haben. Sie haben nur ein Start- und ein Enddatum. Mein erster Gedanke war, ein solches Feld einzufügen. Dann könnte man mit einem beforeSave() im Model oder mit einem Callout bei einer Änderung der Daten dafür sorgen, das dieses KW-Feld richtig besetzt wird. Man könnte dann über dieses Feld eine normale Verbindungsspalte erzeugen (ggf. müsste man noch die Parentspalte angeben). Allerdings ist der Fall hier noch etwas komplizierter, weil es ja auch gut denkbar ist, das eine Veranstaltung durch die auseinanderliegenden Start- und Enddaten sogar in mehreren Kalenderwochen liegt. Dann sollte sie in allen angezeigt werden. Wir brauchen also definitiv eine Art Formel.

Lösung (read-only)

Bei der Suche nach einer Lösung ist mir die WHERE-Clause aufgefallen, die man in einem Register angeben kann. Hier könnte man eine Formel angeben, die genau die Veranstaltungen heraussucht, um die es mir geht. Allerdings gibt es nun ein anderes Problem: Woher weiss ich in dieser Formel, welche Kalenderwoche ausgewählt ist? Um mich diesem Problem zu nähern, habe ich nach einiger Suche einen Breakpoint in die Funktion org.compiere.model.GridTable.createSelectSQL() (im Quellcode in base/src) gesetzt. Dort wird der SQL-String für die Abfrage der Datensätze zusammengesetzt und dabe iauch die WHERE-Clause, die man im Fenster "Fenster & Register" angeben kann, geparst. Dies geschieht mit der Methode Env.parseContext(...). Hierdurch können alle vorliegenden Kontext-Variablen benutzt werden. Welche "vorliegen", hat mir das Debugging gezeigt. Hier gibt es nun wohl auch den Wert "BAY_Kalenderwoche_V_ID".

Was ich übrigens noch nicht so richtig verstanden habe ist, das es dort zwei Schlüssel im Context-Hash gibt: "9|BAY_Kalenderwoche_V_ID" und "9|2|BAY_Kalenderwoche_V_ID". 9 ist meine Fensternummer und 2 ist wohl das Register innerhalb des Fensters. Deshalb ist es logisch, das man mit "9|2|..." zugreifen kann. Warum derselbe Wert nochmals ohne Angabe eines fixen Registers zugänglich ist, ist mir nicht ganz klar. Ich vermute, das hier eine Hilfe eingebaut ist, die einem die "wichtigen" Werte wie die momentan ausgewählten Datensatz-IDs der Register auf der höheren Ebene zur VErfügung stellt.

Nach dem Abenteuer mit dem Debugger konnte ich dann überprüfen, das alle vorhandenen Werte auch direkt in ADempiere über das Einstellungen-Fenster (Registerkarte "Kontext") sichtbar sind. Für das nächste Mal kann man die Suche der Kontext-Parameter also abkürzen. Dabei habe ich dann auch gesehen, das einige Felder des übergeordneten Datensatzes auch direkt im globalen Kontext (also ohne Registernummer davor) stehen. Daraufhin habe ich dann die folgende WHERE-Clause im der Definition meines Registers eingetragen:

 startDate>DATE '@start@'  AND startDate<DATE '@ende@' OR endDate>DATE '@start@' AND endDate<DATE '@ende@'

Nächstes Problem war ein seltsames Fehlverhalten, wenn man mein neues Register anklickt, ohne vorher eine Kalenderwoche ausgewählt zu haben. Es kam eine Fehlermeldung auf der Konsole (log-Meldung) mit dem Inhalt "Failed to parse where clause...". Ist ja logisch, die verwendeten Kontext-Valiablen sind ja auch nicht gesetzt. Hiergegen konnte ich leider bisher nichts tun - letztlich fällt das aber auch keinem Anwender auf.

read-write

Normale Unterlisten sind ja auch beschreibbar insofern, das man einen neuen Datensatz einfügen kann und bei diesem dann automatisch die VErbindungsspalte auf den aktuellen Wert gesetzt wird und schreibgeschützt wird. Bei meiner Lösung ist das nicht so trivial und bedeutet letztlich, das man beim Einfügen eines Datensatzes irgendwie Code ausführt, der dann Informationen über den Kontext hat. An dieser Stelle habe ich jetzt (noch) nicht weiter geforscht. Man kann also Datensätze einfügen (oder natürlich das Einfügen im Register auch komplett abschlaten), kann aber nicht sicherstellen, das diese auch später noch im Register bleiben, ob also der Wertebereich der vorhandenen WHERE-Formel entspricht.

Meine Werkzeuge
Namensräume

Varianten
Aktionen
Navigation
Werkzeuge