Daten anonymisieren

Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.

Wenn ein potenzieller Kunde Sie um Unterstützung beim Programmieren oder Anpassen einer bestehenden Datenbank bittet, ist es am einfachsten, wenn diese Ihnen die Datenbank zum Analysieren zur Verfügung stellt. Das scheitert aber oft daran, dass der Kunde die Datenbank nicht herausgeben darf, weil die enthaltenen Daten nicht weitergegeben werden dürfen. Oft handelt es sich dabei um Adressdaten. Dieser Beitrag zeigt, wie Sie dem Kunden das Werkzeug bereitstellen, die enthaltenen Daten zu anonymisieren.

Warum anonymisieren

Aber warum sollte man sich überhaupt die Mühe machen, die Daten zu anonymisieren Es wäre doch viel einfacher, einfach die Datenbank zu kopieren und die enthaltenen Daten vor der Weitergabe zu löschen. Klar, das geht viel schneller: Allerdings enthält die Datenbank dann auch keine Daten und der Entwickler – in diesem Fall Sie – oder der Kunde müssen manuell einige Testdatensätze eingeben. Und manchmal sollen ja gerade Performance-Probleme behoben werden. In diesem Fall ist es natürlich komplett abwegig, eine leere Datenbank an den Entwickler zu übergeben.

Beides sind gute Anlässe, ein Tool zu programmieren, das den Kunden dabei unterstützt, die Datenbank in eine Form zu bringen, die keine nachvollziehbaren personenbezogenen Daten mehr enthält.

Konkreter Anlass

Im konkreten Fall geht es viel weniger um die oben beschriebene Konstellation, als um die änderung der Personendaten zwecks Veröffentlichung der programmierten Lösung samt Beispieldaten zum Ausprobieren der Anwendung.

Der erste Vorsitzende eines befreundeten Sportvereins ist nämlich mit einer Excel-Datei mit Mitgliedsdaten an mich herangetreten und hat mich gebeten, einmal eine vernünftige Mitgliederverwaltung zu programmieren, mit der die Daten nicht mehr in einer einzigen Excel-Tabelle verwaltet werden müssen, sondern die es auch noch ermöglicht, zusätzliche Auswertungen zu produzieren.

Wenn ich Ihnen als Leser von Access im Unternehmen meine Umsetzung dieser Lösung darlegen möchte, muss ich also die Personendaten in dieser Excel-Tabelle vorher anonymisieren. Die Lösung mit der Umwandlung der Mitgliedsdatei in eine richtige Anwendung finden Sie übrigens unter dem Titel Vereinsverwaltung: Von Excel zum Datenmodell (www.access-im-unternehmen.de/1106) in diesem Heft.

Konzept für das Tool

Wie aber gestalten wir nun das Tool, mit dem wir die Personendaten anonymisieren wollen Normalerweise würde ich es als Add-In programmieren. Allerdings müsste der Kunde dann erst das Add-In installieren, was diesen möglicherweise überfordern könnte. Also gehen wir diesmal einen anderen Weg und programmieren eine eigene Access-Lösung, mit welcher der Kunde dann die betroffene Access-Anwendung auswählen soll. Im Formular dieser Lösung sollen dann die Tabellen der Ausgangsanwendung zur Auswahl angeboten werden. Für die Felder der gewählten Tabelle soll der Benutzer dann angeben, mit welchen Daten diese gefüllt werden sollen – also mit Vornamen, Nachnamen, Straßen, PLZ und Ort, Land und so weiter. Dann soll er per Mausklick den Anonymisierungsvorgang starten können, welcher dann eine Kopie der Datenbank erstellt und die enthaltenen Daten ändert.

Das Tool erstellen

Als Tool legen wir also eine ganz normale Access-Datenbank an. Diese sollte beim öffnen möglichst gleich die enthaltene Funktion offenbaren, damit der Benutzer sich gleich zurechtfindet. In diesem Fall wäre dies das öffnen des Formulars, welches die Funktionen zum Auswählen der zu kopierenden und zu manipulierenden Datenbank enthält.

Das Formular soll keine Datensätze anzeigen, also stellen wir die Eigenschaften Datensatzmarkierer, Navigationsschaltflächen, Trennlinien und Bildlaufleisten auf Nein ein.

Fügen Sie im oberen Bereich zwei Textfelder namens txtQuelldatei und txtZieldatei ein sowie zwei Schaltflächen namens cmdDateiauswahl und cmdZieldateiFestlegen. Diese ordnen Sie wie in Bild 1 an.

Steuer-elemente zum Auswählen von Quell- und Zieldatei

Bild 1: Steuer-elemente zum Auswählen von Quell- und Zieldatei

Für die Beim Klicken-Ereigniseigenschaft hinterlegen wir jeweils eine entsprechende Ereignisprozedur. Ein Klick auf die Schaltfläche cmdDateiauswahl löst die Prozedur cmdDateiauswahl_Click aus Listing 1 aus. Diese verwendet die Funktion Openfilename, die Sie im Modul mdlDateidialoge finden. Sie übergibt der Funktion den aktuellen Datenbankpfad als Parameter und stellt die Access-Dateiendungen .mdb und .accdb als Filter ein.

Private Sub cmdDateiauswahl_Click()
     Dim strQuelldatei As String
     strQuelldatei = Openfilename(CurrentProject.Path, "Quelldatei auswählen", "Access-DB (*.mdb;*.accdb)|Alle Dateien (*.*)")
     Me!txtQuelldatei = strQuelldatei
     Me!txtZieldatei = VerzeichnisAusPfad(strQuelldatei) & "\" & ZieldateiAusPfad(strQuelldatei)
End Sub
Private Sub cmdZieldateiFestlegen_Click()
     Dim strZieldatei As String
     Dim strQuelldatei As String
     Dim strZielverzeichnis As String
     strQuelldatei = Me!txtQuelldatei
     If Len(Dir(strQuelldatei, vbDirectory)) > 0 Then
         strZieldatei = ZieldateiAusPfad(strQuelldatei)
         strZielverzeichnis = VerzeichnisAusPfad(strQuelldatei)
     End If
     strZieldatei = GetSaveFile(strZielverzeichnis, strZieldatei, "Access-DB (*.mdb;*.accdb)|Alle Dateien (*.*)", _
         "Zieldatei auswählen")
     Me!txtZieldatei = strZieldatei
End Sub
Private Function VerzeichnisAusPfad(strPfad As String) As String
     Dim strVerzeichnis As String
     strVerzeichnis = Left(strPfad, InStrRev(strPfad, "\") - 1)
     VerzeichnisAusPfad = strVerzeichnis
End Function
Private Function ZieldateiAusPfad(strPfad As String) As String
     Dim strZieldatei As String
     Dim intPunkt As String
     strZieldatei = Mid(strPfad, InStrRev(strPfad, "\") + 1)
     intPunkt = InStrRev(strZieldatei, ".")
     strZieldatei = Left(strZieldatei, intPunkt - 1) & "_Anonymisiert" & Mid(strZieldatei, intPunkt)
     ZieldateiAusPfad = strZieldatei
End Function

Listing 1: Prozeduren zum Auswählen von Quell- und Zieldatei

Das Ergebnis dieses Dialogs speichert sie in der Variablen, deren Inhalt direkt an das Textfeld txtQuelldatei weitergegeben wird. Außerdem ruft die Prozedur zwei weitere Hilfsfunktionen namens VerzeichnisAusPfad und ZieldateiAusPfad auf, welche sich ebenfalls im Klassenmodul des Formulars befinden und im Listing abgebildet sind.

VerzeichnisAusPfad erwartet einen kompletten Pfad, also beispielsweise die Angabe aus Bild 2 im oberen Textfeld. Es ermittelt die Position des hintersten Backslash und liefert die Zeichenkette bis zu dieser Position minus eins, damit der Backslash wegfällt.

Auswählen von Quell- und Zieldatei

Bild 2: Auswählen von Quell- und Zieldatei

Die Funktion ZieldateiAusPfad arbeitet etwas spezifischer und liefert nicht nur einfach den Dateinamen des hineingegebenen Pfades, sondern ergänzt diesen so, dass der Dateiname gut als die anonymisierte Version zu erkennen ist. Die Funktion ermittelt ebenfalls zunächst in einer Anweisung den Teil des mit strPfad übergebenen Pfades, der sich hinter dem letzten Backslash in strPfad befindet. Das Verzeichnis wird also vorn abgeschnitten. Dann ermittelt sie die Position des Punktes, also des Zeichens, das sich zwischen dem eigentlichen Dateinamen und der Dateiendung befindet. Der in der Variablen strZieldatei zwischengespeicherte Ausdruck besteht dann aus dem Teil vor dem Punkt, dem Ausdruck _anonymisiert. und der Dateiendung. Dieses automatische Füllen des Feldes txtZieldatei ist eine Möglichkeit, dem Benutzer weitere Schritte abzunehmen, denn er braucht in den meisten Fällen nicht noch die Zieldatei auszuwählen.

Möchte er dies dennoch tun, hat er natürlich die Möglichkeit dazu. Er braucht dann nur auf die Schaltfläche cmdZieldateiFestlegen zu klicken, welche die Prozedur cmdZieldateiFestlegen_Click auslöst. Diese liest den Wert des Feldes txtQuelldatei in die Variable strQuelldatei ein und prüft, ob dieser Ausdruck ein gültiges Verzeichnis enthält.

In diesem Fall ermittelt die Prozedur über die Funktion ZieldateiAusPfad einen Vorschlag für den Namen der Zieldatei und speichert diesen in der Variablen strZieldatei. Das Zielverzeichnis wird über die Funktion VerzeichnisAusPfad ermittelt und landet in der Variablen strZielverzeichnis.

Danach ruft die Prozedur über die Funktion GetSaveFile einen Dialog auf, über den der Benutzer die Zieldatei festlegen soll. Hier wird auch klar, warum wir zuvor Zielverzeichnis und Zieldatei in zwei verschiedene Variablen geschrieben haben: Beim Aufruf dieser Funktion wird das Zielverzeichnis als beim öffnen anzuzeigendes Verzeichnis gewählt und der Name der Zieldatei wird unten im Dialog voreingestellt (s. Bild 3). Schließlich landet die hier ausgewählte Datei im Textfeld txtZieldatei.

Auswählen der Zieldatei

Bild 3: Auswählen der Zieldatei

Datei kopieren

Wir haben ja avisiert, dass wir nicht in der vom Benutzer ausgewählten Datei herumspielen – es kann immerhin sein, dass der Benutzer zuvor keine Kopie anlegt und direkt eine Originaldatei zum anonymisieren auswählt. Also legen wir auf jeden Fall zuvor eine Kopie der Datenbank an, wozu wir die zuvor ermittelten Daten zur Quell- und Zieldatei nutzen.

Wir legen direkt einmal eine Schaltfläche namens cmdAnonymisieren im Formular an, auch wenn wir noch keine Steuer-elemente zum Einstellen der Anonymisierungsdetails hinzugefügt habe und diese Funktionalität noch fehlt. Allerdings ist das Kopieren der Datei der Grundstein, daher beginnen wir damit (s. Bild 4). Diese Schaltfläche löst nun die folgende Prozedur aus, welche wiederum eine Funktion zum Kopieren der Quelldatenbank in die Zieldatenbank aufruft. Sollte diese Funktion namens DateiKopieren den Wert True zurückliefern, soll der Inhalt der If…Then-Bedingung ausgeführt werden:

Schaltfläche zum Start des Vorgangs

Bild 4: Schaltfläche zum Start des Vorgangs

Private Sub cmdAnonymisieren_Click()
     If DateiKopieren(Me!txtQuelldatei, Me!txtZieldatei) Then
         ''''...anonymisieren
     End If
End Sub

Funktion zum Kopieren der Datenbank

Die dadurch aufgerufene Funktion DateiKopieren finden sie in Listing 2. Die Funktion erwartet den Pfad der Quell- und der Zieldatenbank als Parameter. Das Kopieren gelingt nicht, wenn die Quelldatei geöffnet ist. Ob dies der Fall ist, ermitteln wir, indem wir nach einer Datei suchen, deren Dateiname auf .ldb oder .laccdb endet. Dies ist die Dateiendung der Datei, die beim öffnen einer Access-Datei angelegt wird. Ist eine solche Datei vorhanden, dann ist die Quelldatei offensichtlich geöffnet und kann nicht kopiert werden. Der Versuch, dies mit der FileCopy-Funktion zu erledigen, würde sonst zum Auslösen des Fehlers mit der Nummer 70 führen (Zugriff verweigert). In diesem Fall gibt die Funktion eine entsprechende Meldung aus. Auch für die Zieldatei erfolgt eine entsprechende überprüfung. Ist die Quelldatenbank hingegen nicht geöffnet und die Zieldatenbank entweder nicht geöffnet oder nicht vorhanden, kopiert die Prozedur diese mit der FileCopy-Methode, der Sie den Pfad zur Quell- und zur Zieldatei übergibt.

Public Function DateiKopieren(strQuelle As String, strZiel As String)
     Dim strQuelleTemp As String
     Dim strZielTemp As String
     strQuelleTemp = Replace(strQuelle, ".mdb", ".ldb")
     strQuelleTemp = Replace(strQuelleTemp, ".accdb", ".laccdb")
     If Len(Dir(strQuelleTemp)) > 0 Then
         MsgBox "Die Quelldatei muss geschlossen sein."
         Exit Function
     End If
     strZielTemp = Replace(strZiel, ".mdb", ".ldb")
     strZielTemp = Replace(strZielTemp, ".accdb", ".laccdb")
     If Len(Dir(strZielTemp)) > 0 Then
         MsgBox "Die Zieldatei muss geschlossen sein."
         Exit Function
     End If
     FileCopy strQuelle, strZiel
     If Len(Dir(strZiel)) > 0 Then
         DateiKopieren = True
     End If
End Function

Listing 2: Die Funktion zum Kopieren der Zieldatei in die Quelldatei

Ist die Zieldatei anschließend im Dateisystem vorhanden, stellt die Funktion den Rückgabewert auf True ein.

Tabellen und Felder speichern

Wir wollen es dem Benutzer ermöglichen, alle zu ändernden Tabellen und Felder auf einen Streich zu definieren. Dazu muss er diese zunächst einlesen und wir müssen mit einem geeigneten Formular dafür sorgen, dass diese auch vom Benutzer bearbeitet werden können.

Wir wollen also Informationen über die Tabellen und die darin enthaltenen Felder speichern. Dazu benötigen wir zwei Tabellen namens tblTabellen und tblFelder. Die erste sieht im Entwurf wie in Bild 5 aus.

Entwurf der Tabelle tblTabellen

Bild 5: Entwurf der Tabelle tblTabellen

Sie enthält ein Primärschlüsselfeld, ein Feld mit dem Namen der Tabelle sowie ein Ja/Nein-Feld namens Anonymisieren, mit der Benutzer festlegen kann, ob diese Tabelle komplett anonymisiert werden soll. Die zweite Tabelle namens tblFelder enthält einige Felder mehr. Das liegt daran, dass hier die Details zum Anonymisieren der Inhalte gespeichert werden. Den Entwurf der Tabelle können Sie Bild 6 entnehmen. Neben den bereits aus der Tabelle tblTabellen bekannten Feldern nutzen wir hier die folgenden Felder:

Entwurf der Tabelle tblFelder

Bild 6: Entwurf der Tabelle tblFelder

  • Felddatentyp: Speichert den Zahlenwert, der den Felddatentyp des Feldes repräsentiert
  • TabelleID: Fremdschlüsselfeld, mit dem der Datensatz der Tabelle tblTabellen festgelegt wird, zu dem das Feld gehört
  • ErsetzenMitID: Fremdschlüsselfeld zu einer Tabelle namens tblErsetzenMit. Hier werden verschiedene Möglichkeiten zum Ersetzen abgebildet, zum Beispiel Vorname, Nachname, Straße et cetera. Damit wird beispielsweise festgelegt, aus welchen Hilfstabellen die zu ersetzenden Daten kommen.
  • Info1, Info2, Info3: Diese Felder enthalten Hinweistexte für weitere Informationen, die in den Feldern Wert1, Wert2 und Wert3 gespeichert werden. Damit können Sie zum Beispiel für Felder, die mit Datumswerten gefüllt werden sollen, den Datumsbereich festlegen.
  • Wert1, Wert2, Wert3: Diese Felder nehmen die Werte auf, die zum Füllen der Felder als Referenz benutzt werden sollen.

Wie Sie der Abbildung entnehmen können, legen wir für die Tabelle außerdem einen zusammengesetzten, eindeutigen Index an, der dafür sorgt, dass jeder Feldname nur einmal je Tabelle eingegeben werden darf. Dazu fügen wir diesem die beiden Felder Feldname und TabelleID hinzu und legen für die Eigenschaft Eindeutig den Wert Ja fest.

Beziehung zwischen den Tabellen tblTabellen und tblFelder

Die Tabelle tblTabellen und tblFelder sollen in einer 1:n-Beziehung stehen. Dazu haben wir per Nachschlagefeld bereits die notwendige Verknüpfung hinzugefügt. Die Verknüpfung können Sie in Bild 7 einsehen. Hier definieren wir noch referenzielle Integrität und aktivieren die Löschweitergabe an verwandte Datensätze. Dadurch werden beim Löschen eines der Datensätze der Tabelle tblTabellen auch alle mit diesem Datensatz verknüpften Datensätze der Tabelle tblFelder gelöscht.

Beziehung zwischen den beiden Tabellen tblTabellen und tblFelder

Bild 7: Beziehung zwischen den beiden Tabellen tblTabellen und tblFelder

Die Tabelle tblErsetzenMit

Die Tabelle, die Informationen darüber liefert, wie die Daten eines Feldes ersetzt werden sollen, heißt tblErsetzenMit (s. Bild 8). Diese enthält neben dem Primärschlüsselfeld ein Feld mit der Bezeichnung der Ersetzungsart sowie, genau wie die Tabelle tblFelder, die drei Felder Info1, Info2 und Info3. Diese werden mit Standardwerten befüllt, die dann nach der Auswahl eines der Einträge für das Fremdschlüsselfeld ErsetzenMitID der Tabelle tblFelder in die entsprechenden Felder Info1, Info2 und Info3 übertragen werden – gleiches gilt für die Felder Wert1, Wert2 und Wert3. Der Benutzer kann die Felder dann nach eigenen Vorstellungen anpassen.

Entwurf der Tabelle tblErsetzenMit

Bild 8: Entwurf der Tabelle tblErsetzenMit

Konfigurationen speichern

Wenn wir schon darüber reden, dass der Benutzer die Einstellungen für das Anonymisieren der Daten in den beiden Tabellen tblTabellen und tblFelder speichert, dann sollten wir uns auch Gedanken machen, was geschieht, wenn der Vorgang abgeschlossen ist. Erst hatten wir geplant, die Daten einfach zu löschen. Allerdings ist dann klar geworden, dass es ja durchaus sein kann, dass der Benutzer nicht nur einmalig seine aktuelle Version der Datenbank anonymisieren und an einen Entwickler übergeben möchte. Also speichern wir die Konfigurationen in einer Tabelle namens tblKonfigurationen (s. Bild 9). Damit die gespeicherten Daten über die Tabellen und Felder auch der entsprechenden Konfiguration zugeordnet werden können, fügen wir der Tabelle tblTabellen noch ein Fremdschlüsselfeld namens KonfigurationID auf die Tabelle tblKonfigurationen hinzu.

Entwurf der Tabelle tblKonfigurationen

Bild 9: Entwurf der Tabelle tblKonfigurationen

Die Tabelle tblKonfigurationen enthält neben Primärschlüsselfeld und Bezeichnung noch die beiden Felder Quelldatenbank und Zieldatenbank. Gleich werden wir noch das Formular frmStart so anpassen, dass dieses das Anlegen und Abrufen von Konfigurationen ermöglicht.

Formulare für die Festlegung von Tabellen und Feldern

Zuvor wollen wir jedoch noch die Unterformulare anlegen, die später im Formular frmStart landen und die Tabellen und Felder der zu anonymisierenden Datenbank zur Konfiguration durch den Benutzer anzeige sollen. Die Tabellen und Felder sollen in einer hierarchischen Ansicht erscheinen, wobei wir diesmal kein TreeView verwenden wollen, sondern die Unterdatenblatt-Ansicht von Access.

Wie Sie diese einrichten, erfahren Sie im Beitrag Unterdatenblätter in Formularen (www.access-im-unternehmen.de/1108) in dieser Ausgabe. Dort finden Sie sowohl die Beschreibung der Prozeduren, um die beiden Tabellen tblTabellen und tblFelder zu füllen als auch die Anleitung, wie Sie die Daten der beiden Tabellen in Form eines Datenblatts mit Unterdatenblatt anzeigen. Schließlich zeigen wir dort auch noch, wie Sie die Kontrollkästchen für die Ja/Nein-Felder Anonymisieren der beiden Tabellen so programmieren, dass die jeweils über- beziehungsweise untergeordneten Elemente aktiviert oder deaktiviert werden (mehr zu diesen Abhängigkeiten im genannten Beitrag).

Sobald sich nicht nur das Formular frmStart, sondern auch die beiden Unterformulare sfmTabellen und sfmFelder in Ihrer Datenbank befinden, können wir diese zusammenführen. Das Unterformular sfmFelder wurde ja bereits im Beitrag Unterdatenblätter in Formularen in das Formular sfmTabellen integriert.

Damit machen wir uns nun ans Werk, um den Entwurf des Formulars frmStart in den Zustand aus Bild 10 zu bringen.

Das Formular frmStart nach dem Umbau

Bild 10: Das Formular frmStart nach dem Umbau

Dazu sind die folgenden Schritte nötig:

  • Einfügen des Unterformulars sfmTabellen aus dem Navigationsbereich in den Entwurf des Formulars frmStart
  • Einstellen der Eigenschaften Horizontaler Anker und Vertikaler Anker für das entstandene Unterformular-Steuerelement auf Beide einstellen. Passend dazu für das Bezeichnungsfeld des Unterformulars die eigenschaften auf Links beziehungsweise Oben einstellen und für die Schaltfläche cmdAnonymisieren auf Links und Unten.
  • Einstellen der Datenherkunft des Formulars frmStart auf die Tabelle tblKonfigurationen.
  • Die beiden Textfelder txtQuelldatenbank und txtZieldatenbank können Sie nun an die entsprechenden Felder der Datenherkunft binden, indem Sie die Eigenschaft Steuerelementinhalt auf die Werte Quelldatenbank und Zieldatenbank einstellen.
  • Außerdem fügen wir oben im Formular noch ein Kombinationsfeld namens cboKonfigurationen hinzu, das wir gleich im Anschluss anpassen.

Für die Eigenschaft Datensatzherkunft des Kombinationsfeldes geben wir die folgende SQL-Abfrage ein:

SELECT KonfigurationID, Konfiguration 
FROM tblKonfigurationen 
ORDER BYKonfiguration;

Damit nur der Wert des Feldes Konfiguration angezeigt wird und nicht der Wert des Primärschlüsselfeldes KonfigurationID, stellen wir die Eigenschaften Spaltenanzahl auf 2 und Spaltenbreiten auf 0cm ein.

Neue Konfiguration anlegen

Nun wollen wir eine neue Konfiguration anlegen. Dies wollen wir über das Kombinationsfeld cboKonfigurationen erledigen, indem wir diesem einen Eintrag mit dem Text und einen weiteren mit dem Text hinzufügen.

Dazu erweitern wir die Datensatzherkunft wie folgt:

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

Testzugang

eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar