Home > Artikel > Ausgabe 4/2012 > Listenfeldauswahl speichern und wiederherstellen

Listenfeldauswahl speichern und wiederherstellen

Achtung: Sie sind nicht angemeldet. Wenn Sie Abonnent sind und sich anmelden, lesen Sie den kompletten Artikel, laden das PDF herunter oder probieren die Beispieldatenbank aus (sofern vorhanden).

Wie Sie die durch einen Benutzer ausgewählten Einträgen im Listenfeld auslesen, haben Sie bereits im Artikel "Mehrfachauswahl in Listenfeldern auslesen" erfahren. In diesem Folgeartikel geht es darum, eine solche Auswahl auf Basis der in einer Tabelle gespeicherten Daten wieder herzustellen. Dazu müssen wir diese Auswahl jedoch erst einmal speichern – und später kümmern wir uns um die Reproduktion

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1204_Mehrfachauswahl.mdb.

Listenfeldauswahl ganz einfach

Normalerweise können Sie Listenfelder, genau wie Kombinationsfelder, mit einer Datensatzherkunft versehen (also etwa mit einer Tabelle oder Abfrage, welche die Daten liefert) und das Steuerelement über die Eigenschaft Steuerelementinhalt an ein Feld einer weiteren Tabelle binden.

Ein Beispiel ist die Auswahl einer Anrede für einen Kunden. Normalerweise verwenden Sie hier ein Kombinationsfeld, aber Sie können dies – ausreichend Platz vorausgesetzt – auch mit einem Listenfeld erledigen. Der Vorteil ist, dass man alle zur Auswahl stehenden Einträge direkt sehen kann – zumindest, wenn es nicht mehr Einträge gibt, als das Listenfeld im sichtbaren Bereich anzeigen kann (siehe Bild 1). Das Listenfeld ist mit der Tabelle tblAnreden als Datensatzherkunft ausgestattet und es ist an das Feld AnredeID der im Formular angezeigten Tabelle tblKunden gebunden. Damit das Listenfeld nur die Anrede, nicht aber die Werte des Feldes AnredeID anzeigt, stellen Sie die Eigenschaften Spaltenanzahl und Spaltenbreite auf die Werte 2 und 0cm ein. So wird das erste Feld mit der AnredeID ausgeblendet. Dieses muss aber dennoch als gebundene Spalte vorliegen: Access sucht nämlich in der Tabelle tblAnreden nach dem Datensatz, dessen als gebundene Spalte angegebenes Feld den gleichen Wert enthält wie das in der Eigenschaft Steuerelementinhalt angegebene Feld, also das Feld AnredeID der Tabelle tblKunden.

Lookup-Daten per Listenfeld auswählen

Bild 1: Lookup-Daten per Listenfeld auswählen

Damit haben Sie gleich zwei Fliegen mit einer Klappe geschlagen: Erstens wird die Auswahl so automatisch gespeichert und zweitens wird sie beim Anzeigen eines Datensatzes auch gleich wieder hergestellt.

Mehrfachauswahl speichern

Schauen wir uns nun an, wie sich dies für die Mehrfachauswahl realisieren lässt. Wenn Sie dies mit der Mehrfachauswahl durchführen, ist der Aufwand schon erheblich höher.

Als Beispiel verwenden wir das Zuweisen von Publikationen zu Kunden, als eine Art Verteilerliste. Dazu benötigen wir drei Tabellen: erstens eine Tabelle tblKunden zum Speichern der Kundendaten, zweitens die Tabelle tblPublikationen und noch eine dritte Tabelle, mit der wir die Publikationen den Kunden zuweisen. Damit realisieren wir eine m:n-Beziehung zwischen den Tabellen tblKunden und tblPublikationen. Dies bedeutet, dass wir über die dritte Tabelle, die wir schlicht tblVerteiler nennen, jede Publikation jedem Kunden zuordnen können. Das Datenmodell sieht wie in Bild 2 aus. Dabei enthält die Tabelle tblVerteiler zwei Fremdschlüsselfelder, mit denen Sie je Datensatz einen Eintrag der Tabelle tblKunden und einen Eintrag der Tabelle tblPublikationen auswählen können. Damit kein Kunde eine Publikation doppelt erhält, haben wir außerdem einen eindeutigen Index für die beiden Felder PublikationID und KundeID festgelegt (siehe Bild 3).

Eindeutiger Index für die Kombination aus Kunde und Publikation

Bild 2: Eindeutiger Index für die Kombination aus Kunde und Publikation

Datenmodell für den Publikationsverteiler

Bild 3: Datenmodell für den Publikationsverteiler

Formular zur Auswahl von Publikationen

Mit diesen Tabellen ausgestattet können wir uns an den Entwurf des Formulars zur Auswahl der Publikationen je Benutzer begeben. Das Formular soll frmVerteiler heißen und verwendet die Tabelle tblKunden als Datenherkunft. Ziehen Sie die notwendigsten Felder der Tabelle tblKunden in den Detailbereich und fügen Sie dem Formular ein Listenfeld namens lstPublikationen hinzu. Das sind vorerst alle notwendigen Steuerelemente, das Formular sollte nun so aussehen wie in Bild 4.

Entwurf des Formulars zum Festlegen der Verteilerlisten

Bild 4: Entwurf des Formulars zum Festlegen der Verteilerlisten

Nun kümmern wir uns um die im Listenfeld angezeigten Daten. Eigentlich soll das Listenfeld nur die Liste aller Publikationen anzeigen. Aber wir benötigen doch noch Informationen darüber, ob eine Publikation über die Tabelle tblVerteiler einem Kunden zugewiesen wurde? Das stimmt prinzipiell. Allerdings benötigen wir diese Information nur zum Markieren der zugeteilten Publikationen. Es werden jedoch immer alle Publikationen angezeigt – wir brauchen das Listenfeld lstPublikationen also einfach nur mit der Tabelle tblPublikationen als Datensatzherkunft zu versehen. Markieren Sie also das Listenfeld im Formularentwurf und stellen Sie die Eigenschaft Datensatzherkunft entsprechend ein. Außerdem soll nur die Publikation, nicht aber die Publikation­ID erscheinen. Dies erreichen wir durch Setzen der Eigenschaften Spaltenanzahl und Spaltenbreiten auf die Werte 2 und 0cm. Stellen Sie außerdem die Eigenschaft Mehrfachauswahl auf Einfach ein (oder Erweitert – je nach Anforderung). Das Formular bietet bereits jetzt die Möglichkeit, eine oder mehrere Publikationen je Kunde auszuwählen – allerdings werden diese weder gespeichert noch ändert sich die Auswahl beim Anzeigen des nächsten Kunden (siehe Bild 5).

Das Formular zum Festlegen von Verteilerlisten in der Formularansicht

Bild 5: Das Formular zum Festlegen von Verteilerlisten in der Formularansicht

Auswahl speichern

Nun wird es interessant: Die Auswahl soll nun gespeichert und beim Anzeigen eines Kunden wieder hergestellt werden. Zum Speichern gibt es grundsätzlich zwei Möglichkeiten:

  • Alle ausgewählten Publikationen eines Kunden werden beim Wechseln des Datensatzes beziehungsweise beim Schließen des Formulars gespeichert.
  • Jede Publikation wird gleich beim Auswählen gespeichert.

Die erste Variante setzt voraus, dass der Datensatz auch geändert wurde, denn die beiden Ereignisse Vor Aktualisierung und Nach Aktualisierung eines Datensatzes werden nur ausgelöst, wenn eine Änderung durchgeführt und der Datensatz somit geändert wurde. Wenn Sie jedoch Änderungen einem Listenfeld durchführen, dass nicht an ein Feld der Datenherkunft des Formulars gebunden ist, wird auch der aktuell angezeigte Datensatz der an das Formular gebundenen Datenherkunft nicht geändert.

Also nehmen wir vorerst mit der zweiten Variante vorlieb. Hier gibt es beim Aus- oder Abwählen mehr als ein Ereignis, zum Beispiel Beim Klicken, Vor Aktualisierung und Nach Aktualisierung. Grundsätzlich spielt es keine Rolle, welches Ereignis Sie hier verwenden – alle greifen auf die bereits markierten Einträge des Listenfeldes zu. Allerdings gibt es einen Nachteil: Das Listenfeld bietet keine Eigenschaft, mit der Sie im Mehrfachauswahl-Modus den Eintrag ermitteln können, auf den der Benutzer zuletzt geklickt hat. Dementsprechend wissen Sie auch nicht, ob der entsprechende Eintrag aus- oder abgewählt wurde. Fazit: Wir müssen jeweils alle Einträge untersuchen und mit dem aktuell in der Tabelle tblVerteiler gespeicherten Stand abgleichen. Da geht es vermutlich schneller, die bisherige Auswahl zu löschen und die aktuell ausgewählten Einträge wieder zur Tabelle tblVerteiler hinzuzufügen.

