Tabellenfeldbeschriftungen im Griff

Anpassen der Beschriftung eines Feldes

Bild 1: Anpassen der Beschriftung eines Feldes

Wozu sollte man Tabellenfeldbeschriftungen im Griff haben? Und was ist das überhaupt? Die Eigenschaft “Beschriftung” von Tabellenfeldern kennen viele Entwickler gar nicht. Dabei könnten sie sich eine Menge Zeit sparen, wenn sie diese Eigenschaft nutzen würden. Trägt man nämlich beispielsweise für ein Feld wie “EMail” eine Beschriftung wie “E-Mail” ein, dann wird diese statt des Feldnamens als Spaltenüberschrift der Tabelle in der Datenblattansicht angezeigt. Und es geht noch weiter: Wenn man in Formularen und Berichten Steuerelemente auf Basis dieser Felder anlegt, übernimmt Access auch dort den Wert der Eigenschaft Beschriftung statt des Feldnamens für die Bezeichnungsfelder Steuerelemente. Man braucht als nur an einer Stelle eine Änderung vorzunehmen und profitiert an vielen anderen Stellen davon. Und wenn man nun nicht in jeder neuen Datenbank die Beschriftungen erneut anlegen müsste … doch auch dafür haben wir in diesem Beitrag eine Lösung.

Eigentlich ist es gar nicht viel Arbeit: Wir erstellen eine neue Tabelle, und für Felder wie KundeID, AnredeID, Strasse, EMail et cetera hinterlegen wir für die Eigenschaft Beschriftung jeweils den anzuzeigende Text wie ID/Kunde-ID, Anrede, Straße oder E-Mail. In Bild 1 sehen Sie, wie wir das Feld Strasse entsprechend angepasst haben.

Anpassen der Beschriftung eines Feldes

Bild 1: Anpassen der Beschriftung eines Feldes

Wechseln wir in die Datenblattansicht, sehen wir direkt die Werte der Eigenschaft Beschriftung der jeweiligen Felder statt der Feldnamen (siehe Bild 2).

Die Beschriftung wird beispielsweise in der Datenblattansicht angewendet.

Bild 2: Die Beschriftung wird beispielsweise in der Datenblattansicht angewendet.

Automatisieren der Beschriftungen

Allerdings ist das eine von vielen Aktionen, die man beim Anlegen neuer Tabellen berücksichtigen muss, und die dafür aufzuwendende Zeit summiert sich. Vor allem wenn man bedenkt, dass man diese Aufgabe im Laufe eines Entwicklerlebens sehr oft durchführt. Also sieht es so aus, als ob wir uns über die Automatisierung dieser Aufgabe Gedanken machen sollten!

Automatisieren der Festlegung von Feldbeschriftungen

Aber lässt sich das überhaupt automatisieren? Ist das nicht ein individueller Vorgang, der mit jeder Datenbank, jeder Tabelle und jedem Feld einzeln durchgeführt und vom Programmierer intensiv überdacht werden muss? Nein, das ist nicht der Fall. Außer, man möchte sich mit ein wenig Routinearbeit entspannen.

Wie also können wir diesen Vorgang automatisieren? Fest steht: Für die meisten Feldnamen gibt es genau eine passende Beschriftung, zumindest wenn man sich einmal auf einen Standard festgelegt hat. Ob zum Beispiel die Inhalte von Primärschlüssel-/Autowertfeldern angezeigt werden müssen, sei dahingestellt, aber in vielen Fällen geschieht das. Dann sollte der Benutzer statt eines Feldnamens wie KundeID oder BestellungID eine passendere Beschriftung wie Kunde-ID/Bestellung-ID, Kundennummer/Bestellnummer oder schlicht ID angezeigt bekommen.

Da einige Entwickler, wie auch ich, für Primärschlüsselfelder und Fremdschlüsselfelder die gleichen Bezeichnungen wählen – also zum Beispiel KundeID als Primärschlüsselfeld in der Tabelle tblKunden und KundeID als Fremdschlüsselfeld in der Tabelle tblBestellungen -, wollen wir hier unterscheiden. Während wir für das Fremdschlüsselfeld KundeID vermutlich die Beschriftung Kunde wählen werden, erhält das Primärschlüsselfeld KundeID eher eine Beschriftung wie Kunde-ID oder auch nur ID.

