Das Thema Adressverwaltung kann man auf viele verschiedene Arten lösen. In vielen Fällen reicht eine einfache Tabelle, die eine Adresse speichert. Reden wir über Adressen in einer Kundenverwaltung, kann es auch vorkommen, dass der Kunde unterschiedliche Adressen für Lieferungen und Rechnungen angeben möchte. Solche Daten speichert man entweder in einer einzigen Tabelle je Kunde oder man trägt die Liefer- und Rechnungsadresse in eigene Tabellen ein, die man dann per 1:1-Beziehung mit dem Kundendatensatz verknüpft. Wir gehen noch einen Schritt weiter und wollen mit der hier vorgestellten Lösung die Möglichkeit bieten, nicht nur zwei, sondern beliebig viele Adressen je Kunde anzulegen – die dann flexibel als Rechnung- oder Lieferadresse festgelegt werden können.
Eigentlich ist es kein Problem, die Adressdaten eines Kunden oder einer Person in einem Datensatz einer Tabelle zu speichern. Sie legen dann Felder für ein oder zwei Adressen an, hier Liefer- und Rechnungsadresse, und speichern den Datensatz. Aus dieser Tabelle können Sie dann ganz einfach die Lieferadresse und die Rechnungsadresse entnehmen.
Nachteile herkömmlicher Kundentabellen
Aber was, wenn der Kunde vorübergehend unter einer anderen Lieferadresse erreichbar ist Oder wenn er eine Rechnung zwischenzeitlich an seinen Arbeitgeber schicken lassen will, statt zu sich nach Hause
Dann müssen Sie entweder zur klassischen Methode greifen und die Rechnung oder das Paket von Hand beschriften oder Sie ändern die Rechnungs- oder Lieferadresse vorübergehend, um diese anschließend wieder in den alten Zustand zu versetzen. Aber wie stellen Sie sicher, dass Sie dann nicht vergessen, die vorübergehende Adresse wieder herauszulöschen Und wo speichern Sie in der Zwischenzeit die üblicherweise zu verwendende Adresse
Solche Fragen stellen sich auch, wenn Sie mit der hier vorgestellten Lösung arbeiten, aber sie macht das Leben deutlich einfacher.
Datenmodell für flexible Adressen
Im Datenmodell für unsere Lösung finden wir zunächst die übliche Tabelle etwa namens tblKunden. Diese enthält einige Basisdaten wie etwa die Anrede, den Vor- und den Nachnamen des Kunden sowie das Geburtsdatum. Wir haben beispielsweise auch noch die E-Mail-Adresse und die Telefonnummer des Kunden erfasst. Sie können nach Bedarf noch weitere organisatorische Daten erfassen, wie etwa das Datum, an dem der Kundendatensatz erstellt wurde.
Diese Tabelle sieht vorerst wie in Bild 1 aus. Das Feld AnredeID ist ein Fremdschlüsselfeld zur Tabelle tblAnreden, welche wir hier nicht abbilden. Diese Tabelle besteht lediglich aus den Feldern ID und Anrede.
Bild 1: Entwurf der Tabelle tblKunden
Die neue Tabelle zum Speichern von Liefer- und Rechnungsadressen heißt schlicht tblAdressen. Sie sieht im Entwurf wie in Bild 2 aus. Sie enthält nochmals die Felder AnredeID, Vorname und Nachname – das deshalb, weil ja auch einmal eine ganz andere Person eine Lieferung oder eine Rechnung erhalten können soll. Außerdem finden Sie hier die üblichen Felder zum Erfassen einer Adresse wie Firma, Strasse, PLZ, Ort und Land.
Bild 2: Entwurf der Tabelle tblAdresse
Interessant wird es beim Feld KundeID. Dabei handelt es sich um ein Fremdschlüsselfeld, mit dem Sie einen der Datensätze der Tabelle tblKunden auswählen können. Wir haben es als Nachschlagefeld ausgelegt.
Außerdem finden Sie hier das Feld Bezeichnung. Damit soll der Benutzer eine individuelle Bezeichnung für die Adresse angeben können, damit er diese später leicht identifizieren kann. Es handelt sich jedoch um kein Pflichtfeld.
Von der Adresse zum Kunden zur Adresse
Nun können wir zwar bereits für eine Adresse festlegen, zu welchem Kunden diese gehört, und auf diese Weise einem Kunden keine, eine oder auch mehrere Adressen zuweisen. Aber woher wissen wir, welche Adresse die Lieferadresse des Kunden ist und welche die Rechnungsadresse
Dazu müssen wir der Tabelle tblKunden noch weitere Felder hinzufügen, was wir wie in Bild 3 erledigen. Das erste Feld heißt LieferadresseID und ist ein Fremdschlüsselfeld zur Auswahl eines der Datensätze der Tabelle tblAdressen. Das zweite Feld namens RechnungsadresseID dient der Auswahl der für den Rechnungsversand zu verwendenden Adresse.
Bild 3: Entwurf der Tabelle tblAdresse mit Feldern zur Auswahl von Rechnungs- und Lieferadresse
Beziehungen zwischen den Tabellen
Wir haben nun verschiedene Beziehungen festgelegt, welche die Tabellen tblKunden und tblAdressen in beide Richtungen miteinander verknüpfen. Die Tabelle tblAdressen wird über das Fremdschlüsselfeld Kunde-ID mit je einem Datensatz der Tabelle tblKunden verknüpft. Die Tabelle tblKunden wiederum wird über kein, eines oder zwei der Felder LieferadresseID und Rechnungsadresse-ID mit der Tabelle tblAdressen verknüpft (siehe Bild 4). Um die Beziehungen zwischen den ID-Feldern der Tabelle tblAdressen und den beiden Fremdschlüsselfeldern LieferadresseID und RechnungsadresseID im Beziehungen-Fenster abzubilden, haben wir die Tabelle tblAdressen unter dem Namen tblAdressen_1 ein zweites Mal hinzugefügt. Die Beziehung zwischen dem Feld KundeID der hier unter tblAdressen_1 abgebildeten Tabelle und der Tabelle tblKunden lässt sich aus technischen Gründen nicht abbilden, sie ist aber wie für die Tabelle tblAdressen dargestellt vorhanden.
Bild 4: Beziehungen zwischen den Tabellen
Reihenfolge beim Anlegen der Daten
Wenn Sie einen Datensatz in die Tabelle tblAdressen eingeben, müssen Sie auch gleich über das Feld KundeID festlegen, zu welchem Kunden die Adresse gehört. Daher muss zu diesem Zeitpunkt bereits ein Kundendatensatz vorhanden sein. Die Reihenfolge lautet also: Erst Kundendatensatz anlegen, dann die Adressdatensätze. Um sicherzustellen, dass kein Adressdatensatz gespeichert werden kann, ohne dass ein Kundendatensatz referenziert wurde, stellen wir die Eigenschaft Eingabe erforderlich für das Feld KundeID der Tabelle tblAdressen auf Ja ein. Dies sollten Sie erledigen, bevor Sie Daten in die Tabelle tblAdressen eingegeben haben, deren Fremdschlüsselfeld KundeID noch leer ist. Datensätze in der Tabelle tblAdressen ohne referenzierten Kundendatensatz sind ein Problem, denn sie befinden sich quasi im luftleeren Raum – sie sind keinem Kunden zugeordnet und so nicht zu gebrauchen.
Löschweitergabe bei den Verknüpfungen
Wenn wir mit Verknüpfungen arbeiten, müssen wir uns auch ansehen, welche Regeln wir für das Löschen von Daten festlegen. Das ist einfach: Wenn ein Kundendatensatz aus der Tabelle tblKunden gelöscht wird, sollen natürlich auch die mit diesem Kunden verknüpften Adressdatensätze aus der Tabelle tblAdressen gelöscht werden. Die Frage ist nur: Über welche Beziehung können wir das festlegen Die korrekte Antwort ist: Über die Beziehung der Felder LieferadresseID und RechnungsadresseID der Tabelle tblKunden zum Feld ID der Tabelle tblAdressen.
Im Fenster Beziehungen bearbeiten für diese Beziehung stellen wir die Eigenschaft Löschweitergabe an verwandte Datensätze zusätzlich zu Mit referentieller Integrität ein (siehe Bild 5).
Bild 5: Beziehung zwischen den Tabellen tblKunden und tblAdressen
Damit werden nun beim Löschen eines Kunden aus der Tabelle tblKunden gleichzeitig alle mit diesem Kundendatensatz verknüpften Adressen gelöscht.
Auswahl der Rechnungs- und Lieferadresse
Wenn wir nun einige Datensätze zur Tabelle tblKunden hinzugefügt haben und in der Tabelle tblAdressen Adressen angelegt haben, die mit den Einträgen der Tabelle tblKunden verknüpft sind, können wir für die beiden Fremdschlüsselfelder LieferadresseID und RechnungsadresseID die passenden Einträge aus der Tabelle tblAdressen auswählen.
Sobald wir zum Beispiel das Nachschlagefeld LieferadresseID der Tabelle tblKunden aufklappen, finden wir dort nicht nur die Einträge der Tabelle tblAdressen vor, die wir dem aktuellen Kunden über das Feld KundeID zugewiesen haben, sondern alle Adressen. Wir müssten hier also noch einen Filter einbauen, der nur die zu diesem Kunden passenden Adressen liefert.
Das ist nun allerdings keine Aufgabe mehr, die wir im Datenmodell erledigen können – dazu benötigen wir entsprechende Formulare.
Formulare zur Eingabe von Kunden und Adressen
Wir starten mit einem einfachen Formular namens frmKunden, das über die Eigenschaft Datensatzquelle an die Tabelle tblKunden gebunden ist.
Außerdem ziehen wir alle Felder dieser Tabelle über die Feldliste in den Entwurf des Formulars und ordnen die Felder wie in Bild 6 an.
Bild 6: Das Formular sfmKundenAdressen in der Entwurfsansicht
Damit haben wir zwar nun die Möglichkeit, über die beiden Kombinationsfelder, die an die Felder LieferadresseID und RechnungsadresseID gebunden sind, aus allen vorhandenen Adressen auszuwählen.
Aber genau das wollten wir ja verhindern und die dort zur Auswahl angebotenen Datensätze auf die zum Kunden gehörenden Adressen reduzieren.
Dazu passen wir nun die Datensatzherkunft der beiden Kombinationsfelder an, die wir übrigens vorher in cboLieferadresseID und cboRechnungsadresseID umbenennen.
Dann fügen wir dem ersten der beiden Kombinationsfelder eine Abfrage hinzu, die wir mit dem Abfrage-Generator wie in Bild 7 zusammenstellen.
Bild 7: Datensatzherkunft für die Kombinationsfelder zur Auswahl der Liefer- und Rechnungsadresse
Wir fügen der Abfrage zunächst das Primärschlüsselfeld der Tabelle hinzu. In der zweiten Spalte legen wir ein Feld namens Adresse an, das folgenden Ausdruck, bestehend aus verschiedenen Feldern der Tabelle, liefern soll. Aber nur, wenn das Feld Bezeichnung, das der Benutzer für jede Adresse vergeben kann, leer ist:
Adresse: Nz([Bezeichnung];[Nachname] & ", " & [Vorname] & " ("+[Firma]+")")
Wir stellen hier einen Ausdruck zusammen, der zunächst prüft, ob das Feld Bezeichnung einen Wert enthält. Falls ja, liefert der Ausdruck diesen Wert zurück. Anderenfalls ist das Ergebnis ein Ausdruck mit dem Format