Combobox Master-Detail in Formularen

Previous  Next

 

 

 

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.

 

clip0500

clip0501


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.

 

clip0500

clip0502

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 hmtoggle_plus1 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.

 

 

hmtoggle_plus1XDEV Object Language

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.

hmtoggle_plus1XDEV Basic

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.

hmtoggle_plus1XDEV NLS

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.