CLS: Tipps & Tricks: Access-Formulare



Tipps & Tricks: Access-Formulare

Auf dieser Seite finden Sie 8 Tipps & Tricks für Access-Formulare. Soweit keine Einschränkungen dazu genannt werden, gelten diese Tipps & Tricks für alle Versionen von Access.

Wenn in den folgenden Erläuterungen Texte wie MsgBox formatiert sind, handelt es sich um konkret einzugebende Inhalte wie VBA-Code oder die Eingabe von Werten. Menüs wie Datei Speichern sind wie hier zu sehen formatiert. Schaltflächen oder Registerkarten auf Dialogen werden wie Menüs behandelt.

Alle Tipps sind nach bestem Wissen geprüft, aber selbstverständlich ohne Gewähr. Sollten Sie doch einen Fehler darin entdecken, würden wir uns freuen, wenn Sie uns per eMail Bescheid sagen.

Wenn Sie in einem Formularentwurf ein Kombinationsfeld mit einer Tabelle als Datenquelle einfügen, stellen Sie deren Datensatzherkunft-Eigenschaft auf Feldliste. Dadurch werden im Formular automatisch alle Feldnamen der zugrundeliegenden Tabelle angezeigt. (Siehe dazu auch den Tipp Alle Felder einer Tabelle ermitteln mit VBA)

Der Tipp "Eigene AutoWert-Nummerierung" zeigt, dass beispielsweise die Schrittweise in AutoWert-Feldern nicht änderbar ist. Jedenfalls nicht in Tabellen. Anhand der Dirty-Methode in Formularen können Sie aber zum Zeitpunkt einer Datenänderung feststellen, ob gerade ein neuer Datensatz angelegt wird und dann eine eigene Nummerierung vergeben. Mit einer Tabelle tblPseudo und einem darin enthaltenen Long-Zahlenfeld PseudoID (kein AutoWert!) können Sie im darauf basierenden Formular diesen Code einsetzen:

Private Sub Form_Dirty(Cancel As Integer)
Const cintStep = 10
 
If Me.NewRecord Then
Me.PseudoID.Value = Nz(DMax("PseudoID", "tblPseudo"), 0) + cintStep
End If
End Sub

Der Code muss in das Modul des gewünschten Formulars kopiert werden und gehört dann zu dessen Bei Geändert-Ereignis. Selbstverständlich müssen Sie den Tabellennamen und den Feldnamen an die Datenquelle des Formulars anpassen. In diesem Beispiel wird auf den höchsten bisherigen Wert, der mit der DMax-Funktion ermittelt werden kann, die vorgegebene Schrittfolge addiert und als neuer Wert des aktuellen Datensatzes eingegeben.

Damit nur neue und keine vorhandenen Datensätze (die bei Änderung auch diese Prozedur auslösen!) nummeriert werden, läßt sich die Me.NewRecord-Eigenschaft prüfen. Die Nz()-Funktion sorgt dafür, dass bei einer leeren Tabelle kein NULL-Wert zurückgegeben wird, sondern der Standardwert 0.

Seit Access 2003 gibt es die "Verschlimmbesserung", dass auch zur Laufzeit eines Formulars das Eigenschaften-Fenster sichtbar ist und nicht nur im Entwurf. Das bedeutet nicht nur Ärger, weil nun jede/r Anwender/in in Ihrem Formular herumfummeln kann, sondern auch, weil viele der dort sichtbaren Eigenschaften zur Laufzeit trotzdem nicht änderbar sind.

Als drittletzte (Formular-)Eigenschaft gibt es seitdem Entwurfsänderungen zulassen, welche Sie am besten auf Nur Entwurfsansicht stellen. Damit ist das Eigenschaften-Fenster nur noch im Entwurf sichtbar. Leider lässt sich das nicht generell für neue Formulare vorgeben, Sie müssen es also jedesmal ändern.

Haupt- und Unterformulare sind eine ideale Art, die typischen 1:n-Beziehungen in Access für Benutzer/innen transparent abzubilden. Die Master-("1"er-)Tabelle ist die Datengrundlage für das Hauptformular, ein oder sogar mehrere Unterformulare enthalten die Detail-("n"-)Daten. Es gibt zwar einen Assistenten für die Erstellung von Haupt- und Unterformularen, Sie werden aber sehen, dass es ohne fast noch einfacher ist.

Eine typische Kunden-Datenbank enthält beispielsweise eine Master-Tabelle tblKunden mit dem Primärschlüssel/AutoWert kndID sowie die Detailtabellen tblMitarbeiter (Fremdschlüssel mitkndIDRef), tblAdressen (Fremdschlüssel adrkndIDRef) und tblNotizen (Fremdschlüssel ntzkndIDRef). Diese drei Detailtabellen sind über ihren jeweiligen Fremdschlüssel mit der kndID in tblKunden selbstverständlich über eine 1:n-Beziehung mit referentieller Integrität verknüpft.

Basierend auf tblKunden können Sie nun ein AutoFormular im üblichen einspaltigen Design erstellen und als frmKunden (Haupt) speichern. Auch für tblMitarbeiter benötigen Sie ein Formular, aus optischen Gründen würde ich mit dem Formular-Assistenten ein AutoFormular: Tabellarisch wählen. Dieses speichern Sie (nur wegen der alphabetischen Sortierung im Datenbankfenster) als frmKunden (Unter: Mitarbeiter).

Bis dahin sind es zwei ganz normale und voneinander unabhängige Formulare. Jetzt sollen sie zu Haupt- und Unterformular kombiniert werden:

  • Öffnen Sie frmKunden (Haupt) in der Entwurfsansicht,
  • machen Sie mit F11 das Datenbankfenster sichtbar
  • ziehen Sie den Namen frmKunden (Unter: Mitarbeiter) vom Datenbankfenster in den Entwurf von frmKunden (Haupt).
Jetzt sind Sie fertig und sollten frmKunden (Haupt) auch einmal speichern, denn nur dieses hat sich geändert. Sie können es nun starten und darin über die Navigations-Schaltflächen zwischen den Datensätzen von tblKunden des Hauptformulars wechseln: das eingebettete Unterformular zeigt automatisch synchronisiert immer die passenden Mitarbeiter an.

So lange noch Platz ist, können Sie auch die anderen beiden Tabellen als Unterformulare hinzufügen, deswegen empfiehlt es sich, dies in der Namenswahl für die Unterformulare direkt zu berücksichtigen.

Die im Tipp "Haupt- und Unterformulare (1): Standard" beschriebene Standardversion der Haupt- und Unterformulare hat einen gravierenden Nachteil: sie ist nicht bedienungsfreundlich. Lassen Sie mal "normale" Benutzer/innen damit arbeiten und schauen Sie, was dann passiert:

  • Zwei Navigationsschaltflächen-Elementen irritieren die meisten, vor allem scheint das Anklicken der oberen (inneren) Navigation nichts auszulösen.
  • Internet-geübte Nutzer/innen suchen Kunden nach Google-Manier, also einen neuen Namen im Kundenfeld eintippen und mit Return-Taste bestätigen, damit die Suche startet. Nix passiert? Nun ja, der gesuchte Kunde ist jedenfalls nicht erschienen, aber mit Schließen des Formulars wird auch noch der aktuelle Datensatz überschrieben.
  • Um dieses versehentliche Kaputtschreiben der Kunden-Daten zu verhindern, lassen sich die Steuerelemente im Hauptfenster natürlich deaktivieren. Damit ist aber leider auch die echte Such- und Filterfunktion von Access lahmgelegt, weil diese aktivierte Steuerelemente voraussetzt.
Die Verbesserungen müssen also darin bestehen, die Suche beizubehalten oder zu verbessern und gleichzeitig die versehentliche Zerstörung der Master-Daten zu verhindern.

Dabei bleiben die Unterformulare völlig unverändert, Sie können diese also aus der Standardversion übernehmen. Als frmKunden (Haupt) beginnen Sie allerdings mit einem komplett leeren Formular ohne Datenquelle. Da dieses Formular gar keine Datenbindung hat, lassen sich von ihm aus auch keine Daten verändern.

Trotzdem können Sie darauf Steuerelemente platzieren, die eigene Datenlisten präsentieren: Listenfelder und Kombinationsfelder. Legen Sie ein Kombinationsfeld mit dem Datensatzherkunftstyp Tabelle/Abfrage und der Datensatzherkunft SELECT kndID, kndName FROM tblKunden ORDER BY kndName an. Das kndID-Feld muss als eindeutige Kennung zwar enthalten sein, Sie können es aber mit den Spaltenbreiten 0cm;7cm ausblenden.

Nachdem Sie das/die Unterformulare frmKunden (Unter: ...) in dieses Hauptformular hineingezogen haben, werden Sie enttäuscht feststellen müssen, dass gar keine Synchronisation stattfindet. Access konnte keine Tabellen-Verknüpfung analysieren, denn das Hauptformular selber enthielt ja gar keine Tabelle. Sie müssen also die Einstellungen manuell nachreichen. Dabei geben Sie ein Objekt/Feld des Unterformulars (klar, das ist eines der ...kndIDRef-Felder) ein und ein Objekt/Feld des Hauptformulars an. Bloß: das Hauptformular hat überhaupt keine Felder!

Aber es hat immerhin ein Objekt, welches nach Anklicken immer die kndID der markierten Zeile enthält. Bevor Sie dieses Objekt jedoch benutzen, sollten Sie es erst einmal ordentlich (siehe Tipp "Namenskonventionen (2): Ungarische Notation") benennen, statt Kombinationsfeld99 wäre cmbKunden besser.

Jetzt tragen Sie diese beiden Informationen nach, nämlich in den Eigenschaften des Unterformulars als Verknüpfen von mitkndIDRef (oder entsprechend für die anderen Unterformulare) und Verknüpfen nach cmbKunden. Damit funktioniert auch die automatische Synchronisation in diesem verbesserten Haupt- und Unterformular. Als Suchfunktion können Ihre Benutzer/innen ohne Bedenken Werte im Kombinationsfeld auswählen oder sogar eintragen. Das ist nicht nur intuitiv, sondern eben auch völlig ungefährlich.

Nichts spricht übrigens dagegen, die Kunden-Daten von hier aus wieder bewußt änderbar zu machen, nachdem die versehentliche Änderung nun ausgeschaltet wurde. Erzeugen Sie dazu ein weiteres tabellarisches Unterformular, diesmal mit tblKunden als Datenquelle. Importieren Sie dieses Unterformular dann wie die übrigen in das Hauptformular. Als Verknüpfen von-Eigenschaft steht dort kndID, für Verknüpfen nach wie bei allen anderen auch cmbKunden.

Gelegentlich brauchen Sie in Datenbanken für die Daten-Anzeige besonders viel Flexibilität. Wenn Sie so extrem viele Datenquellen anzeigen müssen, dass Sie nicht mehr für jede Tabelle oder Abfrage noch ein eigenes Formular vorbereiten wollen, geht das über einen Trick.

Dazu benötigen Sie ein einfaches Formular als Hauptformular, welches auch ohne Datenquelle sein kann. Darauf legen Sie ein Kombinationsfeld cmbWechsel und ein Unterformular-Control ufmWechsel. Für cmbWechsel stellen Sie als Herkunftstyp die Wertliste und als Datensatzherkunft eine Angabe wie 1;2;3;4;5;6 ein. Sein Beim Klicken-Ereignis erhält dann folgenden Code:

Private Sub cmbWechsel_Click()
Select Case cmbWechsel.Value
Case 1: Me.ufmWechsel.SourceObject = "Tabelle.tblKunden"
Case 2: Me.ufmWechsel.SourceObject = "Tabelle.tblArtikel"
Case 3: Me.ufmWechsel.SourceObject = "Abfrage.qryKundenJahresumsatz"
Case 4: Me.ufmWechsel.SourceObject = "Abfrage.qryKundenMitVerkauf"
Case 5: Me.ufmWechsel.SourceObject = "Abfrage.qryMonatsumsaetze"
Case 6: Me.ufmWechsel.SourceObject = "frmKundenStammdaten"
Case Else: Me.ufmWechsel.SourceObject = ""
End Select
End Sub

Die Zuweisung eines neuen SourceObjectes ist dabei nicht so originell, sondern dessen Beschreibung. Normalerweise steht dort der Name eines Formulars wie im Fall 6. Sobald Sie aber mit Tabelle. oder Abfrage. davor den anderen Typ nennen, können Sie dort auch direkt Tabellen und Abfragen anzeigen lassen. Diese erscheinen automatisch in ihrer Datenblattansicht mit allen Feldern.

Vor allem bei der Nutzung mehrerer Unterformulare (siehe Tipp "Haupt- und Unterformulare (2): verbessert") in einem Hauptformular haben Sie sehr schnell Platzprobleme. Diese lassen sich mit Register-Steuerelementen beseitigen.

Wenn Sie neue Kontrollelemente aus der Toolbox in ein Register einfügen, färbt sich dieses vorübergehend dunkelgrau, um anzuzeigen, dass das Element in die jeweilige Seite aufgenommen wurde. Schon vorhandene Objekte auf dem Formular dürfen Sie jedoch nicht einfach in ein Register hineinziehen. Sie lägen dann lediglich verdeckt dahinter, aber nicht "in" der Seite.

Löschen Sie ein vorhandenes Objekt stattdessen mit Strg+X in die Zwischenablage, klicken den Seitenreiter an (dessen Anfasser auf der Seite dann sichtbar sind) und fügen dann mit Strg+V wieder ein. Objekte, die korrekt "in" der Seite liegen, werden auch schon im Entwurf beim Wechsel zu einer anderen Seite ausgeblendet. Damit können Sie einzelne Objekte größer anordnen, die dann nacheinander nutzbar sind, anstatt alle gleichzeitig auf einem Bildschirm anzuzeigen.

Eine neue Seite auf dem Register legen Sie an, indem Sie rechts oben im Register (neben den Reitern) per Rechtsklick den entsprechenden Menüeintrag auswählen. Die Schriftgröße für das Register lässt sich nicht für einzelne Seiten, sondern nur einheitlich einstellen.

Es gibt noch eine Version des Register-Steuerelements (siehe Tipp "Platz schaffen mit Registern (1): tatsächlich"), die nur so tut als ob. Dazu ändern Sie seine Hintergrundart-Eigenschaft auf Transparent, dann dienen die Reiter nur noch zum Umschalten, es liegen aber keine Steuerelemente mehr in den Seiten.

Im Beispiel der Unterformulare (siehe Tipp "Haupt- und Unterformulare (2): verbessert") ziehen Sie nur noch ein einziges Unterformular hinter das Register und benennen es als subDetails. Der Inhalt des Unterformulars wird dann nur noch per VBA je nach ausgewähltem Reiter angepaßt. Schreiben Sie nun folgenden Code für das Register-Steuerelement mpgDetails:

Private Sub mpgDetails_Change()
If Me.Visible Then   'sonst Fehler beim Laden des Formulars
subDetails.LinkChildFields = ""
End If
 
Select Case mpgDetails.Value
Case 0
subDetails.SourceObject = "frmKunden (Unter: Mitarbeiter)"
subDetails.LinkChildFields = "mitkndIDRef"
Case 1
subDetails.SourceObject = "frmKunden (Unter: Notizen)" subDetails.LinkChildFields = "ntzkndIDRef"
Case 2
subDetails.SourceObject = "frmKunden (Unter: Kunden)" subDetails.LinkChildFields = "kndID"
Case Else
subDetails.SourceObject = ""
End Select
End Sub

Damit wird je nach ausgewählter Seite des Registersteuerelements das Unterformular mit den entsprechenden Daten geladen. Da sich die Verknüpfen von-Eigenschaft (LinkChildFields) je nach Datenquelle ändert, muss auch diese mit angepaßt werden, eigentlich sogar gleichzeitig mit dem SourceObject, weil dieses sofort aktualisiert wird. Daher wird vor der Aktualisierung LinkChildFields gelöscht und damit die Synchronisation aufgehoben und erst nach Wechsel zur neuen Datenquelle wieder gesetzt.

Da beim Öffnen des Hauptformulars nun nur noch die Daten eines einzigen Unterformulars geladen werden müssen, kann diese Technik die Anzeige erheblich beschleunigen. Außerdem ist das Layout einfacher, weil "alle" Unterformulare zwangsläufig an gleicher Position und in gleicher Größe erscheinen.