Und das sollen wir für jeden Mausklick des Benutzers auf einen der Einträge erledigen? Nein, es gibt noch eine Alternative, die sich auf die beiden Ereignisse Vor Aktualisierung und Nach Aktualisierung des Formulars bezieht. Zwar setzen diese voraus, dass Sie eine Änderung am Datensatz der Tabelle tblKunden im Formular vorgenommen haben. Dies müssen Sie jedoch nicht selbst erledigen: Wir können auch dafür sorgen, dass der Datensatz nur als bearbeitet markiert wird – und das erledigen wir beim Anklicken eines der Einträge des Listenfeldes. Die dazu notwenige Ereignisprozedur hinterlegen Sie für das Ereignis Beim Klicken des Listenfeldes. Wählen Sie den Wert [Ereignisprozedur] für dieses Feld aus und ergänzen Sie die nun im VBA-Editor erscheinende Prozedur um die folgenden Zeilen:

Private Sub lstPublikationen_Click()

     Me.Painting = False

     Me!Vorname.SetFocus

     Me.Dirty = True

     Me!lstPublikationen.SetFocus

     Me.Painting = True

End Sub

Diese Prozedur soll eigentlich nur den aktuellen Datensatz "schmutzig" machen, also dafür sorgen, dass dieser als bearbeitet markiert wird. Normalerweise reicht dazu das Einstellen der Eigenschaft Dirty auf den Wert True aus. Leider ist die Voraussetzung dafür, dass sich der Fokus auf einem der gebundenen Felder des Formulars befindet. Kein Problem: Verschieben wir also den Fokus auf das Feld Vorname, stellen Me.Dirty auf True ein und setzen den Fokus dann wieder auf das Listenfeld. Nun flackert dies noch ein wenig, was wir durch vorheriges Deaktivieren der Aktualisierung des Formulars verhindern. Dazu stellen wir die Eigenschaft Painting des Formulars auf False ein. Nach dem Zurücksetzen des Fokus auf das Listenfeldes wird die Aktualisierung wieder aktiviert.

Was haben wir damit erreicht? Nun: Dadurch, dass der Datensatz nun als bearbeitet gekennzeichnet ist, werden beim Wechseln des Datensatzes oder beim Schließen des Formulars die beiden Ereignisse Vor Aktualisierung und Nach Aktualisierung ausgelöst.

Markierte Publikationen speichern

Wir nutzen das Ereignis Nach Aktualisierung, um alle bislang für den aktuellen Kunden gespeicherten Publikationen zu löschen und die aktuell markierten zur Liste in der Tabelle tblVerteiler hinzuzufügen. Der Grund, warum wir das Ereignis Nach Aktualisierung und nicht Vor Aktualisierung wählen, ist folgender: Zum Zeitpunkt des Ereignisses Vor Aktualisierung ist der Datensatz noch nicht gespeichert. Dann kann es passieren, dass ein neuer Kunde angelegt und gleich Publikationen für diesen ausgewählt wurden.

Der neue Kunde hat aber zu diesem Zeitpunkt noch keinen in der Tabelle gespeicherten Datensatz, also ist noch kein Wert für das Feld KundeID vorhanden. Dies löst einen Fehler aus, wenn Sie einen Datensatz in der Tabelle tblVerteiler anlegen möchten, der sich auf einen nicht vorhandenen Kundendatensatz bezieht. Also wählen wir das Ereignis Nach Aktualisierung, bei dessen Auslösen der Datensatz bereits gespeichert ist.

Die Prozedur sieht wie in Listing 1 aus. Die Prozedur zählt zunächst mit der Count-Eigenschaft die ausgewählten Einträge im Listenfeld.

Private Sub Form_AfterUpdate()

     Dim db As DAO.Database

     Dim i As Integer

     Dim intCount As Integer

     Dim intIndex As Integer

     Dim intPublikationID As Long

     Set db = CurrentDb

     intCount = Me!lstPublikationen.ItemsSelected.Count

     db.Execute "DELETE FROM tblVerteiler WHERE KundeID = " & Me!KundeID, dbFailOnError

     For i = 0 To intCount - 1

Sie haben das Ende des frei verfügbaren Teil dieses Artikels erreicht!

Wenn Sie mehr lesen und auf viele weitere Artikel zugreifen möchten, melden Sie sich als Abonnent unter Login an. Falls nicht, bestellen Sie doch einfach ein Jahresabonnement!