Automatisierung per VBA

Unsere Idee ist, dass wir die üblichen Zuordnungen von Feldnamen und Beschriftungen in einer Tabelle speichern, die wir beispielsweise tblCaptions nennen. Diese soll vier Felder enthalten – CaptionID, Fieldname, Caption und IsPrimaryKey.

Für die Kombination aus den Feldern Fieldname und IsPrimaryKey definieren wir einen eindeutigen Index, damit zu jedem Feldnamen für einfache Felder und für Primärschlüsselfelder nur jeweils eine Beschriftung hinterlegt werden kann (siehe Bild 3).

Tabelle zum Speichern der Zuordnung von Feldern und Beschriftungen

Bild 3: Tabelle zum Speichern der Zuordnung von Feldern und Beschriftungen

Zusätzlich wollen wir eine Prozedur programmieren, mit der wir die Felder einer Tabelle, die mit Beschriftungen ausgestattet werden soll, durchlaufen und prüfen, ob wir für die Feldnamen bereits entsprechende Beschriftungen in unserer Tabelle tblCaptions hinterlegt haben. Falls ja, soll die Beschriftung einfach für die Eigenschaft Beschriftung hinterlegt werden.

Für eine Tabelle wie tblKunden sieht der Inhalt der Tabelle tblCaption also wie in Bild 4 aus.

Die Tabelle tblCaptions mit einigen Beispieldaten

Bild 4: Die Tabelle tblCaptions mit einigen Beispieldaten

Beschriftungen per VBA zuweisen

Nun fehlt noch die passende Automatisierung. Diese erledigen wir mit einer VBA-Prozedur ApplyCaptions, die wir in Listing 1 abgebildet haben. Die Prozedur erwartet den Namen der Tabelle, deren Felder mit Beschriftungen ausgestattet werden sollen. Wir deklarieren vorsorglich schon einmal zwei Variablen für Database-Objekte: eines für die aktuelle Datenbank und eines für eine Add-In-Datenbank, denn wir werden die hier produzierten Elemente für die Automatisierung vermutlich nicht zu jeder neuen Datenbank hinzufügen, sondern diese über ein Add-In aufrufen wollen. Und bei Verwendung eines Add-Ins muss man unterscheiden, ob man auf die Daten der Tabellen der Add-In-Datenbank oder der aufrufenden Datenbank zugreifen möchte. Deshalb füllt die Prozedur auch die Variable db über die Funktion CurrentDb mit einem Verweis auf die Host-Datenbank und die Variable dbc über die Funktion CodeDb mit einem Verweis auf die Add-In-Datenbank. Und auch wenn wir aktuell noch direkt in der Host-Datenbank programmieren, ist das kein Problem, denn in diesem Fall greifen CurrentDb und CodeDb einfach beide auf die aktuelle Datenbank zu.

Public Sub ApplyCaptions(strTable As String)
     Dim db As DAO.Database
     Dim dbc As DAO.Database
     Dim rstCaptions As DAO.Recordset
     Dim tdf As DAO.TableDef
     Dim fld As DAO.Field
     Dim prp As DAO.Property
     Dim strCaption As String
     Dim bolPrimaryKey As Boolean
     Set db = CurrentDb
     Set dbc = CodeDb
     Set tdf = db.TableDefs(strTable)
     Set rstCaptions = dbc.OpenRecordset("SELECT * FROM tblCaptions", dbOpenDynaset)
     For Each fld In tdf.Fields
         bolPrimaryKey = IsPrimaryKey(tdf, fld)
         rstCaptions.FindFirst "Fieldname = ''" & fld.Name & "'' AND IsPrimaryKey = " & CInt(bolPrimaryKey)
         If Not rstCaptions.NoMatch Then
             strCaption = rstCaptions!Caption
             On Error Resume Next
             Set prp = fld.CreateProperty("Caption", dbText, strCaption)
             fld.Properties.Append prp
             If Not Err.Number = 0 Then
                 fld.Properties("Caption") = strCaption
             End If
             On Error GoTo 0
         End If
     Next fld
