Selektive Datensätze – oder wie zeige ich Datensätze seitenweise an

By , 10. Mai 2011

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.

Beispielanwendung

Bis dahin
Andreas Vogt ©2011

Leave a Reply

You must be logged in to post a comment.

OfficeFolders theme by Themocracy