Mehrfachauswahl und Checkbox-Listen

Previous  Next

 

 

 

01.11.2009

Mehrfachauswahl und Checkbox-Listen

Für dieses Beispiel benötigen Sie die Beispiel-Datenbank FAHRZEUGE und das Projekt fahrzeuge.xdev

 

Mit einer gewöhnlichen Listbox lässt sich nur 1 Wert selektieren und speichern, z.B. ein Farbwert in einer Fahrzeug-Tabelle. Für manche Merkmale müssen jedoch mehrere Werte gespeichert werden, z.B. mehrere Extras für ein Fahrzeug wie Klima, Alu, Leder, Servo etc. Dafür lässt die Listbox auch eine Mehrfachauswahl zu, die Sie mit der Methode hmtoggle_plus1 setSelectionMode ( ) | XDEV NLS: setzeAuswahlModus ( ) ganz leicht aktivieren können. Alternativ können Sie die Listbox über die Eigenschaften bei CheckBox-Liste auch zu einer Checkbox-Liste machen.

 

» Werte der Mehrfachauswahl in neue Tabelle «

Die Auswirkung einer Listbox-Mehrfachauswahl oder einer Checkbox-Liste auf das Datenmodell sind jedoch gravierend, da in einem korrekten relationalen Datenmodell nicht mehrere Werte in einem Datenfeld gespeichert werden dürfen. Zum Beispiel darf in einem Fahrzeug-Datensatz in einem Datenfeld EXTRAS_ID nur 1 ID abgespeichert werden. Damit könnte ein Fahrzeug immer nur 1 Extra besitzen. In der Praxis kann ein Fahrzeug jedoch viele viele Extras besitzen.

 

Das Problem kann nur mit Hilfe einer zusätzlichen Datenbank-Tabelle gelöst werden. Das Prinzip ist jedoch simpel. Gespeichert wird immer ein ID-Paar bestehend aus einer Fahrzeug-ID und einer Extra-ID. Für jedes Extra wird jeweils ein ID-Paar abgespeichert, sodass die Fahrzeug-ID mehrfach vorkommen kann und somit redundant gespeichert wird. Im Gegensatz zu redundanten Werten sind redundante IDs unproblematisch. Der Name der Tabelle wird i.d.R. aus den Namen der zusammen geführten Tabellen gebildet, z.B. FAHRZEUGE_EXTRAS. Mit dem Speichern der Extras in der neuen Tabelle FAHRZEUGE_EXTRAS, wird das Datenfeld EXTRAS_ID in der Tabelle FAHRZEUGE überflüssig und kann aus der Tabelle entfernt werden.

 

» Zusätzliche Speichern-Funktion «

Das Speichern der Mehrfachauswahl in einer anderen Datenbank-Tabelle FAHRZEUGE_EXTRAS hat zur Folge, dass Sie dafür eine eigene Funktion zum Speichern benötigen. Dafür müssen Sie eine eigene Methode schreiben, welche die Fahrzeug-ID sowie die IDs aller gewählten Extras ermitteln und diese in der Datenbank-Tabelle FAHRZEUGE_EXTRAS abspeichern muss.

 

 

 

Listbox mit Mehrfachauswahl:

clip0478

 

 

Listbox als Checkbox-Liste:

clip0479

 

clip0477

Die Listbox unterstützt Mehrfachauswahl und lässt sich auch als Checkbox-Liste darstellen.

In einem Datenfeld lassen sich nur einzelne Werte oder IDs abspeichern, z.B. bei EXTRAS_ID. Das Speichern mehrerer Werte in einem Datenfeld ist zwar in Form einer Liste grundsätzlich möglich, widerspricht jedoch einem korrekten relationalen Datenmodell.

 

 

1.Fügen Sie eine Listbox auf die Arbeitsfläche ein (in diesem Fall müssen Sie die Listbox nicht zwingend in ein Formular einfügen).
2.Wechseln Sie in den Code-Editor und wählen Sie das Ereignis hmtoggle_plus1 ON_SHOW ( ) | XDEV NLS: Nach der Darstellung ( ) aus, klicken Sie die Listbox an, um alle Methoden der Listbox in der Bibliothek anzuzeigen, ziehen Sie die Methode hmtoggle_plus1 setSelectionMode ( ) | XDEV NLS: setzeAuswahlModus ( ) per Drag&Drop in den Code-Editor und wählen Sie im folgenden Parameter-Assistenten die Konstante hmtoggle_plus1 ON_SHOW ( ) | XDEV NLS: SELEKTION_MEHRERE_ABSCHNITTE ( ) aus und klicken Sie abschließend auf OK.

 

Datenbankabfrage:

 

3.Fügen Sie eine Datenbankabfrage hmtoggle_plus1 XDEV Query | XDEV NLS: XDEV Datenbankabfrage in den Code-Editor ein und klicken Sie diese an, um den SQL-Assistenten aufzurufen. Klicken Sie die Datenbank-Tabelle EXTRAS an, um alle Datenfelder dieser Tabelle zu selektieren. Übernehmen Sie die vom SQL-Assistenten automatisch angebotene Virtuelle Ziel-Tabelle #EXTRAS und klicken Sie auf OK, um den SQL-Assistenten zu schließen.

 

4.Klicken Sie die Listbox an, um alle Methoden der Listbox in der Bibliothek anzuzeigen. Scrollen Sie in der Bibliothek ganz nach unten, öffnen Sie den Zweig bei hmtoggle_plus1 XdevItemList listItems | XDEV NLS: XdevLeistEinträge listenEinträge und fügen Sie die Methode hmtoggle_plus1 fillFromVT ( ) | XDEV NLS: fülleAusVirtuellerTabelle ( ) per Drag&Drop in den Code-Editor ein. Legen Sie im folgenden Parameter-Dialog zuerst die Virtuelle Quell-Tabelle fest und wählen Sie dazu die Virtuelle Tabelle #EXTRAS aus.  Legen Sie in der zweiten Zeile das Datenfeld EXTRA fest, aus der die Listbox-Einträge ausgelesen werden sollen. Legen Sie schließlich in der dritten Zeile das Datenfeld ID fest, aus der die IDs der Listbox-Einträge ausgelesen

 

 

hmtoggle_plus1XDEV Object Language

Füllen der Listbox:

1

2

3

4

5

6

ON_SHOW ( )

{

  this.setSelectionMode (SELECTION_MULTIPLE_INTERVAL);

  XDEV Query #EXTRAS << EXTRAS

  this.listItems.fillFromVT(#EXTRAS, "EXTRAS", "ID")

}

this.setSelectionMode (SELECTION_MULTIPLE_INTERVAL);

Aktiviert die Mehrfachauswahl

 

XDEV Query #EXTRAS << EXTRAS

Mit einer Datenbankabfrage wird zuerst die Virtuelle Tabelle #EXTRAS mit allen Extras gefüllt.

 

this.listItems.fillFromVT(#EXTRAS, "EXTRAS", "ID")

Füllt die Listbox mit den Daten aus der Virtuellen Tabelle #EXTRAS.

 

 

Eigene Funktion save( ) zum Speichern der Listbox:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

save( )

{

  #FAHRZEUGE_EXTRAS.clear();

 

  Int fahrzeug_ID = Formular.getTagData();

  Int extra_ID;

  XdevList liste = Listbox.getSelectedIndices();

 

  for (Int zeile; zeile < liste.size(); zeile = zeile + 1 )

  {

    extra_ID = Listbox.listItems.getData(liste.get(zeile));

 

    #FAHRZEUGE_EXTRAS.addRow();

    #FAHRZEUGE_EXTRAS.setValueAt(zeile, "FAHRZEUGE_ID", fahrzeug_ID);

    #FAHRZEUGE_EXTRAS.setValueAt(zeile, "EXTRAS_ID", extra_ID);

  }

  XDEV DeleteDB FAHRZEUGE_EXTRAS;

  #FAHRZEUGE_EXTRAS.synchronizeChangedRows();

}

save( )

Die Methode save( ) wird bei der Listbox hinterlegt und kann z.B. beim Formular-Speichern-Button mit Listbox.save( ); aufgerufen werden.

 

#FAHRZEUGE_EXTRAS.clear( );

Löscht die Virtuelle Tabelle #FAHRZEUGE_EXTRAS, da diese noch Werte enthalten könnte.

 

Int fahrzeug_ID = Formular.getTagData( );

Die Fahrzeug-ID wird aus den Formular-Zusatzdaten ausgelesen, da jedes Extra immer zusammen mit einer Fahrzeug-ID gespeichert wird. Vor dem Aufruf der Methode save( ) muss die Fahrzeug-ID in den Formular-Zusatzdaten hinterlegt werden. Die Fahrzeug-ID kann jedoch auch auf eine andere Weise übergeben werden.

 

Int extra_ID;

Definiert die Integer-Variable extra_ID.

 

XdevList liste = Listbox.getSelectedIndices();

Definiert eine neue Liste mit dem Namen liste und weist dieser die Indizes aller selektierten Einträge in der Listbox zu.

Mehrere Listen-Einträge können nur mit der Methode getSelectedIndices( ) gleichzeitig ausgelesen werden.

 

for (Int zeile; zeile < liste.size( ); zeile = zeile+1)

Die Schleife wird so oft wiederholt wie sich Einträge in der Liste liste befinden. Die Anzahl der Einträge in einer Liste lässt sich mit der Methode size( ) ermitteln.

 

extra_ID = Listbox.listItems.getData(liste.get(zeile));

Liest die Extra-ID mit Hilfe der Methode getData( ) aus der Listbox-Liste aus. Dazu muss der Index der Zeile angegeben werden, der von get(zeile) ermittelt wird.

 

#FAHRZEUGE_EXTRAS.addRow( );

Fügt eine neue, leere Zeile in die Virtuelle Tabelle #FAHRZEUGE_EXTRAS ein.

 

#FAHRZEUGE_EXTRAS.setValueAt(zeile, "FAHRZEUGE_ID", fahrzeug_ID);

Speichert die Fahrzeug-ID im Datenfeld FAHRZEUG_ID.

 

#FAHRZEUGE_EXTRAS.setValueAt(zeile, "EXTRAS_ID", extra_ID);

Ermittelt die ID des aktuellen Listbox-Eintrages, und speichert diese im Datenfeld EXTRAS_ID ab.

 

XDEV DeleteDB FAHRZEUGE_EXTRAS;

Löscht alle ID-Paare mit der aktuellen Fahrzeug-ID, um mehrfaches Speichern von ID-Paaren mit der aktuellen Fahrzeug-ID zu verhindern.

 

#FAHRZEUGE_EXTRAS.synchronizeChangedRows( );

Synchronisiert die Virtuelle Tabelle #FAHRZEUGE_EXTRAS mit der entsprechenden Datenbank-Tabelle und speichert so alle ID-Paare ab.

 

 

Füllen der Listbox mit Setzen der Mehrfach-Selektierung:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

ON_SHOW ( )

{

  this.setSelectionMode (SELECTION_MULTIPLE_INTERVAL);

  XDEV Query #EXTRAS << EXTRAS

  this.listItems.fillFromVT(#EXTRAS, "EXTRAS", "ID")

 

  Int index

  Int data

  XdevList liste = createList() 

  Int zeilen = #FAHRZEUGE_EXTRAS_JOIN.getRowCount()

 

  for (Int i; i<zeilen; i = i+1)

  {

     data = #FAHRZEUGE_EXTRAS_JOIN.getValueAt(i, "EXTRAS_ID")

     index = Listbox.listItems.indexOfData(data)

     liste.add(index)

  }

  Listbox.setSelectedIndices(liste)

 

}

this.setSelectionMode (SELECTION_MULTIPLE_INTERVAL);

Aktiviert die Mehrfachauswahl

 

XDEV Query #EXTRAS << EXTRAS

Mit einer Datenbankabfrage wird zuerst die Virtuelle Tabelle #EXTRAS mit allen Extras gefüllt.

 

this.listItems.fillFromVT(#EXTRAS, "EXTRAS", "ID")

Füllt die Listbox mit den Daten aus der Virtuellen Tabelle #EXTRAS.

hmtoggle_plus1XDEV Basic

Füllen der Listbox:

1

2

3

4

ON_SHOW ( )

  This.setSelectionMode (SELECTION_MULTIPLE_INTERVAL)

  XDEV Query #EXTRAS << EXTRAS

  This.listItems.fillFromVT(#EXTRAS, "EXTRAS", "ID")

This.setSelectionMode (SELECTION_MULTIPLE_INTERVAL)

Aktiviert die Mehrfachauswahl

 

XDEV Query #EXTRAS << EXTRAS

Mit einer Datenbankabfrage wird zuerst die Virtuelle Tabelle #EXTRAS mit allen Extras gefüllt.

 

This.listItems.fillFromVT(#EXTRAS, "EXTRAS", "ID")

Füllt die Listbox mit den Daten aus der Virtuellen Tabelle #EXTRAS.

 

 

Eigene Funktion save( ) zum Speichern der Listbox:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

save( )

  #FAHRZEUGE_EXTRAS.clear()

 

  Int fahrzeug_ID = Formular.getTagData()

  Int extra_ID

  XdevList liste = Listbox.getSelectedIndices()

 

  XFor Int zeile, zeile < liste.size( ), zeile = zeile + 1

      extra_ID = Listbox.listItems.getData(liste.get(zeile))

    

      #FAHRZEUGE_EXTRAS.addRow()

      #FAHRZEUGE_EXTRAS.setValueAt(zeile, "FAHRZEUGE_ID", fahrzeug_ID)

      #FAHRZEUGE_EXTRAS.setValueAt(zeile, "EXTRAS_ID", extra_ID)

  Next

 

  XDEV DeleteDB FAHRZEUGE_EXTRAS

  #FAHRZEUGE_EXTRAS.synchronizeChangedRows()

save( )

Die Methode save( ) wird bei der Listbox hinterlegt und kann z.B. beim Formular-Speichern-Button mit Listbox.save( ); aufgerufen werden.

 

#FAHRZEUGE_EXTRAS.clear( )

Löscht die Virtuelle Tabelle #FAHRZEUGE_EXTRAS, da diese noch Werte enthalten könnte.

 

Int fahrzeug_ID = Formular.getTagData( )

Die Fahrzeug-ID wird aus den Formular-Zusatzdaten ausgelesen, da jedes Extra immer zusammen mit einer Fahrzeug-ID gespeichert wird. Vor dem Aufruf der Methode save( ) muss die Fahrzeug-ID in den Formular-Zusatzdaten hinterlegt werden. Die Fahrzeug-ID kann jedoch auch auf eine andere Weise übergeben werden.

 

Int extra_ID

Definiert die Integer-Variable extra_ID.

 

XdevList liste = Listbox.getSelectedIndices()

Definiert eine neue Liste mit dem Namen liste und weist dieser die Indizes aller selektierten Einträge in der Listbox zu.

Mehrere Listen-Einträge können nur mit der Methode getSelectedIndices( ) gleichzeitig ausgelesen werden.

 

XFor Int zeile, zeile < liste.size( ), zeile = zeile+1

Die Schleife wird so oft wiederholt wie sich Einträge in der Liste liste befinden. Die Anzahl der Einträge in einer Liste lässt sich mit der Methode size( ) ermitteln.

 

extra_ID = Listbox.listItems.getData(liste.get(zeile))

Liest die Extra-ID mit Hilfe der Methode getData( ) aus der Listbox-Liste aus. Dazu muss der Index der Zeile angegeben werden, der von get(zeile) ermittelt wird.

 

#FAHRZEUGE_EXTRAS.addRow( )

Fügt eine neue, leere Zeile in die Virtuelle Tabelle #FAHRZEUGE_EXTRAS ein.

 

#FAHRZEUGE_EXTRAS.setValueAt(zeile, "FAHRZEUGE_ID", fahrzeug_ID)

Speichert die Fahrzeug-ID im Datenfeld FAHRZEUG_ID.

 

#FAHRZEUGE_EXTRAS.setValueAt(zeile, "EXTRAS_ID", extra_ID)

Ermittelt die ID des aktuellen Listbox-Eintrages, und speichert diese im Datenfeld EXTRAS_ID ab.

 

XDEV DeleteDB FAHRZEUGE_EXTRAS

Löscht alle ID-Paare mit der aktuellen Fahrzeug-ID, um mehrfaches Speichern von ID-Paaren mit der aktuellen Fahrzeug-ID zu verhindern.

 

#FAHRZEUGE_EXTRAS.synchronizeChangedRows( )

Synchronisiert die Virtuelle Tabelle #FAHRZEUGE_EXTRAS mit der entsprechenden Datenbank-Tabelle und speichert so alle ID-Paare ab.

 

 

Füllen der Listbox mit Setzen der Mehrfach-Selektierung:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

ON_SHOW ( )

{

  this.setSelectionMode (SELECTION_MULTIPLE_INTERVAL);

  XDEV Query #EXTRAS << EXTRAS

  this.listItems.fillFromVT(#EXTRAS, "EXTRAS", "ID")

 

  Int index

  Int data

  XdevList liste = createList() 

  Int zeilen = #FAHRZEUGE_EXTRAS_JOIN.getRowCount()

 

  Xfor Int i; i<zeilen; i = i+1

     data = #FAHRZEUGE_EXTRAS_JOIN.getValueAt(i, "EXTRAS_ID")

     index = Listbox.listItems.indexOfData(data)

     liste.add(index)

  Next

  this.setSelectedIndices(liste)

this.setSelectionMode (SELECTION_MULTIPLE_INTERVAL);

Aktiviert die Mehrfachauswahl

 

XDEV Query #EXTRAS << EXTRAS

Mit einer Datenbankabfrage wird zuerst die Virtuelle Tabelle #EXTRAS mit allen Extras gefüllt.

 

this.listItems.fillFromVT(#EXTRAS, "EXTRAS", "ID")

Füllt die Listbox mit den Daten aus der Virtuellen Tabelle #EXTRAS.

hmtoggle_plus1XDEV NLS

Füllen der linken Listbox:

1

2

3

4

Nach der Darstellung ( )

  Lokal\setzeAuswahlModus (SELEKTION_MEHRERE_ABSCHNITTE)

  XDEV Datenbankabfrage #EXTRAS << EXTRAS

  Lokal\listenEinträge\fülleAusVirtuellerTabelle(#EXTRAS, "EXTRAS", "ID")

Lokal\setzeAuswahlModus (SELEKTION_MEHRERE_ABSCHNITTE)

Aktiviert die Mehrfachauswahl

 

XDEV Datenbankabfrage #EXTRAS << EXTRAS

Mit einer Datenbankabfrage wird zuerst die Virtuelle Tabelle #EXTRAS mit allen Extras gefüllt.

 

Lokal\listenEinträge\fülleAusVirtuellerTabelle(#EXTRAS, "EXTRAS", "ID")

Füllt die Listbox mit den Daten aus der Virtuellen Tabelle #EXTRAS.

 

 

Eigene Funktion speichern( ) zum Speichern der Listbox:

1

2

3

4

5

6

7

8

9

10

11

12

13

speichern( )

  #FAHRZEUGE_EXTRAS\löscheAlles()

 

  Ganzzahl fahrzeug_ID = Formular\holeZusätzlicheDaten()

  Ganzzahl extra_ID

  XdevListe liste = Listbox\selektierteZeilen()

 

  Zählerschleife (Ganzzahl zeile | zeile< liste\größe | zeile = zeile+1)

      extra_ID = Listbox\listenEinträge\holeWert(liste\hole(zeile))

 

      #FAHRZEUGE_EXTRAS\fügeZeileHinzu()

      #FAHRZEUGE_EXTRAS\setzeWert(zeile, "FAHRZEUGE_ID", fahrzeug_ID)

      #FAHRZEUGE_EXTRAS\setzeWert(zeile, "EXTRAS_ID", extra_ID)

 

  XDEV AusDatenbankLöschen FAHRZEUGE_EXTRAS

  #FAHRZEUGE_EXTRAS\synchronisiereGeänderteZeilen()

speichern( )

Die Methode speichern( ) wird bei der Listbox hinterlegt und kann z.B. beim Formular-Speichern-Button mit Listbox.speichern( ) aufgerufen werden.

 

#FAHRZEUGE_EXTRAS\löscheAlles( )

Löscht die Virtuelle Tabelle #FAHRZEUGE_EXTRAS, da diese noch Werte enthalten könnte.

 

Ganzzahl fahrzeug_ID = Formular\holeZusätzlicheDaten()

Die Fahrzeug-ID wird aus den Formular-Zusatzdaten ausgelesen, da jedes Extra immer zusammen mit einer Fahrzeug-ID gespeichert wird. Vor dem Aufruf der Methode speichern( ) muss die Fahrzeug-ID in den Formular-Zusatzdaten hinterlegt werden. Die Fahrzeug-ID kann jedoch auch auf eine andere Weise übergeben werden.

 

Ganzzahl extra_ID

Definiert die Ganzzahl-Variable extra_ID.

 

XdevList liste = Listbox\selektierteZeilen()

Definiert eine neue Liste mit dem Namen liste und weist dieser die Indizes aller selektierten Einträge in der Listbox zu.

Mehrere Listen-Einträge können nur mit der Methode selektierteZeilen( ) gleichzeitig ausgelesen werden.

 

Zählerschleife (Ganzzahl zeile | zeile < liste\größe | zeile = zeile+1)

Die Schleife wird so oft wiederholt wie sich Einträge in der Liste liste befinden. Die Anzahl der Einträge in einer Liste lässt sich mit der Methode größe( ) ermitteln.

 

extra_ID = Listbox\listenEinträge\holeWert(liste\hole(zeile))

Liest die Extra-ID mit Hilfe der Methode holeWert( ) aus der Listbox-Liste aus. Dazu muss der Index der Zeile angegeben werden, der von hole(zeile) ermittelt wird.

 

#FAHRZEUGE_EXTRAS\fügeZeileHinzu()

Fügt eine neue, leere Zeile in die Virtuelle Tabelle #FAHRZEUGE_EXTRAS ein.

 

#FAHRZEUGE_EXTRAS\setzeWert(zeile, "FAHRZEUGE_ID", fahrzeug_ID)

Speichert die Fahrzeug-ID im Datenfeld FAHRZEUG_ID.

 

#FAHRZEUGE_EXTRAS\setzeWert(zeile, "EXTRAS_ID", extra_ID)

Ermittelt die ID des aktuellen Listbox-Eintrages, und speichert diese im Datenfeld EXTRAS_ID ab.

 

XDEV AusDatenbankLöschen FAHRZEUGE_EXTRAS

Löscht alle ID-Paare mit der aktuellen Fahrzeug-ID, um mehrfaches Speichern von ID-Paaren mit der aktuellen Fahrzeug-ID zu verhindern.

 

#FAHRZEUGE_EXTRAS\synchronisiereGeänderteZeilen()

Synchronisiert die Virtuelle Tabelle #FAHRZEUGE_EXTRAS mit der entsprechenden Datenbank-Tabelle und speichert so alle ID-Paare ab.

 

 

Füllen der Listbox mit Setzen der Mehrfach-Selektierung:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

ON_SHOW ( )

{

  this.setSelectionMode (SELECTION_MULTIPLE_INTERVAL);

  XDEV Query #EXTRAS << EXTRAS

  this.listItems.fillFromVT(#EXTRAS, "EXTRAS", "ID")

 

  Ganzzahl index

  Ganzzahl data

  XdevListe liste = erzeugeListe() 

  Ganzzahl zeilen = #FAHRZEUGE_EXTRAS\anzahlZeilen()

 

  Zählerschleife (Ganzzahl i | i<zeilen | i = i+1)

     data = #FAHRZEUGE_EXTRAS\holeWert(i, "EXTRAS_ID")

     index = Listbox\listenEinträge\indexVonWert(data)

     liste\hinzufügen(index)

  Lokal\zeilenAuswählen(liste)

this.setSelectionMode (SELECTION_MULTIPLE_INTERVAL);

Aktiviert die Mehrfachauswahl

 

XDEV Query #EXTRAS << EXTRAS

Mit einer Datenbankabfrage wird zuerst die Virtuelle Tabelle #EXTRAS mit allen Extras gefüllt.

 

this.listItems.fillFromVT(#EXTRAS, "EXTRAS", "ID")

Füllt die Listbox mit den Daten aus der Virtuellen Tabelle #EXTRAS.