End Sub

Listing 1: Anwenden von Beschriftungen auf die Felder der per Parameter übergebenen Tabelle

Weiter im Code: Dort referenzieren wir mit der TableDef-Variable tdf das TableDef-Objekt für die mit dem Parameter strTable übergebene Tabelle. Dann öffnen wir ein Recordset für den Zugriff auf die Daten der Tabelle tblCaptions und speichern den Verweis in rstCaptions.

Anschließend durchläuft die Prozedur alle Felder der Tabelle, deren Felder wir mit Beschriftungen ausstatten wollen, in einer For Each-Schleife. Innerhalb der Schleife prüft die Prozedur zunächst, ob es sich bei dem aktuell untersuchten Feld um ein Primärschlüsselfeld handelt. Dies geschieht mit der Funktion IsPrimaryKey, die wir weiter unten beschreiben.

Ob es sich um ein Primärschlüsselfeld handelt oder nicht, ist wie oben bereits erwähnt wichtig, da wir bei gleicher Benennung von Primärschlüsselfeldern und Fremdschlüsselfeldern gegebenenfalls unterschiedliche Beschriftungen verwenden wollen. Danach versucht die Prozedur, im Recordset mit den Beschriftungen einen Eintrag zu finden, dessen Feld Fieldname dem Namen des aktuell durchlaufenen Feldes entspricht und das, je nachdem, welches Ergebnis die Funktion IsPrimaryKey geliefert hat, auch dieses Feld in die Bedingung einbezieht.

Wurde ein Eintrag gefunden, liefert die in der kommenden If…Then-Bedingung überprüfte Eigenschaft NoMatch den Wert False. In diesem Fall werden die Anweisungen innerhalb der If…Then-Bedingung durchgeführt. Wir schreiben dort die zu dem Feld passende Beschriftung in die Variable strCaption und weisen diese dann der Eigenschaft Beschriftung zu.

Das ist nicht ganz trivial, denn im Gegensatz zum Tabellenentwurf in der Benutzeroberfläche, wo die Eigenschaft jederzeit zur Verfügung steht, ist die dahinter stehende Eigenschaft Caption standardmäßig gar nicht in der Auflistung der Properties eines Field-Objekts vorhanden. Das entsprechende Property-Objekt wird erst angelegt, wenn der Benutzer eine Beschriftung einträgt.

Um nicht prüfen zu müssen, ob die Property bereits vorhanden ist, versuchen wir einfach, diese bei deaktivierter Fehlerbehandlung anzulegen. Dazu nutzen wir zwei Anweisungen.

Die erste ruft die CreateProperty-Methode für das Feld auf und legt für die Eigenschaft Caption mit dem Datentyp dbText den Wert aus strCaption fest. Danach hängt sie das neu erstellte Property-Objekt an die Properties-Auflistung des Field-Objekts für das Feld an.

Ist die Property bereits vorhanden, löst dieser Vorgang einen Fehler aus. Das prüfen wir in der folgenden If…Then-Bedingung und legen in diesem Fall einfach den Wert der Eigenschaft Caption auf den Wert aus strCaption fest.

Dies wiederholen wir für alle Felder der angegebenen Tabelle und tragen so für alle Felder, für die wir in der Tabelle tblCaptions eine alternative Beschriftung angegeben haben, die jeweilige Beschriftung ein.

Herausfinden, ob ein Feld ein Primärschlüsselfeld ist

Die Funktion IsPrimaryKey erwartet das TableDef-Objekt und das Field-Objekt des zu untersuchenden Feldes als Parameter (siehe Listing 2). Sie durchläuft alle Index-Elemente des übergebenen TableDef-Objekts in einer For Each-Schleife. Wenn der Index ein Primärschlüssel ist, durchläuft sie außerdem alle Felder, die zu diesem Primärschlüsselindex gehören (ein Primärschlüssel kann ja auch aus mehreren Feldern bestehen). Ist das zu untersuchende Feld hier enthalten, handelt es sich bei diesem um ein Primärschlüsselfeld und wir können die Funktion wieder verlassen.

Public Function IsPrimaryKey(tdf As DAO.TableDef, fld As DAO.Field) As Boolean
     Dim idx As DAO.Index
     Dim fldPK As DAO.Field
     For Each idx In tdf.Indexes
         If idx.Primary Then
             For Each fldPK In idx.Fields
                 If fld.Name = fldPK.Name Then
                     IsPrimaryKey = True
                     Exit Function
                 End If
             Next fldPK
         End If
     Next idx
End Function

Listing 2: Funktion zum Prüfen, ob ein Feld ein Primärschlüsselfeld ist

Noch mehr Automation: Beschriftungen einlesen

Da wir uns nun schon ein wenig in das Thema eingearbeitet haben, können wir auch noch weiter automatisieren. Wieso sollten wir eigentlich die Felder und die dafür vorgesehenen Beschriftungen von Hand in die Tabelle tblCaptions eintragen?

Nicht, dass das nicht auch eine entspannende Beschäftigung wäre … Aber noch praktischer wäre es doch, wenn wir die Beschriftung für alle vorhandenen Felder einer Tabelle auch per VBA einlesen könnten. Und genau dazu können wir die Prozedur SaveCaptions aus Listing 3 nutzen.

Public Sub SaveCaptions(strTable As String)
     Dim db As DAO.Database
     Dim dbc As DAO.Database
     Dim tdf As DAO.TableDef
     Dim fld As DAO.Field
     Dim prp As DAO.Property
     Dim rstCaptions As DAO.Recordset
     Dim strCaption As String
     Dim strCaptionOld As String
     Dim bolPrimaryKey As Boolean
     Set db = CurrentDb
     Set dbc = CodeDb
     Set tdf = db.TableDefs(strTable)
     Set rstCaptions = dbc.OpenRecordset("SELECT * FROM tblCaptions", dbOpenDynaset)
     For Each fld In tdf.Fields
         bolPrimaryKey = IsPrimaryKey(tdf, fld)
         strCaption = ""
         On Error Resume Next
         strCaption = fld.Properties("Caption")
         On Error GoTo 0
         If Not Len(strCaption) = 0 Then
             On Error Resume Next
             dbc.Execute "INSERT INTO tblCaptions(Fieldname, Caption, IsPrimaryKey) VALUES(''" & fld.Name & "'', ''" _
                 & strCaption & "'', " & CInt(bolPrimaryKey) & ")", dbFailOnError
             Select Case Err.Number
                 Case 3022
                     rstCaptions.FindFirst ("Fieldname = ''" & fld.Name & "'' AND IsPrimaryKey = " & CInt(bolPrimaryKey))
                     strCaptionOld = rstCaptions!Caption
                     If Not strCaption = strCaptionOld Then
                         If MsgBox("Für das Feld ''" & fld.Name & "'' wurde bereits die Beschriftung ''" & strCaptionOld _
                                 & "'' hinterlegt. Soll die in der Tabelle ''" & strTable & "'' gefundene Beschriftung ''" _
                                 & strCaption & "'' dafür gespeichert werden?", vbYesNo + vbExclamation, _
                                 "Beschriftung bereits vorhanden.") = vbYes Then
                             dbc.Execute "UPDATE tblCaptions SET Caption = ''" & strCaption & "'', IsPrimaryKey = " _
                                 & CInt(bolPrimaryKey) & " WHERE Fieldname = ''" & fld.Name & "''", dbFailOnError
                         End If
                     End If
                 Case 0
                 Case Else
                     MsgBox "Fehler: " & Err.Number & ", " & Err.Description
             End Select
         End If
     Next fld
End Sub 

Sie haben das Ende des frei verfügbaren Textes erreicht. Möchten Sie ...

TestzugangOder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

Schreibe einen Kommentar