Persistente Mehrfachauswahl mit Klasse

Wenn Sie Listenfelder für die Anzeige von Daten aus m:n-Beziehungen nutzen, müssen Sie die änderungen an der Auswahl jeweils in der zugrunde liegenden m:n-Verknüpfungstabelle speichern und diese beim Anzeigen eines Datensatzes wiederherstellen. Das ist kein Hexenwerk, wie der Beitrag Persistente Mehrfachauswahl in Listenfeldern (www.access-im-unternehmen.de/479) zeigt. Wenn Sie diese Technik häufiger verwenden, artet das Anlegen der entsprechenden Ereignisprozeduren jedoch in echte Arbeit aus. Warum also die Funktionalität nicht einfach in eine Klasse auslagern und diese wiederverwenden

Beispiel

Ein gutes Beispiel für einen solchen Fall ist das Formular frmMitarbeiterDetail aus der Lösung, die der Beitrag Schichtplaner (www.access-im-unternehmen.de/906) beschreibt. Dort finden Sie gleich zwei Listenfelder, welche die Daten aus m:n-Beziehungen darstellen. Dort sollen nämlich für einen Mitarbeiter sowohl die Schichten, für die er zur Verfügung steht, als auch die entsprechenden Wochentage markiert und natürlich auch gespeichert werden (s. Bild 1).

Formular mit zwei Listenfeldern zum Speichern von Daten aus m:n-Beziehungen

Bild 1: Formular mit zwei Listenfeldern zum Speichern von Daten aus m:n-Beziehungen

Wenn der Benutzer in diesem Formular zum nächsten Mitarbeiter wechselt, soll dieses natürlich auch gleich die richtigen Datensätze in den beiden Listenfeldern markieren. Und wenn der Benutzer einen der Listenfeldeinträge aus- oder abwählt, müssen natürlich die entsprechenden änderungen in den zugrunde liegenden Tabellen durchgeführt werden.

Woher kommen die Daten

Um das Beispiel zu verdeutlichen, schauen wir uns die Tabellen an, auf denen die einzelnen Elemente aufbauen.

Das Formular frmMitarbeiterDetail zeigt die Daten der Tabelle tblMitarbeiter an. Diese ist sehr einfach gehalten und enthält lediglich zwei Felder:

  • MitarbeiterID (Primärschlüsselfeld) und
  • Mitarbeiter (Bezeichnung des Mitarbeiters).

Das Listenfeld lstSchichtarten verwendet die Tabelle tblSchichtarten als Datensatzherkunft, wobei diese Tabelle über die Tabelle tblMitarbeiterSchichtarten mit der Tabelle tblMitarbeiter verknüpft wird (s. Bild 2).

Aufbau der an der m:n-Beziehung beteiligten Tabellen

Bild 2: Aufbau der an der m:n-Beziehung beteiligten Tabellen

Damit das Listenfeld zwar das Feld SchichtartID als gebundene Spalte verwendet, diese aber nicht anzeigt, stellen Sie die beiden Eigenschaften Spaltenanzahl und Spaltenbreite auf die Werte 2 und 0cm ein. Auf diese Weise erscheint nur die entsprechende Schichtart im Listenfeld.

Um die Mehrfachauswahl zu ermöglichen, stellen Sie außerdem die gleichnamige Eigenschaft auf den Wert Einfach ein (s. Bild 3).

Die Listenfelder bieten die Mehrfachauswahl für ihre Einträge an.

Bild 3: Die Listenfelder bieten die Mehrfachauswahl für ihre Einträge an.

Voraussetzung

Eine Voraussetzung hat die hier vorgestellte Version der Klasse: Die Namen der Primärschlüsselfelder der verknüpften Tabellen sowie der Fremdschlüsselfelder der Verknüpfungstabelle müssen übereinstimmen. Anderenfalls müssten Sie die Klasse entsprechend erweitern.

Benötigte Ereignisse

Was ist nun zu tun Als Erstes sollen beim Anzeigen eines Datensatzes im Hauptformular die diesem Datensatz zugeordneten Einträge der im Listenfeld angezeigten Tabelle markiert werden. Sprich: Die Einträge des Listenfeldes werden einzeln durchlaufen und mit den Daten der Verknüpfungstabelle tblMitarbeiterSchichtarten abgeglichen. Ist der aktuelle Eintrag über diese Tabelle mit dem im Formular angezeigten Mitarbeiter verknüpft, soll der Eintrag markiert werden.

Dies geschieht logischerweise, wenn das Ereignis Beim Anzeigen ausgelöst wird.

Außerdem soll bei einem Klick auf einen der Einträge eine änderung in der Tabelle tblMitarbeiterSchichtarten vorgenommen werden: Ist der Eintrag noch nicht markiert, soll der Tabelle ein Datensatz hinzugefügt werden, der im Feld MitarbeiterID den Wert des gleichnamigen Feldes im Formular und im Feld SchichtartID den Wert der gebundenen Spalte des angeklickten Eintrags des Listenfeldes aufnimmt.

