In Detailformularen zeigen Sie Datensätze an, bearbeiten oder betrachten diese und schließen dann das Formular oder wechseln zum nächsten Datensatz. In vielen Fällen möchten Sie aber dann vielleicht noch einmal zu einem der zuvor bearbeiteten Datensätze – und gegebenenfalls wieder zurück. Solch eine Funktion bietet Access nicht, dort können Sie über die Navigationsschaltflächen nur durch die Datensätze in der Reihenfolge der Datenherkunft springen. Wir statten in diesem Beitrag ein Formular mit einer Historie aus, wie Sie sie auch vom Internet-Browser kennen.
Im Internet-Browser starten Sie beispielsweise mit einer Google-Suche, finden dann in der Ergebnisliste eine Seite und rufen diese dann auf. Dort fällt Ihnen ein weiterer Links ins Auge, den Sie sich anschauen. Sie entscheiden sich, dass Sie doch wieder zum vorherigen Link zurückwechseln möchten. Bringt dieser nicht das gewünschte Ergebnis, soll es wieder zurück zum Suchergebnis gehen, von wo Sie entweder den nächsten Treffer betrachten oder vielleicht sogar die Seite mit den folgenden Treffern aufrufen.
Wie auch immer dies läuft: Die Vor- und Zurück-Tasten des Browsers nehmen Ihnen hier eine Menge Arbeit ab. Dabei bieten diese die folgenden Möglichkeiten:
- Sie klicken direkt auf die Vor- oder Zurück-Taste, um zur folgenden oder vorherigen Seite zu springen.
- Sie klicken auf die Pfeile und halten die Maustaste gedrückt. Der Internet-Explorer zeigt dann beispielsweise die Titel der zuletzt besuchten Seiten an (s. Bild 1).
- Wenn Sie dort auf den Eintrag Verlauf klicken, können Sie sogar die zuletzt besuchten Seiten inklusive Datum aufrufen (s. Bild 2).
Bild 1: Historie im Internet-Explorer
Bild 2: Anzeige des Verlaufs
Das sind interessante Aussichten – vor allem, wenn man sich vorstellt, dies etwa auf ein Kunden-Formular zu übertragen und mal eben schnell die Kunden zu betrachten, die man zuletzt oder vor zwei Tagen bearbeitet hat.
Also wollen wir uns nun an die Umsetzung dieser nützlichen Funktion für ein Access-Formular machen.
Vorgaben
Zuvor müssen wir noch ein paar Definitionen treffen, die sich auf das Verhalten der Schaltflächen beziehen. Wenn Sie sich nur vorwärts durch die Kunden bewegen, ist es kein Problem – alle bisher besichtigten Kundendatensätze werden dann in der richtigen Reihenfolge in der Liste der zuvor betrachteten Kunden abgelegt.
Was aber geschieht, wenn ich mich vom aktuellen Datensatz zu dem zuvor betrachteten Datensatz bewege und dann einen anderen Datensatz aufrufe als den, von dem ich gerade komme Sprich: Ich schaue mir erst Datensatz A an, dann Datensatz B, gehe zu Datensatz A zurück und rufe dann Datensatz C auf. Im Browser wird dies so gelöst, dass Datensatz B in diesem Fall aus der Reihenfolge verschwindet. Im Verlauf werden alle Seiten angezeigt. Dies wollen wir auch so umsetzen.
Ausgangsformular
Wir beginnen mit einem Formular, das wie in Bild 3 aussieht. Es verwendet die Tabelle tblKunden der Beispieldatenbank als Datenherkunft und zeigt alle Felder im Detailbereich an. Im Formularkopf haben wir ein Kombinationsfeld eingebaut, mit dem der Benutzer direkt zu jedem beliebigen Datensatz springen kann.
Bild 3: Entwurf des Beispielformulars
Das Kombinationsfeld heißt cboAuswahl und soll immer beim Anzeigen eines Datensatzes direkt mit dem Datensatz gefüllt werden, der auch im Formular erscheint. Dazu müssen wir zunächst die Datensatzherkunft des Kombinationsfeldes auf die folgende Abfrage einstellen:
SELECT tblKunden.KundeID, tblKunden.Firma FROM tblKunden ORDER BY tblKunden.Firma;
Damit das Kombinationsfeld nur den Inhalt des Feldes Firma anzeigt, aber nicht den des Feldes KundeID, stellen Sie die Eigenschaften Spaltenanzahl auf 2 und Spaltenbreiten auf 0cm ein. Um das Kombinationsfeld beim Auswählen eines Datensatzes über die übrigen Elemente des Formulars wie etwa die Navigationsschaltflächen mit dem Da-tensatz des Formulars zu synchronisieren, legen Sie die folgende Ereignispro-zedur an:
Private Sub Form_Current() Me!cboAuswahl = Me!KundeID End Sub
Diese wird durch das Ereignis Beim Anzeigen des Formulars ausgelöst.
Nun müssen wir noch dafür sorgen, dass das Formular auch nach der Auswahl eines Eintrags im Kombinationsfeld gleich den passenden Datensatz anzeigt. Dies erledigt die folgende Ereignisprozedur, die durch das Ereignis Nach Aktualisierung des Kombinationsfeldes ausgelöst wird:
Private Sub cboAuswahl_AfterUpdate() Me.Recordset.FindFirst "KundeID = " & Me!cboAuswahl End Sub
Vor-und-Zurück-Schaltfläche
Wenn dies alles funktioniert, können wir uns der Erweiterung zuwenden. Dazu fügen Sie neben dem Kombinationsfeld zwei Schaltflächen hinzu, die Sie mit dem Kleiner- und dem Größer-Zeichen als Beschriftung ausstatten. Die Schaltflächen sollen cmdVor und cmdZurueck heißen und jeweils eine eigene Ereignisprozedur beim Anklicken auslösen.
Mit den Schaltflächen sieht der Formularkopf nun wie in Bild 4 aus.
Bild 4: Kombinationsfeld zur Auswahl von Kunden-Datensätzen. Rechts die Schaltflächen zum Vor- und Zurückblättern
Verlauf speichern
Bevor wir uns an die Programmierung der Funktion für die Schaltflächen begeben, müssen wir erst einmal eine Möglichkeit schaffen, die zuletzt besuchten Datensätze zu speichern. Dies wird ohne Zweifel eine Tabelle sein, da die Daten ja auch nach dem Schließen und erneutem öffnen zur Verfügung stehen sollen. Aber welche Felder benötigen wir in dieser Tabelle Die erste Frage, die sich stellt, ist die nach dem Primärschlüsselfeld.
Benötigen wir ein eigenes Primärschlüsselfeld, wenn wir doch wahrscheinlich in einem Feld der Tabelle den Wert des Primärschlüsselfeldes der Tabelle tblKunden speichern – also der Tabelle, für die wir die Zugriffe speichern möchten Man könnte es tun, wenn man dieses Primärschlüsselfeld zur Sortierung verwenden möchte.
Was aber ist, wenn man erst den Kunden A aufruft, dann Kunde B und Kunde C und schließlich wieder zu Kunde A zurückspringt Kunde A kann dann, wenn der Verlauf tatsächlich in chronologischer Reihenfolge dargestellt werden soll, nicht mehr über den Primärschlüsselwert an die richtige Position gebracht werden, da diese ja nicht geändert werden kann.
Also vergeben wir keinen eigenen Autowert-Primärschlüssel für die Tabelle, sondern übernehmen einfach den Primärschlüssel aus der Kundentabelle als eindeutiges Merkmal für die angezeigten Datensätze. Diesen benötigen wir dann später auch, um einen der Kundendatensätze aus der Verlaufsliste heraus aufrufen zu können.
Wie aber sortieren wir die Datensätze dann in chronologischer Reihenfolge, und wie bringen wir diese in Ordnung, wenn der Benutzer einen bereits im Verlauf befindlichen Kunden nochmals aufruft Zu diesem Zweck fügen wir der Tabelle ein Feld namens Zugriffszeit hinzu. Diese nimmt Datum und Zeit des letzten Zugriffs auf diesen Datensatz auf.
Auf diese Weise brauchen wir, wenn der Benutzer einen bereits in der Verlaufstabelle befindlichen Datensatz erneut aufruft, auch nur eine kleine änderung an diesem Datensatz vorzunehmen – nämlich den Wert im Feld Zugriffszeit zu aktualisieren.
Wenn wir die Anzeige der Verlaufsliste dann absteigend nach dem Inhalt des Feldes Zugriffszeit sortieren, liefert diese immer die zuletzt verwendeten Datensätze zuerst.
Die Tabelle zum Speichern des Verlaufs soll tblVerlauf heißen und nimmt aktuell die Felder auf, die auch in der Entwurfsansicht in Bild 5 zu erkennen sind.
Bild 5: Diese Tabelle speichert den Verlauf der zuletzt aufgerufenen Kunden.
Noch nicht gesprochen haben wir über das letzte Feld dieser Tabelle namens PopuplisteID. Wir wollen ja wie im Internet Explorer sowohl eine Verlaufsliste mit der kompletten Historie der zuletzt aufgerufenen Kunden darstellen, aber auch Ziele für die beiden Schaltflächen zum Anspringen des vorherigen und des nächsten Datensatzes speichern und diese auch in einem Popup-Listenfeld anzeigen. Letztere sollen allerdings nach dem Schließen des Formulars gelöscht und nach dem erneuten öffnen und Auswählen von Datensätzen wieder gefüllt werden.
Für diese Liste wollen wir jeweils maximal sieben Einträge speichern. Wenn der Benutzer Kunde 1 auswählt, erhält Kunde 1 in diesem Feld den Wert 0. Wählt der Benutzer dann Kunde 2 aus, erhält Kunde 1 den Wert -1 und Kunde 2 den Wert 0. Folgt dann Kunde 3, erhält Kunde 1 den Wert -2, Kunde 2 erhält den Wert -1 und Kunde 3 den Wert 0. Springt der Benutzer dann zu Kunde 2 zurück, erhält Kunde 1 den Wert -1, Kunde 2 den Wert 0 und Kunde 3 den Wert 1 im Feld PopuplisteID.
Der aktuelle Kunde erhält also immer den Wert 0, die Liste wird immer in Richtung der positiven Zahlen erweitert. Was aber geschieht, wenn der Benutzer nun vom aktuellen Kunden (Nummer 0) aus zum vorherigen Kunden springen kann (-1) und zum folgenden (1), aber einen neuen Kunden auswählt
In diesem Fall wird der Pfad in Richtung positiver Zahlen gelöscht, der neue Kunde mit der Zahl 0 und die übrigen mit -1, -2 und -3 versehen.
Programmierung des Verlaufs
Theoretisch hört sich das alles recht einfach an – in der Praxis ist es allerdings etwas komplizierter als erwartet.
Vor allem solche Details wie das Einblenden der Popupliste nach längerem Drücken der beiden Schaltflächen cmdVorheriger und cmdNaechster sind recht aufwendig zu programmieren.
Die Popupliste
Unter den Schaltflächen cmdVorheriger und cmdNaechster müssen wir noch die Liste unterbringen, die beim längeren Drücken einer der beiden Schaltflächen eingeblendet wird. Dies erledigen wir mit einem Listenfeld namens lstPopupliste, das wir wie in Bild 6 im Formular positionieren.
Bild 6: Die Popupliste realisieren wir in Form eines Listenfeldes, das zunächst unsichtbar ist und nur bei Bedarf eingeblendet wird.
Für dieses Listenfeld legen wir eine Datensatzherkunft namens qryPopupliste an.
Diese sieht im Entwurf wie in Bild 7 aus und liefert alle Datensätze der Tabelle tblVerlauf, deren Feld PopuplisteID nicht leer ist – und zwar in absteigender Reihenfolge nach diesem Feld sortiert.
Bild 7: Dies ist die Datensatzherkunft für die Popupliste.
Popupliste beim Laden zurücksetzen
Wenn das Formular geöffnet wird, soll eine neue Historie der zuletzt verwendeten Datensätze geschaffen werden. Dies betrifft nicht den eigentlichen Verlauf in zeitlicher Abfolge – dieser soll immer erhalten bleiben.
Für die Auswahl eines der seit dem öffnen des Formulars angezeigten Datensätze ist aber auch nur der Inhalt des Feldes PopupListeID der Tabelle tblVerlauf verantwortlich, sodass dieses Feld einfach nur beim Laden des Formulars geleert werden soll.
Dies erledigt die Ereignisprozedur Form_Load, die durch das Ereignis Beim Laden ausgelöst wird:
Private Sub Form_Load() Dim db As DAO.Database Set db = CurrentDb db.Execute "UPDATE tblVerlauf SET PopuplisteID = NULL", dbFailOnError Set db = Nothing End Sub
Speichern des aktuellen Datensatzes
Die erste Aufgabe lautet, überhaupt den aktuellen Datensatz in die Tabelle tblVerlauf einzutragen beziehungsweise die Position für die Anzeige in der Popup-liste der zuletzt verwendeten Datensätze zu speichern. Wann soll dieser überhaupt gespeichert werden Direkt nach dem Anzeigen. Dies erledigen wir am einfachsten mit einer Ereignisprozedur, die durch das Ereignis Beim Anzeigen des Formulars ausgelöst wird.
Diese Prozedur sieht wie in Listing 1 aus und stellt zunächst das Kombinationsfeld cboAuswahl auf den Datensatz ein, der auch im Formular angezeigt wird. Dann ruft sie eine Prozedur namens VerlaufSpeichern auf, welche den Primärschlüsselwert und die Bezeichnung des aktuellen Datensatzes, hier den Wert des Feldes Firma, als Parameter erwartet. Diese Prozedur finden Sie in Listing 2: Sie legt einen neuen Datensatz in der Tabelle tblVerlauf an und trägt dabei den Primärschlüsselwert des Datensatzes (aus dem Parameter lngPKID), den Titel für die Anzeige im Popup-Listenfeld (aus strTitel) sowie Zeit und Datum ein.
Private Sub VerlaufSpeichern(lngPKID As Long, strTitel As String) Dim db As DAO.Database Set db = CurrentDb On Error Resume Next db.Execute "INSERT INTO tblVerlauf(PKID, Titel, Zugriffszeit) VALUES(" _ & lngPKID & ", ''" & Replace(strTitel, "''", "''''") _ & "'', " & ISODatum(Now) & ")", dbFailOnError If Err.Number = 3022 Then db.Execute "UPDATE tblVerlauf SET Zugriffszeit = " & ISODatum(Now) _ & " WHERE PKID = " & lngPKID End If Set db = Nothing End Sub
Listing 1: Speichern des soeben aufgerufenen Datensatzes in der Tabelle tblVerlauf
Sollte bereits ein Datensatz für diesen Kunden vorhanden sein, löst der Versuch, diesen erneut anzulegen, den Fehler 3022 aus. Diesen behandeln wir entsprechend, indem wir einfach dem bereits vorhandenen Datensatz den aktuelle Wert für Datum und Zeit zuweisen. Damit wäre der aktuell ausgewählte Datensatz also zumindest schon in der Tabelle tblVerlauf gespeichert.
Die aufrufende Prozedur Form_Current blendet nun das Listenfeld lstPopupliste aus, da diese ja gegebenenfalls durch vorheriges Drücken einer der beiden Schaltflächen cmdVorheriger oder cmdNaechster eingeblendet worden sein könnte. Dann ruft sie eine weitere Prozedur auf, die sich um das aktualisieren des Feldes PopuplisteID in der Tabelle tblVerlauf kümmert – mehr dazu weiter unten.
Schließlich sollen auch noch, wie beim Internet Explorer, die beiden Schaltflächen cmdVorheriger und cmdNaechster aktiviert oder deaktiviert werden – je nachdem, ob in der Popupliste bereits Einträge stehen, die seit dem öffnen des Formulars vor oder nach dem aktuellen Datensatz angezeigt wurden. Dazu prüft die Prozedur per DLookup-Funktion, ob die Tabelle tblVerlauf mindestens einen Datensatz enthält, dessen Wert im Feld PopuplisteID größer als 0 ist. In diesem Fall blendet sie die Schaltfläche cmdNaechster ein, anderenfalls wird die Schaltfläche ausgeblendet. Gleiches geschieht wenige Zeilen danach mit der Schaltfläche cmdVorheriger.
Popup-Liste aktualisieren
Die Prozedur PopuplisteAktualisieren wird jeweils beim Anzeigen eines Datensatzes im Formular aufgerufen (s. Listing 3). Sie ermittelt zunächst die Anzahl der Einträge, die im Listenfeld lstPopupliste angezeigt werden sollen. Dies sind alle Datensätze der Tabelle tblVerlauf, für die im Feld PopuplisteID zuvor ein Zahlenwert hinterlegt wurde. Wenn das Formular soeben geöffnet wurde, ist dieser Wert 0 – dafür hat die weiter oben beschriebene Prozedur Form_Load gesorgt, die das Feld PopuplisteID für alle Datensätze geleert hat.
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
den kompletten Artikel im PDF-Format mit Beispieldatenbank
diesen und alle anderen Artikel mit dem Jahresabo