Kundendatensätze zusammenführen

Wenn Sie ein Abonnement des Magazins 'Access im Unternehmen' besitzen, können Sie sich anmelden und den kompletten Artikel lesen.
Anderenfalls können Sie das Abonnement hier im Shop erwerben.

Kundendatensätze zusammenführen

Wer eine Kundendatenbank pflegt, wird früher oder später Dubletten in seiner Datenbank vorfinden. Sei es, weil Kunden sich mit neuer E-Mail und neuer Adresse erneut im Onlineshop anmelden und von dort importiert werden oder weil man bei der Suche nach einem vorhandenen Konto für einen Kunden wegen eines Tippfehlers keinen Treffer landet – langfristig lassen sich doppelte Kundendatensätze nicht verhindern. Aber das ist kein Problem: In Datenbanken lässt sich zum Glück alles nachträglich ändern. Wie dies bei Kundendaten und den damit verknüpften Daten wie etwa Bestellungen funktioniert, erklärt dieser Beitrag.

Das Problem nach der Erstellen eines doppelten Kundendatensatzes lautet: Wie mache ich aus den beiden Kundendatensätzen einen, und vor allem: Wie sorge ich dafür, dass die Daten, die mit dem zu löschenden Kundendatensatz verknüpft sind, mit dem verbleibenden Kundendatensatz zusammengeführt werden?

Es wäre ja leicht, wenn man einfach den »alten« Kundendatensatz löschen könnte und dann Ruhe hätte. Aber in der Regel erstellt man ja einen Kundendatensatz erst, wenn für diesen auch eine Bestellung vorliegt. Wenn wir ein Datenmodell wie in Bild 1 zugrunde legen, bei dem ein Bestelldatensatz auf der einen Seite mit dem bestellenden Kunden, auf der anderen Seite mit der Tabelle Bestelldetails verknüpft wird, ist klar: Wir können nicht einfach den alten Datensatz löschen, sondern müssen auch alle Daten der Tabelle tblBestelldetails auf den Kundendatensatz übertragen, der beibehalten werden soll. Das bedeutet eigentlich nur, dass der Wert des Fremdschlüsselfeldes KundeID mit dem entsprechenden Primärschlüsselwert des neuen Kundendatensatzes gefüllt werden muss. Das allein lässt sich mit einer einfachen UPDATE-Abfrage erledigen. Danach noch den nicht mehr benötigten Kundendatensatz löschen oder als inaktiv markieren, schon ist man fertig.

Tabellen der Beispieldatenbank

Bild 1: Tabellen der Beispieldatenbank

Um solche Änderungen nachher wieder rückgängig machen oder zumindest nachvollziehen zu können, sollten Sie die geänderten oder gelöschten Daten archivieren. Wenn Sie Access ab Version 2010 verwenden, können Sie dies etwa gemäß dem Beitrag Geänderte Daten archivieren (www.access-im-unternehmen.de/925) erledigen. Beim SQL Server würden Sie entsprechende Trigger nutzen oder in die gespeicherten Prozeduren, welche die Daten ändern, passende Anweisungen zum Sichern der Datensätze einbringen.

Benutzeroberfläche

Nun hätten wir die Theorie bereits erledigt. Wie aber sieht die Praxis aus? Otto Normalverbraucher kann leider meist nicht mal eben eine UPDATE-Anweisung ins Direktfenster schmeißen, sodass wir für die gewünschte Funktion eine entsprechende Benutzeroberfläche bereitstellen müssen. Nehmen wir doch ein herkömmliches Formular mit Unterformular als Basis, wie es zur Darstellung von Daten aus zwei Tabellen einer 1:n-Beziehung aussieht. Im Beispiel aus Bild 2 finden Sie die Tabelle tblKunden im Hauptformular und die Bestellungen des aktuell angezeigten Kunden aus tblBestellungen im Unterformular vor.

Formular zur Anzeige der Bestellungen eines Kunden

Bild 2: Formular zur Anzeige der Bestellungen eines Kunden

Im Gegensatz zum Standard-Bestellformular, das eine Bestellung samt Bestellpositionen anzeigt, fallen hier die Bestelldetails unter den Tisch. Wir können diese mit einem zweiten Unterformular nachreichen, das die Bestellpositionen zu der jeweils im ersten Unterformular ausgewählten Bestellung anzeigt. Dies ist allerdings unnötig, denn wir wollen ja nur die Bestellungen des nicht mehr benötigten Duplikats eines Kunden auf einen anderen Kunden übertragen. Die Bestellpositionen sind ja ohnehin mit der Tabelle tblBestellungen verknüpft und werden quasi »mit übertragen«.

Gibt es nun eine sinnvolle Variante, um diesen Datensatz mit einer Dublette zusammenzuführen? Nun, eigentlich nicht – denn diese müssten wir ja auf jeden Fall erst einmal ausfindig machen. Gelegentlich wird sich vielleicht ein Kunde melden, der vielleicht Kundennewsletter an die beiden unterschiedlichen E-Mail-Adressen seiner beiden Accounts erhält und somit das Vorhandensein eines Duplikats aufdecken. In der Regel sollten Sie sich allerdings, je nach der Anzahl der zu verwaltenden Kunden, von Zeit zu Zeit selbst auf die Suche nach Duplikaten machen.

Aufmerksame und langjährige Access im Unternehmen-Leser werden jetzt aufhorchen: War da nicht mal was? Ja, genau: Im Beitrag Duplikatsuche in Access (www.access-im-unternehmen.de/744) haben wir ein Formular vorgestellt, mit dem Sie flexibel Duplikate in Ihren Datenbeständen finden können. Die Lösung aus diesem Beitrag werden wir für unsere Zwecke nutzen und entsprechend aufbohren.

Integration der Lösung in eigene Datenbanken

Wenn Sie die Lösung in einer eigenen Datenbank nutzen möchten, müssen Sie zunächst die folgenden Objekte aus der Beispieldatenbank in Ihre Datenbank importieren:

  • frmDuplikatmanager
  • sfmDuplikatfelder
  • sfmFlex
  • frmDuplikatdetails
  • tblDuplikatfelder
  • clsDatasheetForm
  • clsDatasheetControl
  • clsColumnWidths
  • mdlTools

Damit erhalten Sie schon einmal das Formular aus Bild 3 mit allen benötigten Unterformularen, Modulen und Klassen. Außerdem fügen Sie so eine Tabelle hinzu, welche die Konstellation für das Auffinden der Duplikate speichert.

Das Formular zum Ermitteln und Abgleichen der Duplikate einer Tabelle

Bild 3: Das Formular zum Ermitteln und Abgleichen der Duplikate einer Tabelle

Außerdem müssen Sie das Formular frmDuplikatdetails noch an die Gegebenheiten der Zieldatenbank anpassen. Das Formular sieht in der Beispieldatenbank im Entwurf wie in Bild 4 aus. Dieses Formular soll einen der zusammenzufassenden Datensätze mit den notwendigsten Informationen für den Abgleich darstellen. Das Hauptaugenmerk liegt dabei darauf, dass die verknüpften Daten angezeigt werden, die beim Zusammenführen zweier (oder auch mehrerer) Duplikate berücksichtigt werden sollen. Auf diese Weise kann der Benutzer sich nochmals versichern, dass dort auch die richtigen Daten zusammengeführt werden.

Formular zur Anzeige der Details zu einem der Duplikate

Bild 4: Formular zur Anzeige der Details zu einem der Duplikate

Das Formular soll mehrfach geöffnet werden. Mit einem Klick auf die Schaltfläche Als Ziel übernehmen übernimmt der Benutzer dann den entsprechenden Datensatz als Zieldatensatz für das Zusammenführen der Daten – die bis dahin geöffneten Detailformulare werden dann geschlossen.

Ablauf der Zusammenführung zweier Datensätze

Das Formular frmDuplikatmanager bietet in einem Kombinationsfeld alle Tabellen der aktuellen Datenbank zur Auswahl an. Wenn der Benutzer eine Tabelle ausgewählt hat, erscheinen alle Felder im linken, oberen Unterformular. Dort finden Sie neben der Spalte mit den Feldnamen noch zwei weitere Spalten – eine mit den für die Duplikatsuche zu verwendenden Felder und eine mit den Feldern, die im Ergebnis angezeigt werden sollen.

Nachdem der Benutzer diese festgelegt hat (im Screen­shot sollen nur die E-Mail-Adressen abgeglichen werden und alle Felder in der Ergebnisliste erscheinen), klickt er auf die Schaltfläche Duplikate suchen. Findet die Lösung mindestens ein Duplikat, zeigt es die Anzahl der gefundenen Exemplare sowie den Wert des Vergleichsfeldes im Unterformular rechts oben an.

Hier kann der Benutzer nun wiederum auf einen Eintrag klicken und so alle Duplikate zu diesem Eintrag im unteren Unterformular einblenden. Dies hat den Vorteil, dass Sie direkt prüfen können, ob sich die Inhalte der übrigen Felder unterscheiden. Wenn Sie sich entschieden haben, welcher der Datensätze beibehalten werden soll, können Sie in diesem gegebenenfalls Korrekturen vornehmen oder Informationen aus den zu löschenden Datensätzen übernehmen.

Nun kommt auch unser Formular für die Anzeige der Duplikatdetails ins Spiel. Der Hauptgrund für die Erstellung der vorliegenden Lösung ist ja, nicht nur einen von mehreren Datensätzen (im Beispiel Kunden) zu übernehmen und die übrigen zu löschen, sondern auch noch die Daten, die mit den zu löschenden Datensätzen verknüpft sind, auf den verbleibenden Datensatz zu übertragen.

Deshalb können Sie mit dem Formular frmDuplikatdetails in diesem Beispiel die Kundendaten plus die Bestellungen der Kunden anzeigen, und zwar per Doppelklick auf einen der Einträge im unteren Unterformular. Im Gegensatz zu üblichen Formularen, von denen Sie nur jeweils eine einzige Instanz öffnen, können Sie hier für jeden der in der Liste enthaltenen Kunden ein Detailformular öffnen. In Bild 5 sehen Sie beispielsweise zwei Formulare mit verschiedenen Datensätzen zum gleichen Kunden. Klicken Sie hier auf die Schaltfläche Als Ziel übernehmen, werden alle Formulare geschlossen. Außerdem markiert das Formular frmDuplikatmanager den zu übernehmenden Datensatz im unteren Unterformular.

Vergleich zweier Datensätze für den gleichen Kunden

Bild 5: Vergleich zweier Datensätze für den gleichen Kunden

Nun folgt der interessante Teil: Das untere Listenfeld des Formulars frmDuplikatmanager zeigt alle mit der zusammenzuführenden Tabelle per 1:n-Beziehung verknüpften Tabellen an, in diesem Fall tblBestellungen und tblNotizen (s. Bild 6).

Auswahl der zu übernehmenden Daten aus den verknüpften Tabellen

Bild 6: Auswahl der zu übernehmenden Daten aus den verknüpften Tabellen

Sie können nun einen oder mehrere Einträge auswählen, damit die enthaltenen Datensätze auf den zu übernehmenden Kundendatensatz übertragen werden. Um die Duplikate letztlich zusammenzuführen, klicken Sie auf die Schaltfläche rechts neben dem Listenfeld.

Danach sollte der übernommene Datensatz rasch vom unteren Unterformular verschwinden. Über einen Doppelklick auf den verbleibenden Datensatz können Sie sich im Detailformular vergewissern, dass die verknüpften Daten wie gewünscht übernommen wurden.

Sicher ist sicher

Zur Sicherheit sollten Sie solche Aktionen nicht durchführen, ohne zuvor eine Kopie der Datenbank angelegt zu haben. Noch besser wäre es, wenn Sie Access 2010 oder höher verwenden und die geänderten oder gelöschten Datensätze in entsprechenden Archivtabellen sichern. Eine geeignete Lösung finden Sie in den Beiträgen Geänderte Daten archivieren auf (www.access-im-unternehmen.de/925) und Änderungshistorie implantieren (www.access-im-unternehmen.de/995).

Aufbau der benötigten Formulare

Die folgenden Abschnitte erläutern die Zusammenhänge zwischen dem Haupt- und den Unterformularen und wie diese gefüllt werden und auf Benutzeraktionen reagieren.

Laden des Formulars

Beim Laden des Formulars frmDuplikatmanager müssen einige Aktionen ausgeführt werden, um das Formular vorzubereiten. Dies geschieht in der Ereignisprozedur, die durch das Ereignis Beim Laden ausgelöst wird (s. Listing 1).

Private Sub Form_Load()
     Dim db As DAO.Database
     Set db = CurrentDb
     db.Execute "DELETE FROM tblDuplikatfelder", dbFailOnError
     Me!sfmDuplikatfelder.Form.Requery
     Set frm_sfmDuplikate = Me!sfmDuplikate.Form
     frm_sfmDuplikate.OnCurrent = "[Event Procedure]"
     Set objCW_Duplikatfelder = New clsColumnWidths
     Set objCW_Duplikatfelder.DataSheetForm = Me!sfmDuplikatfelder.Form
     Set objCW_Duplikate = New clsColumnWidths
     Set objCW_Duplikate.DataSheetForm = Me!sfmDuplikate.Form
     Set objCW_DuplikateDetail = New clsColumnWidths
     Set objCW_DuplikateDetail.DataSheetForm = Me!sfmDuplikateDetails.Form
     DatasheetFormInstanzieren
     Set colForms = New Collection
End Sub

Listing 1: Vorbereitung des Formulars und seiner Elemente

Diese leert zunächst die Tabelle tblDuplikatfelder, welche später mit je einem Datensatz für jedes Feld der zu untersuchenden Tabelle gefüllt wird (s. Bild 7). Danach aktualisiert sie den Inhalt des Unterformulars sfmDuplikatfelder, damit dieses den aktualisierten Inhalt der nun leeren Tabelle tblDuplikatfelder anzeigt. Anschließend füllt sie die folgende Variable mit einem Verweis auf das Unterformular sfmDuplikate:

Tabelle zum Speichern der zu verwendenden Felder

Bild 7: Tabelle zum Speichern der zu verwendenden Felder

Dim WithEvents frm_sfmDuplikate As Form

Dies geschieht mit dem Schlüsselwort WithEvents, weil wir im Klassenmodul des Hauptformulars Ereignisse für dieses Unterformular implementieren wollen – zum Beispiel für die Auswahl eines der enthaltenen Datensätze, um dann alle passenden Duplikate im Unterformular sfmDuplikatdetails anzuzeigen. Dabei handelt es sich um das Ereignis Beim Anzeigen, wozu wir noch mitteilen müssen, dass das aktuelle Klassenmodul auf solche Ereignisse lauschen soll (OnCurrent = [Event Procedure]).

Die drei Unterformulare sfmDuplikatfelder, sfmDuplikate und sfmDuplikateDetails sollen mit optimierter Spaltenbreite angezeigt werden. Dazu verwenden wir die Klasse clsColumnWidths, die wir ausführlich im Beitrag Spaltenbreiten optimieren mit Klasse vorstellen (siehe www.access-im-unternehmen.de/998).

Wir wollen jedes der drei Unterformulare mit der Funktion zur optimalen Anpassung der Spaltenbreiten ausstatten, also legen wir drei Objektvariablen für die entsprechenden Objekte fest:

Dim objCW_Duplikatfelder As clsColumnWidths
Dim objCW_Duplikate As clsColumnWidths
Dim objCW_DuplikateDetail As clsColumnWidths

Diese instanziert die Prozedur Form_Load dann und stellt mit der Eigenschaft DataSheetForm jeweils das betroffene Unterformular ein.

Danach ruft sie noch die Prozedur DatasheetFormInstanzieren auf, die dem unteren Unterformular einige Funktionen hinzufügt, und instanziert ein Collection-Objekt, das wir im Kopf des Klassenmoduls deklarieren:

Dim colForms As Collection

Den Zweck dieser Collection erläutern wir weiter unten.

Instanzieren der Datenblattfunktionen von sfmDuplikateDetails

Das untere Unterformular namens sfmDuplikateDetails soll bei einem Doppelklick auf einen der Datensätze ein Ereignis auslösen, um einen Detaildatensatz in einem eigenen Formular anzuzeigen. Damit der Benutzer dabei nur auf eine beliebige Stelle im Datensatz zu klicken braucht, müssen wir theoretisch für jedes Steuerelement eine Beim Klicken-Ereignisprozedur anlegen.

Dies können wir uns jedoch sparen, wenn wir die beiden im Beitrag Datenblattereignisse mit Klasse vorgestellten Klassen nutzen. Damit brauchen wir als Erstes nur ein Element mit folgendem Typ zu deklarieren:

Dim WithEvents objDS As clsDataSheetForm

Danach benötigen wir noch die Anweisungen aus der Routine aus Listing 2. Diese instanziert das Objekt auf Basis von clsDatasheetForm und weist diesem das Unterformular sfmDuplikateDetails als Formular zu. Außerdem stellt sie die Eigenschaft PrimaryKey auf den Primärschlüsselnamen der zu untersuchenden Tabelle ein, den wir mit der Funktion GetSinglePrimaryKey einlesen (siehe Primärschlüsselfelder ermitteln, www.access-im-unternehmen.de/1004. Mit ZeileBeiKlickMarkieren = False legen wir fest, dass beim Anklicken nicht die komplette Zeile des Datensatzes markiert werden soll.

Private Sub DatasheetFormInstanzieren()
     Set objDS = New clsDatasheetForm

Dies war die Leseprobe dieses Artikels.
Melden Sie sich an, um auf den vollständigen Artikel zuzugreifen.

Bitte geben Sie die Zeichenfolge in das nachfolgende Textfeld ein

Die mit einem * markierten Felder sind Pflichtfelder.

Ich habe die Datenschutzbestimmungen zur Kenntnis genommen.