Wenn der Eintrag beim Anklick bereits markiert war und somit deaktiviert wird, soll die Prozedur den Datensatz der Tabelle tblMitarbeiterSchichtarten suchen, der dem Wert des Feldes MitarbeiterID im Formular und dem Wert der gebundenen Spalte des angeklickten Eintrags im Listenfeld entspricht.

Und da wir schon von Anklicken reden, wissen wir auch, welches Ereignis gemeint ist: nämlich das Ereignis Beim Klicken.

Diese beiden Ereignisse müssten wir also in einer Klasse implementieren, die uns die wiederkehrende Programmierarbeit für das Speichern und Wiederherstellen der Mehrfachauswahl in Listenfeldern abnehmen soll.

Benutzung der Klasse

Die Klasse soll clsPersistenteMehrfachauswahl heißen, also deklarieren wir im Kopf des Klassenmoduls des Formulars mit den auszurüstenden Listenfeldern für jedes Listenfeld eine entsprechende Objektvariable.

In unserem Beispiel handelt es sich um die folgenden beiden Einträge:

Dim objPMSchichtarten As  clsPersistenteMehrfachauswahl
Dim objPMWochentage As  clsPersistenteMehrfachauswahl

Die Instanzierung der beiden Klassen erfolgt in der Prozedur, die durch das Ereignis Beim Laden des Formulars ausgelöst wird. Diese sieht wie in Listing 1 aus und führt die folgenden Schritte für die beiden Listenfelder durch:

Private Sub Form_Load()
     Set objPMSchichtarten = New clsPersistenteMehrfachauswahl
     With objPMSchichtarten
         Set .Form = Me
         Set .Listbox = Me!lstSchichtarten
         .mField = "MitarbeiterID"
         .nField = "SchichtartID"
         .mnTable = "tblMitarbeiterSchichtarten"
     End With
     Set objPMWochentage = New clsPersistenteMehrfachauswahl
     With objPMWochentage
         Set .Form = Me
         Set .Listbox = Me!lstWochentage
         .mField = "MitarbeiterID"
         .nField = "WochentagID"
         .mnTable = "tblMitarbeiterWochentage"
     End With
End Sub

Listing 1: Initialisieren der Klasse clsPersinstenteMehrfachauswahl für die beiden Listenfelder

  • Instanzieren eines Objekt auf Basis der Klasse mit dem Schlüsselwort New
  • Zuweisen des aktuellen Formulars an die Eigenschaft Form der Klasse
  • Zuweisen eines Verweises auf das Listenfeld an die Eigenschaft Listbox
  • Zuweisen des Namens des Primärschlüsselfeldes der Tabelle der m-Seite der Beziehung an die Eigenschaft mField
  • Zuweisen des entsprechenden Feldes der n-Seite der Beziehung an die Eigenschaft nField
  • Zuweisen des Namens der Verknüpfungstabelle an die Eigenschaft mnTable

Diese Schritte führt man für jedes mit der Klasse auszustattende Listenfeld aus.

Wenn Sie die Klasse clsPersistenteMehrfachauswahl einfach in Ihre Anwendung übernehmen, war es das – die Anzeige und das Speichern der ausgewählten Werte funktioniert nun bereits.

Die Klasse clsPersistenteMehrfachauswahl

Erstellen Sie im VBA-Editor zunächst ein neues Klassenmodul (Menüeintrag Einfügen|Klassenmodul).

Wie Sie der oben beschriebenen Anleitung entnehmen konnten, soll die Klasse nach dem Instanzieren gleich fünf Variablen entgegennehmen.

Dafür benötigen wir natürlich erstens fünf Member-Variablen, die nur innerhalb der Klasse verwendet werden und von außen zugewiesen werden sollen.

Bei der Variablen für die übergabe der Tabelle benötigen wir beispielsweise die folgende Deklaration:

Private m_mnTable As String

Damit man diese private deklarierte Variable nach dem Instanzieren von außen füllen kann, benötigen wir eine entsprechende Property Let-Prozedur.

Diese sieht wie folgt aus:

Public Property Let mnTable(str As String)
     m_mnTable = str
End Property

Die Prozedur liefert beim Zugriff auf ein Objekt auf Basis der Klasse von außen die Möglichkeit, die Variable m_mnTable wie folgt zu füllen:

objPMSchichtarten.mnTable =  "tblMitarbeiterSchichtarten"

Auf die gleiche Weise deklarieren wir die beiden Variablen zum Aufnehmen der betroffenen Tabellenfelder:

Private m_mField As String
Private m_nField As String

Die Property Let-Prozeduren sehen so aus:

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar