Zuletzt verwendete Datensätze per Listenfeld

Eine sehr praktische Funktion findet sich in den Office-Anwendungen und auch in vielen anderen Produkten. Wo auch immer Dateien verwendet werden, finden Sie beim Öffnen der jeweiligen Anwendung eine Liste der zuletzt verwendeten Dateien vor. Warum sollte man dies nicht auch in einer Access-Datenbank nutzen, um die zuletzt angezeigten Datensätze in Formularen zur Auswahl anzubieten Wenn Sie zum Beispiel eine Bestellverwaltung nutzen, könnte es sehr sinnvoll sein, die zuletzt angezeigten oder bearbeiteten Kunden in einer Schnellauswahl zum erneuten Aufrufen vorzufinden. Wie das gelingt und welche Erweiterungen dazu notwendig sind, zeigt der vorliegende Beitrag.

Feature wie unter Office

Wenn Sie mit Anwendungen wie Word, Excel oder Access arbeiten, kennen Sie die Anzeige der zuletzt verwendeten Dateien, die beim Starten der Anwendung über die jeweilige Verknüpfung erscheint.

Hier wählen Sie immer aus den zuletzt verwendeten Dateien aus oder alternativ aus einer Liste von angehefteten Dateien, die unabhängig davon, wann sie zuletzt benutzt wurden, angezeigt werden sollen.

Vorbereitungen

Wir wollen zunächst nur den ersten Teil auch für die Datensätze einer Tabelle realisieren, in diesem Fall für die Kunden einer Bestellverwaltung.

Wir nutzen dazu wieder die Tabellen der Beispieldatenbank Südsturm, wobei für uns die Tabelle tblKunden interessant ist.

Als Basis dient das Formular frmKundenZuletzt, für dessen Eigenschaft Datensatzquelle wir die Tabelle tblKunden angeben.

Aus der Feldliste ziehen wir alle Felder der Tabelle in den Detailbereich des Entwurfs des Formulars (siehe Bild 1).

Dieses Formular wollen wir mit einer Liste der zuletzt verwendeten Kunden ausstatten.

Bild 1: Dieses Formular wollen wir mit einer Liste der zuletzt verwendeten Kunden ausstatten.

Konzept für die Liste zuletzt verwendeter Datensätze

Bevor wir loslegen und dem Formular ein Listenfeld zur Anzeige der zuletzt verwendeten Datensätze hinzufügen, stellen wir ein paar grundlegende Überlegungen an.

Welche Datensätze speichern wir in der Liste der zuletzt verwendeten Datensätze

Die erste Frage, die sich uns stellt, ist folgende: Zu welchen Datensätzen beziehungsweise wann soll ein Datensatz überhaupt gespeichert und in der Liste der zuletzt verwendeten Datensätze angezeigt werden

Es gibt verschiedene Möglichkeiten:

  • Jeder angezeigte Datensatz wird in der Liste gespeichert.
  • Jeder bearbeitete Datensatz wird gespeichert.
  • Jeder gezielt angezeigte Datensatz, beispielsweise durch das Anzeigen von einem Übersichtsformular aus, wird gespeichert.
  • Nur Datensätze, die explizit gespeichert werden sollen – beispielsweise über einen Klick auf eine entsprechende Schaltfläche – werden in die Liste übernommen.

Wir wollen im ersten Entwurf den ersten Ansatz umsetzen und alle Datensätze in der Liste der zuletzt angezeigten Datensätze speichern, die überhaupt im Formular frmKundenZuletzt angezeigt wurden.

Wo sollen die Informationen über die zuletzt verwendeten Datensätze gespeichert werden

Die zweite Frage lautet: Wo wollen wir überhaupt die Information speichern, welche Datensätze der Tabelle tblKunden zuletzt verwendet wurden

Hier gibt es wiederum mindestens zwei Möglichkeiten:

  • In einer eigenen Tabelle, die wir beispielsweise tblKundenZuletzt nennen. Hier speichern wir Informationen wie den Namen und/oder den Primärschlüsselwert des jeweiligen Datensatzes. Die Liste zur Anzeige der zuletzt verwendeten Datensätze kann ihre Daten direkt aus dieser Tabelle beziehen.
  • Direkt in der Tabelle tblKunden. Wir könnten ein eigenes Feld mit dem Datentyp Datum beispielsweise namens ZuletztAngezeigt anlegen, das wir immer aktualisieren, wenn der Datensatz angezeigt wurde. Die Liste soll dann die X zuletzt geöffneten Datensätze anhand dieses Feldes ermitteln.

Hier wählen wir ebenfalls den ersten Ansatz. Dies ist praktikabler, weil wir dann nicht den Entwurf der Tabelle tblKunden anpassen müssen. Gegebenenfalls handelt es sich bei dieser Tabelle um eine per ODBC eingebundene SQL Server-Tabelle und es ist gar nicht möglich, diese Tabelle anzupassen. Außerdem spricht für die Speicherung in einer eigenen Tabelle, dass diese im Frontend gespeichert werden kann und somit die zuletzt verwendeten Datensätze für den jeweiligen Benutzer sichert.

Anlegen der Tabelle zum Speichern der zuletzt angezeigten Datensätze

Die Tabelle wollen wir tblKundenZuletzt nennen. Wir könnten auch den Namen tblZuletztGeoeffnet oder ähnlich verwenden, aber vielleicht wollen wir die gleiche Funktion auch noch für die Artikel hinzufügen – daher ist es sinnvoller, den Namen der betroffenen Elemente direkt im Tabellennamen anzugeben.

Welche Felder soll die Tabelle für die zuletzt angezeigten Datensätze enthalten

Nun wird es interessanter. Wenn es nur um die Anzeige der zuletzt verwendeten Einträge der Tabelle tblKunden geht, könnte man neben dem Primärschlüsselfeld nur noch ein Feld mit der Bezeichnung des jeweiligen Elements, in diesem Falle der Kunden, anlegen. Allerdings wollen Sie den jeweiligen Kunden ja auch über das Listenfeld öffnen, und dazu müssen wir genau wissen, um welchen Datensatz es sich handelt. Also benötigen wir auch noch den Primärschlüsselwert aus der Tabelle tblKunden.

Wenn wir aber den Primärschlüsselwert und auch den Namen des Kunden aus der Tabelle tblKunden in der Tabelle tblKundenZuletzt speichern, laufen wir Gefahr, inkonsistente Daten anzuzeigen. Es kann nämlich sein, dass wir im Formular frmKundenLetzte den Namen eines Kunden ändern, nachdem wir diesen angezeigt haben.

Dem können wir allerdings vorbeugen, indem wir im Formular frmKundenLetzte nicht nur eine Ereignisprozedur anlegen, die beim Anzeigen eines Kunden ausgelöst wird und dessen Daten in der Tabelle tblKundenZuletzt speichert, sondern auch noch eine, die beim Ändern eines Datensatzes ausgelöst wird und den aktuellen Kunden dann in der Tabelle tblKundenZuletzt überschreibt.

Und bei der Gelegenheit sollten wir auch im Hinterkopf behalten, dass der Benutzer ja auch einmal einen Kundendatensatz löschen kann. Dieser soll dann selbstverständlich auch aus der Tabelle tblKundenZuletzt entfernt werden.

Entwurf der Tabelle tblKundenZuletzt

Also gestalten wir die Tabelle tblKundenZuletzt wie in Bild 2. Neben dem Primärschlüsselfeld legen wir ein Feld an, das den gleichen Namen erhält wie das Feld, aus dem die in der Liste der zuletzt geöffneten Einträge anzuzeigenden Werte stammen. Für das Feld KundeID, welches den Primärschlüsselwert der anzuzeigenden Einträge aus der Tabelle tblKunden aufnehmen soll, legen wir einen eindeutigen Index fest. Dieser sorgt dafür, dass jeder Datensatz der Tabelle tblKunden nur einmal in der Tabelle tblKundenZuletzt referenziert werden kann. Später nutzen wir das Auslösen eines Fehlers beim Hinzufügen eines Datensatzes mit einem bereits vorhandenem Wert in diesem Feld für unsere Zwecke – mehr dazu weiter unten.

Entwurf der Tabelle tblKundenZuletzt

Bild 2: Entwurf der Tabelle tblKundenZuletzt

Benötigen wir kein Feld in tblKundenZuletzt, das die Reihenfolge angibt

Wir könnten die Funktion mit noch mehr Features ausstatten und beispielsweise die Zeit anzeigen, wann der Datensatz zuletzt aufgerufen wurde. Fürs erste reicht es uns jedoch, einfach nur die zuletzt verwendeten Kunden so anzuzeigen, dass der zuletzt verwendete Kunde ganz oben erscheint. Benötigen wir dazu ein spezielles Feld Nein, wir können dazu das Primärschlüsselfeld KundeZuletztID nutzen und einfach in absteigender Reihenfolge nach dem Inhalt dieses Feldes sortieren.

Prozedur erstellen, die den aktuellen Kunden zur Tabelle hinzufügt

Nachdem wir diese Tabelle erstellt haben, wollen wir dem Formular frmKundeZuletzt zuerst einmal eine Ereignisprozedur hinzufügen, die bei Anzeigen eines Kunden ausgelöst wird und welche die Daten für diesen Kunden in der Tabelle tblKundenZuletzt speichert. Erst danach fügen wir das Listenfeld mit den Daten der Tabelle tblKundenZuletzt hinzu.

Das passende Ereignis für unsere Zwecke heißt Beim Anzeigen. Es wird sowohl beim Anzeigen des ersten Datensatzes beim Öffnen des Formulars als auch beim Wechseln zu einem anderen Datensatz ausgelöst.

Diese Prozedur füllen wir mit dem Code aus Listing 1. Die Prozedur prüft zuerst, ob KundeID nicht den Wert Null hat, was der Fall ist, wenn der Datensatzzeiger auf einen neuen, leeren Datensatz verschoben wird. Diesen Fall müssten wir später berücksichtigen, wenn wir uns um das Speichern beim Ändern eines Datensatzes kümmern.

Private Sub Form_Current()
     Dim db As DAO.Database
     Dim strINSERT As String
     Dim strDELETE As String
     If Not IsNull(Me!KundeID) Then
         Set db = CurrentDb
         On Error Resume Next
         strINSERT = "INSERT INTO tblKundenZuletzt(Firma, KundeID) VALUES(''" & Replace(Me!Firma, "''", "''''") & "'', " _
             & Me!KundeID & ")"
         db.Execute strINSERT, dbFailOnError
         Select Case Err.Number
             Case Is = 3022
                 strDELETE = "DELETE FROM tblKundenZuletzt WHERE KundeID = " & Me!KundeID
                 db.Execute strDELETE, dbFailOnError
                 db.Execute strINSERT, dbFailOnError
             Case 0
             Case Else
                 MsgBox "Fehler " & Err.Number & vbCrLf & vbCrLf & Err.Description
         End Select
     End If
End Sub

Listing 1: Prozedur zum Speichern der Daten für den aktuellen Datensatz in der Tabelle tblKundenZuletzt

Danach deaktivieren wir die eingebaute Fehlerbehandlung mit On Error Resume Next. Das ist nötig, damit wir versuchen können, den Datensatz mit dem entsprechenden Wert im Feld KundeID zur Tabelle tblKundenZuletzt hinzuzufügen. Ist bereits ein Datensatz mit diesem Wert für das Feld KundeID vorhanden, wird nämlich der Fehler mit der Nummer 3022 ausgelöst. In diesem Fall wollen wir den vorhandenen Datensatz mit dem Wert aus KundeID aus der Tabelle tblKundenZuletzt löschen und diesen erneut anlegen. Warum belassen wir diesen dann nicht einfach in der Tabelle Weil der Datensatz nun der zuletzt verwendeten Datensatz ist und da wir absteigend nach dem Inhalt des Feldes KundeZuletztID sortieren, müssen wir den Datensatz löschen und wieder anlegen, um dieses entsprechend zu aktualisieren.

In dem Fall, dass der Kunde noch nicht in der Liste enthalten ist, fügen wir diesen einfach mit der Anweisung aus strINSERT zur Tabelle tblKundenZuletzt hinzu. Für einen Beispieldatensatz sieht diese Anweisung etwa wie folgt aus:

INSERT INTO tblKundenZuletzt(Firma, KundeID) VALUES(''Centro comercial Moctezuma'', 13)

Falls tatsächlich der Fehler 3022 auftritt, den wir in einer Select Case-Bedingung über den Wert von Err.Number prüfen, stellen wir eine DELETE-Anweisung zusammen, um den betroffenen Datensatz zu löschen und diesen anschließend mit der Anweisung aus strINSERT erneut anzulegen. Die DELETE-Anweisung sieht für diese Fall wie folgt aus:

DELETE FROM tblKundenZuletzt WHERE KundeID = 13

Die Select Case-Bedingung enthält noch zwei weitere Zweige. Der mit dem Wert 0 ist für einen fehlerfreien Aufruf der INSERT INTO-Anweisung vorgesehen und erledigt nichts. Der Else-Zweig zeigt für alle anderen Fehler eine entsprechende Meldung an. Nachdem wir in die Formularansicht gewechselt sind und einige Datensätze durchlaufen haben – inklusive eines Sprungs zum Datensatz mit der Nummer 6 am Ende – sieht die Tabelle tblKundenZuletzt wie in Bild 3 aus.

Einige zur Tabelle tblKundenZuletzt hinzugefügte Datensätze

Bild 3: Einige zur Tabelle tblKundenZuletzt hinzugefügte Datensätze

Zuletzt verwendete Datensätze in Listenfeld anzeigen

Nun fügen wir dem Formular frmKundenZuletzt auf der linken Seite ein Listenfeld namens lstKundenZuletzt hinzu. Zuvor verschieben wir die Textfelder des Formulars weiter nach rechts, damit genug Platz für das Listenfeld vorhanden ist. Das Ergebnis sehen Sie in Bild 4.

Entwurf des Formulars frmKundenZuletzt mit Listenfeld

Bild 4: Entwurf des Formulars frmKundenZuletzt mit Listenfeld

Das Listenfeld füllen wir über die Eigenschaft Datensatzherkunft mit einer Abfrage, die auf der Tabelle tblKundenZuletzt basiert. Warum benötigen wir dazu eine Abfrage Weil wir die Datensätze absteigend nach dem Primärschlüsselfeld KundeZuletztID sortieren wollen. Die Abfrage sieht in der Entwurfsansicht wie in Bild 5 aus.

Abfrage mit den Daten für das Listenfeld lstKundenZuletzt

Bild 5: Abfrage mit den Daten für das Listenfeld lstKundenZuletzt

Sie enthält alle Felder der Tabelle tblKundenZuletzt und sortiert die Datensätze absteigend nach dem Feld KundeZuletztID. Das Feld KundeZuletztID benötigen wir allerdings nur zum Sortieren, aber nicht für die Anzeige im Listenfeld. Also blenden wir es durch Entfernen des Hakens im Feld Anzeigen aus. Außerdem wollen wir das Feld KundeID als erstes Feld zurückliefern und als zweites das Feld Firma. Warum, erläutern wir gleich im Anschluss.

Definition der Anzeige im Listenfeld

Die Abfrage liefert die beiden Felder KundeID und Firma zurück. Wir möchten aber nur das Feld Firma anzeigen. Das Feld KundeID möchten wir als gebundenes Feld nutzen. Deshalb stellen wir die Eigenschaft Spaltenanzahl auf 2 und die Eigenschaft Spaltenbreiten auf 0cm ein (siehe Bild 6).

Einstellungen für die Spalten im Listenfeld

Bild 6: Einstellungen für die Spalten im Listenfeld

Dadurch wird die erste Spalte praktisch ausgeblendet und nur die zweite Spalte angezeigt. Das Ergebnis sehen Sie in Bild 7.

Die Anzeige der zuletzt geöffneten Datensätze

Bild 7: Die Anzeige der zuletzt geöffneten Datensätze

Hier sehen wir allerdings ein kleines Problem: Der erste Datensatz im Listenfeld erscheint gleich als #Gelöscht. Der Effekt tritt auf, weil dieser Datensatz derjenige ist, der gerade oben stand und auch als erster angezeigt wird. Diese Aktualisierung erledigt Access im Gegensatz zu den anderen, wie das Neuanlegen dieses Datensatzes, automatisch. Also fügen wir der Beim Anzeigen-Prozedur noch eine Zeile hinzu, die das Listenfeld aktualisiert:

Private Sub Form_Current()
     ...
     If Not IsNull(Me!KundeID) Then
         ...
         Me!lstKundenZuletzt.Requery
     End If
End Sub

Damit können Sie nun durch die Datensätze navigieren und das Listenfeld nimmt immer den aktuellen Datensatz als ersten Datensatz in die Liste auf.

Den aktuellen Datensatz sofort anzeigen

Hier stellt sich die Frage, ob der aktuelle Datensatz immer gleich beim Anzeigen im Formular auch an die erste Stelle in die Liste der zuletzt angezeigten Datensätze aufgenommen werden soll. Immerhin wird er ja gerade erst im Formular angezeigt, warum sollte man ihn dann direkt als ersten Datensatz in der Liste anzeigen

Also prüfen wir, ob wir das auch so umsetzen können, dass der Datensatz immer erst beim Anzeigen des nächsten Datensatzes in die Liste aufgenommen werden kann. Das gelingt zumindest nicht so einfach, denn im Gegensatz zu Beim Anzeigen gibt es kein Ereignis, dass beim Ausblenden eines Datensatzes ausgelöst wird.

Wir müssten uns also überlegen, welches Ereignis wir stattdessen nutzen können. Wir könnten zum Beispiel den Primärschlüsselwert des aktuellen Datensatzes in einer Variablen speichern und diesen dann beim nächsten Aufruf von Beim Anzeigen als neuen zuletzt aufgerufenen Datensatz speichern.

Das misslingt aber, wenn das Formular geschlossen wird, da dann kein weiterer Datensatz mehr angezeigt wird, und spätestens wenn man zwischendurch die Anwendung schließt, wird es aufwendig.

Aber es gibt eine einfachere Lösung: Wir zeigen einfach alle Einträge der Tabelle mit Ausnahme des zuletzt hinzugefügten Eintrags an! Das ist immer der aktuell sichtbare Eintrag, den wir einfach als Kriterium über die als Datensatzherkunft verwendete Abfrage ausschließen.

Um dies zu erreichen, brauchen wir nur das Kriterium aus Bild 8 zum Formular hinzuzufügen. Dieses referenziert das Feld KundeID des aktuell im Formular frmKundenZuletzt angezeigten Datensatzes.

Anpassen der Datensatzherkunft des Listenfeldes so, dass es den aktuell angezeigten Datensatz nicht enthält.

Bild 8: Anpassen der Datensatzherkunft des Listenfeldes so, dass es den aktuell angezeigten Datensatz nicht enthält.

Einen der zuletzt angezeigten Datensätze aufrufen

Ein passendes Ereignis, um einen der Datensätze aus dem Listenfeld lstKundenZuletzt im Formular anzuzeigen, ist das Beim Doppelklicken-Ereignis. Für dieses hinterlegen wir die folgende Ereignisprozedur:

Private Sub lstKundenZuletzt_DblClick(Cancel As Integer)
     Dim strWhere As String
     If Not IsNull(Me!lstKundenZuletzt) Then
         strWhere = "KundeID = " & Me!lstKundenZuletzt
         Me.Recordset.FindFirst strWhere
     End If
End Sub

Die Prozedur prüft zuerst, ob der aktuelle Wert im Listenfeld nicht Null ist. In diesem Fall soll nichts geschehen. Anderenfalls stellt die Prozedur eine Where-Bedingung zusammen, die anschließend der FindFirst-Methode des Recordset-Objekts des Formulars übergeben wird.

Diese sieht beispielsweise wie folgt aus:

KundeID = 10

Das Formular zeigt anschließend genau diesen Kunden an. Die vorher beschriebene Prozedur für das Ereignis Beim Anzeigen sowie die Anpassung der Abfrage, die wir als Datensatzquelle für das Formular verwenden, sorgen dann dafür, dass der so aufgerufene Datensatz nicht in der Liste angezeigt wir.

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

Schreibe einen Kommentar