Selektive Datensätze – oder wie zeige ich Datensätze seitenweise an
Eine bekannte Problematik ist, wie man viele Datensätze so anzeigt, dass immer nur eine bestimmte Anzahl sichtbar wird, gleichzeitig aber Seitenartig geblättert werden kann.
Aus der PHP/MySQL Welt ist die Möglichkeit bekannt in einer Abfrage die Datensätze mittels dem Limit Operator die Anzahl und die Startposition der Datensätze einzustellen. Diese Möglichkeit gibt es in Access leider nicht – man kann sich aber behelfen.
Möchte man z.B. die sortierten Datensätze 31 bis 40 darstellen, lässt sich das dadurch bewerkstelligen, indem man die Top 40 Datensätze nimmt, und von diesen in umgekehrter Reihenfolge die Top 10 Datensätze nimmt. Jetzt hat man die Datensätze 40……bis 31 in umgekehrter Reihenfolge. Auf diese Menge wendet man eine äußere Abfrage an die absteigend aufsteigend sortiert und schon hat man die richtige Ergebnismenge in der korrekten Reihenfolge.
In meinem Beispiel verwende ich ein Unterformular in Datenblattansicht, 4 Buttons zur Navigation und 1 Bezeichnungsfeld als Datensatzanzeiger. Es werden immer 10 Einträge pro Seite angezeigt.
Zuerst werden in einem Modul Globale Variablen deklariert:
Global sumDS As Long Global start As Long
Dann benötigt man eine Prozedur die die Datenherkunft des Unterformulars einstellt:
Private Sub setQuery(start As Long, Optional perpage As Long = 10) Me!ufo1.Form.RecordSource = "SELECT tblKfzKennzeichen.ID, tblKfzKennzeichen.Kennzeichen, tblKfzKennzeichen.Bezirk " & _ "FROM tblKfzKennzeichen " & _ "WHERE (((tblKfzKennzeichen.ID) In (Select Top " & perpage & " ID From (Select top " & start & " ID From tblKfzKennzeichen) Order By ID Desc))) " & _ "ORDER BY tblKfzKennzeichen.ID;" Me.DSAnzeiger.Caption = "Eintrag " & start - (perpage - 1) & " bis " & start Me!ufo1.Form.Requery End Sub
Im Load-Ereignis des Formulars sind Starteinstellungen zu tätigen:
Private Sub Form_Load() sumDS = DCount("ID", "tblKfzKennzeichen") start = 10 setQuery start End Sub
Die Navigation vor/zurück erfolgt dadurch, indem die Variable start um 10 erhöht bzw. erniedrigt wird. Gleichzeitig muss aber die obere bzw. untere Grenze getestet werden damit kein unterschreiten/überschreiten der Gültigkeitsmenge erfolgt.
Bei der Navigation „zum ersten“ wird einfach start auf den Anfangswert 10 gesetzt. Bei der Navigation „zum letzten“ muss zuerst die Anzahl der auf der letzten Seite anzuzeigenden Einträge ermittelt werden.
Nachfolgend der Code der Navigationsbuttons:
Private Sub erster_Click() start = 10 setQuery start End Sub Private Sub letzter_Click() Dim perpage As Long perpage = (sumDS / 10 - Int(sumDS / 10)) * 10 start = sumDS setQuery start, perpage End Sub Private Sub naechster_Click() start = start + 10 If testBorder("n") Then setQuery start End Sub Private Sub vorheriger_Click() If sumDS - start = 0 Then start = sumDS - (sumDS / 10 - Int(sumDS / 10)) * 10 Else start = start - 10 End If If testBorder("v") Then setQuery start End Sub
Eine kleine Besonderheit ist der Fall wenn die letzte Seite aufgerufen wird und dann zum vorherigen navigiert wird. Ist die Anzahl auf der letzen Seite kleiner als vorgegeben, muss der Startwert um diese Differenz angepasst werden.
Beispiel: 298 Einträge =>Anzeige von 290 bis 298 auf letzter Seite. Der Wert der Variable start beträgt 298, vermindere ich diesen um 10 wäre der vorherige Startwert bei 288 anstatt 290. Daher darf man den startwert nur um 8 Verringern, nicht um 10.
Die Prüfung der Grenzen des Wertebereiches habe ich in eine Funktion ausgelagert:
Private Function testBorder(btn As String) As Boolean Dim strCrit As String strCrit = IIf(btn = "v", start & " < 10", start & " > " & sumDS) If Not Eval(strCrit) Then testBorder = True Else Beep End If End Function
Zuerst wird das Prüfkriterium bestimmt, je nach dem ob die obere oder untere Grenze geprüft wird. Trifft das Prüfkriterium zu, wird ein Beep ausgelöst und es wird False zurückgeliefert.
Wie die komplette Anwendung aussehen könnte zeigt das nachfolgende Bild.
Bis dahin
Andreas Vogt ©2011