|
01.11.2009
Combobox Master-Detail in Formularen
Für dieses Beispiel benötigen Sie die Beispiel-Datenbank FAHRZEUGE und das Projekt fahrzeuge.xdev.
» Die Master-Combobox gehört nicht zum Formular «
Aus programmiertechnischer Sicht ist eine Master-Combobox in einem Eingabeformular unnötig, da i.d.R. in einem relationalen Datenmodell die Master-ID ohnehin beim Detail-Wert gespeichert ist. Zum Beispiel ergibt sich durch die Auswahl eines Fahrzeugmodells der Hersteller automatisch, da in der Modell-Tabelle zu jedem Modell automatisch die jeweilige Hersteller-ID gespeichert wird. Die Master-Combobox ist vielmehr nur ein Hilfsmittel für den Anwender, um damit die Auswahlmöglichkeit in der Detail-Combobox einzugrenzen und somit zu erleichtern. Da die Auswahl in der Master-Combobox beim Speichern des Formulars ohnehin nicht mitgespeichert wird, muss diese auch nicht zwingend im Formular liegen und muss nicht mit einem Datenfeld verknüpft werden.

|

|
|
Die Master-Combobox Hersteller gehört nicht zum Formular, da der Hersteller nicht in der Tabelle Fahrzeuge abgespeichert wird, siehe ER-Diagramm. Bei der Auswahl des Modells ergibt sich der Hersteller automatisch, da die Hersteller-ID zum Modell gespeichert wird. Die Hersteller-Combobox dient lediglich dazu, die Auswahlmöglichkeiten in der Modell-Combobox einzugrenzen und ist somit lediglich eine Hilfe für den Anwender.
|
|
» Die Master-Combobox muss manuell angesteuert werden «
Umgekehrt wird die Master-Combobox aber auch beim Füllen des Formulars nicht berücksichtigt und bleibt daher unverändert. Dies wäre jedoch nicht anwenderfreundlich und würde wie ein Programmfehler aussehen. Deshalb muss die Master-Combobox nach dem Füllen des Formulars manuell angesteuert werden, um den entsprechenden Wert anzuzeigen. Dazu ist jedoch nur 1 Methodenaufruf notwendig.

|

|
Häufig muss ein Datensatz von einer Table in ein Formular übertragen werden. Bei den Daten handelt es sich dabei i.d.R. um Werte, die aus mehreren Tabellen zusammengeführt werden, z.B. Fahrzeugdaten, die aus den Tabellen FAHRZEUGE, MODELLE, HERSTELLER, FARBE usw. Die Übertragung des Datensatzes lässt sich mit wenigen Zeilen Code realisieren. Abschließend muss die Master-Combobox angesteuert werden, da diese beim Füllen des Formulars nicht berücksichtigt wird.
|
» Ereignis-Konflikt bei der Auswahl «
Programmierte Ereignisse können in Ausnahmefällen unerwünscht sein und müssen daher unterdrückt werden. Dies ist u.a. auch bei Master-Detail Comboboxen i.V.m. einem Formular der Fall. Die Auswahl in einer Master-Combobox führt dazu, dass eine Detail-Combobox neu gefüllt wird, und zwar nur mit bestimmten Werten, z.B. mit Modellen eines bestimmten Automobilherstellers. Diese Funktion ist konkret beim Anlegen eines neuen Datensatzes erwünscht. Da jedoch bei der Übertragung eines Datensatzes in das Formular die Master-Combobox nicht berücksichtigt wird, muss diese gezielt angesteuert werden, nur um einen passenden Wert anzuzeigen, z.B. den zum Datensatz passenden Hersteller. Dabei ändert sich jedoch automatisch die Selektierung in der Combobox, sodass das Ereignis ON_SELECTION_CHANGE ( ) | XDEV NLS: Bei Änderung Auswahl ( ) ausgelöst wird, wodurch wiederum die Detail-Combobox neu gefüllt wird und den zuvor übertragenen Wert verliert. In so einem Fall kann die Ausführung entsprechenden Aktionen, z.B. das neu Füllen der Detail-Combobox, mit Hilfe eines sog. Flags i.V.m. mit einer simplen Abfrage verhindert werden. Ein Flag kann z.B. eine Variable sein, deren Inhalt einen bestimmten Zustand entspricht, z.B. gesperrt.
Tipp: Die Werte der Master-Combobox gehören nicht zum Formular-Datensatz, z.B. Hersteller. Somit muss sich die Master-Combobox nicht zwingend im Formular befinden.
|
Hinweis: Da die Master-Combobox nicht zum Formular-Datensatz gehört, wird diese beim Füllen des Formulars nicht berücksichtigt und muss daher manuell angesteuert werden.
|
Table - Füllen des Formulars mit einem Datensatz aus einer Table:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
ON_SELECTION_CHANGE ( )
{
// Füllt die Detail-Combobox neu
XDEV Query #MODELLE << MODELLE;
ComboboxModelle.listItems.fillFromVT(#MODELLE, "MODELL", "ID");
// Füllt das Formular mit dem in der Table selektierten Datensatz
Int zeile = this.getSelectedRow();
Int ID = #FAHRZEUGE_JOIN.getValueAt(zeile, "ID");
XDEV Query #FAHRZEUGE << FAHRZEUGE;
Formular.fillFromVT(#FAHRZEUGE, 0);
// Steuert die Master-Combobox an und übergibt den Hersteller
Int modellID = #FAHRZEUGE.getValueAt(0, "MODELL_ID");
XDEV Query #MODELLE << MODELLE;
Int herstellerID = #MODELLE.getValueAt(0, "HERSTELLER_ID");
ComboboxHersteller.setSelectedData(herstellerID);
// Blockiert die Ausführung von ON_SELECTION_CHANGE bei der Master-Combobox
ComboboxHersteller.setTagData"gesperrt");
}
|
ON_SELECTION_CHANGE ( )
Führt den Code bei der Änderung der Auswahl bei einer Table aus.
XDEV Query #MODELLE << MODELLE;
Datenbankabfrage. Selektiert die Datenfelder ID und MODELL und holt alle Datensätze der Datenbank-Tabelle MODELLE.
Abfragebedingung: keine.
ComboboxModelle.listItems.fillFromVT(#MODELLE, "MODELL", "ID");
Füllt die Modell-Combobox mit den Daten aus der Virtuellen Tabelle #MODELLE. Die sichtbaren Combobox-Einträge werden aus dem Datenfeld MODELL ausgelesen, die jeweiligen IDs aus dem Datenfeld ID.
Int zeile = this.getSelectedRow( );
Legt eine Integer-Variable mit dem Namen zeile an und weist dieser den Index der selektierten Zeile in der Table zu.
Int ID = #FAHRZEUGE_JOIN.getValueAT(zeile, "ID");
Legt eine Integer-Variable mit dem Namen ID an und weist dieser die Fahrzeug-ID zu, die aus der Virtuellen Tabelle #FAHRZEUGE_JOIN in der Spalte ID und der Zeile zeile ausgelesen wird. In der Virtuellen Tabelle #FAHRZEUGE_JOIN befindet sich das Abfrageergebnis einer Datenbankabfrage über sämtliche Datenbank-Tabellen, die mit der Tabelle FAHRZEUGE verknüpft sind, um alle Fahrzeugdaten in der Table anzuzeigen.
XDEV Query #FAHRZEUGE << FAHRZEUGE;
Datenbankabfrage. Liefert alle Datensätze der Tabelle FAHRZEUGE mit der zuvor ermittelten Datensatz-ID ID.
Abfragebedingung: #FAHRZEUGE.ID = ID.
Formular.fillFromVT(#FAHRZEUGE, 0);
Füllt das Formular mit dem Datensatz mit dem Index 0 in der Virtuellen Tabelle #FAHRZEUGE.
Int modellID = #FAHRZEUG.getValueAt(0,"MODELL_ID";
Legt eine Integer-Variable mit dem Namen modellID an und weist dieser die Modell-ID zu, die aus der Virtuellen Tabelle #FAHRZEUGE in der Zeile mit dem Index 0 und in der Spalte MODELL_ID ausgelesen wird.
XDEV Query #MODELLE << MODELLE;
Datenbankabfrage. Liefert alle Datensätze der Tabelle FAHRZEUGE mit der zuvor ermittelten Modell-ID modellID.
Abfragebedingung: #FAHRZEUGE.MODELL_ID = modellID.
Int herstellerID = #MODELLE.getValueAt(0, "HERSTELLER_ID");
Legt eine Integer-Variable mit dem Namen herstellerID an und weist dieser die Hersteller-ID zu, die aus der Virtuellen Tabelle #MODELLE in der Zeile mit dem Index 0 und in der Spalte HERSTELLER_ID ausgelesen wird.
ComboboxHersteller.setSelectedData(markenID);
Selektiert in der Hersteller-Combobox den Wert mit der ID herstellerID.
ComboboxHersteller.setTagData("gesperrt");
Speichert in den Zusatzdaten der Hersteller-Combobox den Wert gesperrt als Status-Flag.
ComboboxHersteller - Füllen der Detail-Combobox:
1
2
3
4
5
6
7
8
9
10
|
ON_SELECTION_CHANGE ( )
{
if (this.getTagData()="")
{
Int herstellerID = this.getSelectedData();
XDEV Query #MODELLE << MODELLE;
ComboboxModelle.listItems.fillFromVT(#MODELLE, "MODELL", "ID");
}
this.setTagData("");
}
|
ON_SELECTION_CHANGE ( )
Führt den Code bei bei einer Änderung der Auswahl in der Combobox aus.
if (this.getTagData()="")
Prüft, ob die Zusatzdaten der Combobox leer sind. Der IF-Block, durch den die Modell-Combobox neu gefüllt wird, wird nur dann ausgeführt, wenn die Zusatzdaten leer sind. Der IF-Block wird nicht ausgeführt, wenn der Wert gesperrt in den Zusatzdaten steht.
Int herstellerID = this.getSelectedData();
Legt eine Integer Variable mit dem Namen herstellerID an und weist dieser die ID des in der Combobox selektierten Eintrages zu.
XDEV Query #MODELLE << MODELLE;
Datenbankabfrage: Selektiert in der Datenbank-Tabelle MODELLE die Datenfelder ID und MODELL.
Abfragebedingung: #MODELLE.HERSTELLER_ID = herstellerID.
ComboboxModelle.listItems.fillFromVT(#MODELLE, "MODELL", "ID");
Füllt die Combobox mit den Daten aus der Virtuellen Tabelle #MODELLE. Die sichtbaren Combobox-Einträge werden aus dem Datenfeld MODELL ausgelesen, die jeweiligen IDs aus dem Datenfeld ID.
this.setTagData("");
Löscht die Zusatzdaten der Combobox. Dadurch wird bei der nächsten Änderung der Selektierung die Combobox wieder neu gefüllt.
|
Table - Füllen des Formulars mit einem Datensatz aus einer Table:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
ON_SELECTION_CHANGE ( )
// Füllt die Detail-Combobox neu
XDEV Query #MODELLE << MODELLE
ComboboxModelle.listItems.fillFromVT(#MODELLE, "MODELL", "ID")
// Füllt das Formular mit dem in der Table selektierten Datensatz
Int zeile = this.getSelectedRow()
Int ID = #FAHRZEUGE_JOIN.getValueAt(zeile, "ID")
XDEV Query #FAHRZEUGE << FAHRZEUGE
Formular.fillFromVT(#FAHRZEUGE, 0)
// Steuert die Master-Combobox an und übergibt den Hersteller
Int modellID = #FAHRZEUGE.getValueAt(0, "MODELL_ID")
XDEV Query #MODELLE << MODELLE
Int herstellerID = #MODELLE.getValueAt(0, "HERSTELLER_ID")
ComboboxHersteller.setSelectedData(herstellerID)
// Blockiert die Ausführung von ON_SELECTION_CHANGE bei der Master-Combobox
ComboboxHersteller.setTagData"gesperrt")
|
ON_SELECTION_CHANGE ( )
Führt den Code bei der Änderung der Auswahl bei einer Table aus.
XDEV Query #MODELLE << MODELLE
Datenbankabfrage. Selektiert die Datenfelder ID und MODELL und holt alle Datensätze der Datenbank-Tabelle MODELLE.
Abfragebedingung: keine.
ComboboxModelle.listItems.fillFromVT(#MODELLE, "MODELL", "ID")
Füllt die Modell-Combobox mit den Daten aus der Virtuellen Tabelle #MODELLE. Die sichtbaren Combobox-Einträge werden aus dem Datenfeld MODELL ausgelesen, die jeweiligen IDs aus dem Datenfeld ID.
Int zeile = this.getSelectedRow( )
Legt eine Integer-Variable mit dem Namen zeile an und weist dieser den Index der selektierten Zeile in der Table zu.
Int ID = #FAHRZEUGE_JOIN.getValueAT(zeile, "ID")
Legt eine Integer-Variable mit dem Namen ID an und weist dieser die Fahrzeug-ID zu, die aus der Virtuellen Tabelle #FAHRZEUGE_JOIN in der Spalte ID und der Zeile zeile ausgelesen wird. In der Virtuellen Tabelle #FAHRZEUGE_JOIN befindet sich das Abfrageergebnis einer Datenbankabfrage über sämtliche Datenbank-Tabellen, die mit der Tabelle FAHRZEUGE verknüpft sind, um alle Fahrzeugdaten in der Table anzuzeigen.
XDEV Query #FAHRZEUGE << FAHRZEUGE
Datenbankabfrage. Liefert alle Datensätze der Tabelle FAHRZEUGE mit der zuvor ermittelten Datensatz-ID ID.
Abfragebedingung: #FAHRZEUGE.ID = ID.
Formular.fillFromVT(#FAHRZEUGE, 0)
Füllt das Formular mit dem Datensatz mit dem Index 0 in der Virtuellen Tabelle #FAHRZEUGE.
Int modellID = #FAHRZEUG.getValueAt(0,"MODELL_ID"
Legt eine Integer-Variable mit dem Namen modellID an und weist dieser die Modell-ID zu, die aus der Virtuellen Tabelle #FAHRZEUGE in der Zeile mit dem Index 0 und in der Spalte MODELL_ID ausgelesen wird.
XDEV Query #MODELLE << MODELLE
Datenbankabfrage. Liefert alle Datensätze der Tabelle FAHRZEUGE mit der zuvor ermittelten Modell-ID modellID.
Abfragebedingung: #FAHRZEUGE.MODELL_ID = modellID.
Int herstellerID = #MODELLE.getValueAt(0, "HERSTELLER_ID")
Legt eine Integer-Variable mit dem Namen herstellerID an und weist dieser die Hersteller-ID zu, die aus der Virtuellen Tabelle #MODELLE in der Zeile mit dem Index 0 und in der Spalte HERSTELLER_ID ausgelesen wird.
ComboboxHersteller.setSelectedData(markenID)
Selektiert in der Hersteller-Combobox den Wert mit der ID herstellerID.
ComboboxHersteller.setTagData("gesperrt")
Speichert in den Zusatzdaten der Hersteller-Combobox den Wert gesperrt als Status-Flag.
ComboboxHersteller - Füllen der Detail-Combobox:
1
2
3
4
5
6
7
8
|
ON_SELECTION_CHANGE ( )
If This.getTagData()="" Then
Int herstellerID = this.getSelectedData();
XDEV Query #MODELLE << MODELLE;
ComboboxModelle.listItems.fillFromVT(#MODELLE, "MODELL", "ID");
End If
this.setTagData("");
|
ON_SELECTION_CHANGE ( )
Führt den Code bei bei einer Änderung der Auswahl in der Combobox aus.
If Tthis.getTagData()="" Then
Prüft, ob die Zusatzdaten der Combobox leer sind. Der IF-Block, durch den die Modell-Combobox neu gefüllt wird, wird nur dann ausgeführt, wenn die Zusatzdaten leer sind. Der IF-Block wird nicht ausgeführt, wenn der Wert gesperrt in den Zusatzdaten steht.
Int herstellerID = this.getSelectedData()
Legt eine Integer Variable mit dem Namen herstellerID an und weist dieser die ID des in der Combobox selektierten Eintrages zu.
XDEV Query #MODELLE << MODELLE
Datenbankabfrage: Selektiert in der Datenbank-Tabelle MODELLE die Datenfelder ID und MODELL.
Abfragebedingung: #MODELLE.HERSTELLER_ID = herstellerID.
ComboboxModelle.listItems.fillFromVT(#MODELLE, "MODELL", "ID")
Füllt die Combobox mit den Daten aus der Virtuellen Tabelle #MODELLE. Die sichtbaren Combobox-Einträge werden aus dem Datenfeld MODELL ausgelesen, die jeweiligen IDs aus dem Datenfeld ID.
End If
Markiert das Ende des If-Blocks.
This.setTagData("")
Löscht die Zusatzdaten der Combobox. Dadurch wird bei der nächsten Änderung der Selektierung die Combobox wieder neu gefüllt.
|
Table - Füllen des Formulars mit einem Datensatz aus einer Table:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
Bei Änderung Auswahl ( )
// Füllt die Detail-Combobox neu
XDEV Datenbankabfrage #MODELLE << MODELLE
ComboboxModelle\listenEinträge\fülleAusVirtuellerTabelle(#MODELLE,"MODELL","ID")
// Füllt das Formular mit dem in der Table selektierten Datensatz
Ganzzahl zeile = Lokal\holeSelektierteZeile()
Ganzzahl ID = #FAHRZEUGE_JOIN\holeWert(zeile, "ID")
XDEV Datenbankabfrage #FAHRZEUGE << FAHRZEUGE
Formular\fülleAusVT(#FAHRZEUGE, 0)
// Steuert die Master-Combobox an und übergibt den Hersteller
Ganzzahl modellID = #FAHRZEUGE\holeWert(0, "MODELL_ID")
XDEV Datenbankabfrage #MODELLE << MODELLE
Ganzzahl herstellerID = #MODELLE\holeWert(0, "HERSTELLER_ID")
ComboboxHersteller\datenAuswählen(herstellerID)
// Blockiert die Ausführung von ON_SELECTION_CHANGE bei der Master-Combobox
ComboboxHersteller\setzeZusätzlicheDaten("gesperrt")
|
Bei Änderung Auswahl ( )
Führt den Code bei der Änderung der Auswahl bei einer Table aus.
XDEV Datenbankabfrage #MODELLE << MODELLE
Datenbankabfrage. Selektiert die Datenfelder ID und MODELL und holt alle Datensätze der Datenbank-Tabelle MODELLE.
Abfragebedingung: keine.
ComboboxModelle\listenEinträge\fülleAusVirtuellerTabelle(#MODELLE,"MODELL","ID")
Füllt die Modell-Combobox mit den Daten aus der Virtuellen Tabelle #MODELLE. Die sichtbaren Combobox-Einträge werden aus dem Datenfeld MODELL ausgelesen, die jeweiligen IDs aus dem Datenfeld ID.
Ganzzahl zeile = Lokal\holeSelektierteZeile()
Legt eine Integer-Variable mit dem Namen zeile an und weist dieser den Index der selektierten Zeile in der Table zu.
Ganzzahl ID = #FAHRZEUGE_JOIN\holeWert(zeile, "ID")
Legt eine Ganzzahl-Variable mit dem Namen ID an und weist dieser die Fahrzeug-ID zu, die aus der Virtuellen Tabelle #FAHRZEUGE_JOIN in der Spalte ID und der Zeile zeile ausgelesen wird. In der Virtuellen Tabelle #FAHRZEUGE_JOIN befindet sich das Abfrageergebnis einer Datenbankabfrage über sämtliche Datenbank-Tabellen, die mit der Tabelle FAHRZEUGE verknüpft sind, um alle Fahrzeugdaten in der Table anzuzeigen.
XDEV Datenbankabfrage #FAHRZEUGE << FAHRZEUGE
Datenbankabfrage. Liefert alle Datensätze der Tabelle FAHRZEUGE mit der zuvor ermittelten Datensatz-ID ID.
Abfragebedingung: #FAHRZEUGE.ID = ID.
Formular\fülleAusVT(#FAHRZEUGE, 0
Füllt das Formular mit dem Datensatz mit dem Index 0 in der Virtuellen Tabelle #FAHRZEUGE.
Ganzzahl modellID = #FAHRZEUGE\holeWert(0, "MODELL_ID")
Legt eine Ganzzahl-Variable mit dem Namen modellID an und weist dieser die Modell-ID zu, die aus der Virtuellen Tabelle #FAHRZEUGE in der Zeile mit dem Index 0 und in der Spalte MODELL_ID ausgelesen wird.
XDEV Datenbankabfrage #MODELLE << MODELLE
Datenbankabfrage. Liefert alle Datensätze der Tabelle FAHRZEUGE mit der zuvor ermittelten Modell-ID modellID.
Abfragebedingung: #FAHRZEUGE.MODELL_ID = modellID.
Ganzzahl herstellerID = #MODELLE\holeWert(0, "HERSTELLER_ID")
Legt eine Ganzzahl-Variable mit dem Namen herstellerID an und weist dieser die Hersteller-ID zu, die aus der Virtuellen Tabelle #MODELLE in der Zeile mit dem Index 0 und in der Spalte HERSTELLER_ID ausgelesen wird.
ComboboxHersteller\datenAuswählen(herstellerID)
Selektiert in der Hersteller-Combobox den Wert mit der ID herstellerID.
ComboboxHerstellerl\setzeZusätzlicheDaten("gesperrt")
Speichert in den Zusatzdaten der Hersteller-Combobox den Wert gesperrt als Status-Flag.
ComboboxHersteller - Füllen der Detail-Combobox:
1
2
3
4
5
6
7
|
Bei Änderung Auswahl ( )
Wenn (Lokal\holeZusätzlicheDaten ()="")
Ganzzahl herstellerID = Lokal\holeSelektierteDaten()
XDEV Datenbankabfrage #MODELLE << MODELLE
ComboboxModelle\listenEinträge\fülleAusVirtuellerTabelle(#MODELLE, "MODELL", "ID")
Lokal\setzeZusätzlicheDaten("")
|
Bei Änderung Auswahl ( ))
Führt den Code bei bei einer Änderung der Auswahl in der Combobox aus.
Wenn (Lokal\holeZusätzlicheDaten ()="")
Prüft, ob die Zusatzdaten der Combobox leer sind. Der Wenn-Block, durch den die Modell-Combobox neu gefüllt wird, wird nur dann ausgeführt, wenn die Zusatzdaten leer sind. Der Wenn-Block wird nicht ausgeführt, wenn der Wert gesperrt in den Zusatzdaten steht.
Ganzzahl herstellerID = Lokal\holeSelektierteDaten()
Legt eine Ganzzahl-Variable mit dem Namen herstellerID an und weist dieser die ID des in der Combobox selektierten Eintrages zu.
XDEV Datenbankabfrage #MODELLE << MODELLE
Datenbankabfrage: Selektiert in der Datenbank-Tabelle MODELLE die Datenfelder ID und MODELL.
Abfragebedingung: #MODELLE.HERSTELLER_ID = herstellerID.
ComboboxModelle\listenEinträge\fülleAusVirtuellerTabelle(#MODELLE, "MODELL", "ID")
Füllt die Combobox mit den Daten aus der Virtuellen Tabelle #MODELLE. Die sichtbaren Combobox-Einträge werden aus dem Datenfeld MODELL ausgelesen, die jeweiligen IDs aus dem Datenfeld ID.
Lokal\setzeZusätzlicheDaten("")
Löscht die Zusatzdaten der Combobox. Dadurch wird bei der nächsten Änderung der Selektierung die Combobox wieder neu gefüllt.
|
|