Home > Artikel > Ausgabe 1/2013 > Reihenfolge individuell einstellen

Reihenfolge individuell einstellen

Achtung: Sie sind nicht angemeldet. Wenn Sie Abonnent sind und sich anmelden, lesen Sie den kompletten Artikel, laden das PDF herunter oder probieren die Beispieldatenbank aus (sofern vorhanden).

In der Regel sorgen Sortierungen nach dem Inhalt bestimmter Felder für die richtige Reihenfolge bei der Anzeige von Daten. Es gibt jedoch Ausnahmen, bei denen Sie ein individuelles Kriterium für die richtige Sortierung benötigen. Dazu fügen Sie einer Tabelle ein eigenes Feld hinzu und füllen dieses mit entsprechenden Zahlenwerten. Wie aber ändert man die Reihenfolge komfortabel? Die Antwort liefert der vorliegende Artikel.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1301_ReihenfolgeIndividuellEinstellen.mdb.

Individuelle Reihenfolge

Wenn Sie beispielsweise Kunden in einer Kundenliste nach der Beliebtheit sortieren möchten, können Sie diese Sortierung über entsprechende Werte in einem Feld namens ReihenfolgeID vorgeben. Um die Datensätze eindeutig zu sortieren, darf dieses Feld nur eindeutige Werte aufnehmen – also beispielsweise die Zahlen von 1 bis n. Dazu stellen Sie die Eigenschaft Indiziert des Feldes ReihenfolgeID auf den Wert Ja (Ohne Duplikate) ein (siehe Bild 1).

Hinzufügen eines Feldes für die Definition einer individuellen Reihenfolge

Bild 1: Hinzufügen eines Feldes für die Definition einer individuellen Reihenfolge

Nun weisen Sie allen Datensätzen einen der Beliebtheit entsprechenden Zahlenwert zu und sortieren diese nach dem Feld ReihenfolgeID. Das Feld ReihenfolgeID erhält einen numerischen Datentyp und sollte den gleichen Wertebereich wie das Primärschlüsselfeld der Tabelle enthalten. Das ist grundsätzlich die Lösung für eine individuelle Sortierung. Allerdings ist diese nicht besonders komfortabel: Wer will schon manuell die Zahlenwerte für die Reihenfolge von Datensätzen eintragen?

Wenn Sie beispielsweise den zehnten Eintrag einer Liste an die erste Stelle verschieben möchten, legen Sie für das Feld Reihenfolge des zu verschiebenden Datensatzes den Wert 1 ein. Der Datensatz, der bislang den Wert 1 im Feld Reihenfolge enthielt, bekommt die 2, der mit der 2 die 3 und so weiter.

Wenn Sie einen eindeutigen Index für das Feld ReihenfolgeID festgelegt haben, wird es noch komplizierter – Sie müssen dann für das zu verschiebende Element temporär einen neuen Wert festlegen (zum Beispiel 999 oder einfach einen Wert, der um eins größer als der bislang größte Wert ist), dann dem neunten Datensatz den Wert 10, dem achten den Wert 9 und so weiter zuweisen, bevor der zehnte Datensatz den Wert 1 im Feld ReihenfolgeID erhält (siehe Bild 2).

Änderungen im Feld ReihenfolgeID beim Verschieben des zehnten Eintrags an die erste Position

Bild 2: Änderungen im Feld ReihenfolgeID beim Verschieben des zehnten Eintrags an die erste Position

Was aber ist nun der Unterschied zwischen dem Reihenfolge-Feld und anderen Feldern, nach denen Sie Datensätze sortieren – beispielsweise Preis, Gewicht et cetera? Ganz klar: Das Reihenfolge-Feld hat, genau wie in vielen Fällen das Primärschlüsselfeld einer Tabelle, nur eine einzige Aufgabe – und die dient nicht dem Speichern von Geschäftsdaten. Sondern – in diesem Fall – dem Festhalten einer allein vom Benutzer definierten Reihenfolge. Im Gegensatz dazu hat das Primärschlüsselfeld meist einzig und allein die Aufgabe, einen Datensatz eindeutig zu kennzeichnen. Manchmal hat der Primärschlüsselwert auch noch andere Aufgaben und dient beispielsweise als Kundennummer oder Artikelnummer.

Sortieren der Datensätze nach der Reihenfolge

Zum Sortieren der Datensätze nach den Werten des Feldes ReihenfolgeID benötigen Sie eine Abfrage. Diese heißt qryKundenNachReihenfolgeID und enthält zu Beispielzwecken nur einige wenige Felder der als Datenherkunft dienenden Tabelle – darunter natürlich das Feld ReihenfolgeID und, zur fixen eindeutigen Identifizierung, das Feld KundeID. Für das Feld ReihenfolgeID legen Sie die aufsteigende Sortierung fest (siehe Bild 3). Auf diese Weise sortiert die Tabelle das Ergebnis der Abfrage allein nach dem Wert des Feldes ReihenfolgeID.

Abfrage zur Sortierung der Kunden nach dem Wert des Feldes ReihenfolgeID

Bild 3: Abfrage zur Sortierung der Kunden nach dem Wert des Feldes ReihenfolgeID

Reihenfolge komfortabel einstellen

Wie bereits erwähnt, werden Sie die Reihenfolge nicht durch manuelles Anpassen der Werte des Feldes ReihenfolgeID einstellen wollen. Deshalb erstellen Sie nun ein Formular, das die Datensätze der Tabelle tblKunden in einem Listenfeld anzeigt und einige Steuerelemente enthält, um die Position des aktuell markierten Datensatzes anzupassen. Später zeigen wir noch die Anpassung der Reihenfolge für die in einem Unterformular in der Datenblattansicht angezeigten Daten an.

Das Listenfeld im Formular frmReihenfolgeImListenfeld enthält die Abfrage qryKundenNachReihenfolgeID als Datenherkunft. Listenfelder sollen normalerweise nicht die Werte des Primärschlüsselwertes anzeigen, aber in diesem Fall schon – dies erleichtert die Prüfung, ob die nachfolgend hinzugefügten Schaltflächen zum Anpassen der Reihenfolge funktionieren. Geben Sie dazu den Wert 2 für die Eigenschaft Spaltenanzahl und 1cm für die Eigenschaft Spaltenbreiten ein (siehe Bild 4). Dadurch wird die erste Spalte mit einer Breite von einem Zentimeter angezeigt, die zweite Spalte nimmt die restliche Breite ein. Wie ändern wir nun die Reihenfolge? Es gibt mehrere Möglichkeiten. Wenn Sie für andere Benutzer programmieren, sollten Sie eine offensichtliche Variante verwenden – also beispielsweise entsprechende Schaltflächen. Das Betätigen dieser Schaltflächen wirkt sich immer auf den jeweils markierten Datensatz aus. Die Schaltflächen sollen die folgenden Funktionen ermöglichen:

Listenfeld mit den nach dem Feld ReihenfolgeID sortierten Datensätzen in der Entwurfsansicht

Bild 4: Listenfeld mit den nach dem Feld ReihenfolgeID sortierten Datensätzen in der Entwurfsansicht

  • Eintrag um eine Position nach oben verschieben
  • Eintrag um eine Position nach unten verschieben
  • Eintrag ganz nach oben verschieben
  • Eintrag ganz nach unten verschieben

Später soll das Formular wie in Bild 5 aussehen. Unten rechts sehen Sie noch eine Schaltfläche mit einer wichtigen Funktion – dem initialen Festlegen der ReihenfolgeID oder zum Zurücksetzen dieses Feldes.

Formular mit den Schaltflächen zum individuellen Einstellen der Reihenfolge

Bild 5: Formular mit den Schaltflächen zum individuellen Einstellen der Reihenfolge

Eintragen der ReihenfolgeID

Wenn Sie den Daten erst nachträglich das Feld ReihenfolgeID hinzugefügt haben, müssen Sie dieses noch füllen. Dies soll die Schaltfläche cmdZuruecksetzen erledigen, wenn der Benutzer sie anklickt. Dazu legen Sie eine entsprechende Ereignisprozedur an (Schaltfläche markieren, Eigenschaft Beim Klicken auf [Ereignisprozedur] einstellen und auf die Schaltfläche mit den drei Punkten klicken) und ergänzen diese wie folgt:

Private Sub cmdZuruecksetzen_Click()

     ReihenfolgeZuruecksetzen

End Sub

Die durch die einzige Anweisung dieser Prozedur aufgerufene Routine sieht wie in Listing 1 aus. Die Prozedur deklariert ein Database- und ein Recordset-Objekt. Das Database-Objekt db wird mit einem Verweis auf die aktuelle Datenbank gefüllt, rst nimmt ein Recordset mit allen Datensätzen der Abfrage qryKundenNachReihenfolgeID auf. Anschließend durchläuft eine Do While-Schleife alle Datensätze dieses Recordsets. Dabei wird der jeweils aktuelle Datensatz zum Bearbeiten vorbereitet, der Wert des Feldes ReihenfolgeID angepasst und der Datensatz gespeichert. Welchen Wert erhält das Feld ReihenfolgeID? Den Wert der Eigenschaft AbsolutePosition, also der Position des Datensatzzeigers, plus eins – weil AbsolutePosition immer mit 0 beginnt, wir aber eine Nummerierung von 1 beginnend brauchen.

Public Sub ReihenfolgeZuruecksetzen()

     Dim db As DAO.Database

     Dim rst As DAO.Recordset

     Set db = CurrentDb

     Set rst = db.OpenRecordset("SELECT * FROM qryKundenNachReihenfolgeID ORDER BY KundeID", dbOpenDynaset)

     Do While Not rst.EOF

         rst.Edit

         rst!ReihenfolgeID = rst.AbsolutePosition + 1

         rst.Update

         rst.MoveNext

     Loop

     Set db = Nothing

End Sub

Listing 1: Zurücksetzen des Feldes ReihenfolgeID

Datensätze verschieben

Wir schauen uns nun die für die zweite Schaltfläche notwendige Funktion an. Ein Klick auf diese Schaltfläche soll den aktuellen Datensatz um eine Position nach oben verschieben. Dazu führt die Prozedur folgende Schritte durch – bezogen auf Bild 6, wo der Datensatz mit dem Wert 7 im Feld KundeID (ReihenfolgeID ist auch 7) mit dem darüber liegenden Datensatz vertauscht werden soll:

Drei Schritte zum Ändern der Reihenfolge zweier Elemente

Bild 6: Drei Schritte zum Ändern der Reihenfolge zweier Elemente

  • Ermitteln des Primärschlüsselwertes des zu verschiebenden Datensatzes (hier 6 im Feld KundeID)
  • Ermitteln der ReihenfolgeID des zu verschiebenden Datensatzes (ebenfalls 7)
  • Ermitteln der ReihenfolgeID des Zieldatensatzes (6)
  • Ermitteln eines noch nicht verwendeten Wertes für das Feld ReihenfolgeID (hier 108)
  • Einstellen der ReihenfolgeID für den zu verschiebenden Datensatz auf den temporären ReihenfolgeID-Wert (92)
  • Einstellen der ReihenfolgeID des Ziel-Datensatzes auf den ursprünglichen Wert des zu verschiebenden Datensatzes (7)
  • Einstellen der ReihenfolgeID des zu verschiebenden Datensatzes auf die ursprüngliche ReihenfolgeID des Zieldatensatzes (6)
  • Aktualisieren des Listenfeldes

Die erste Frage beim Ändern der Reihenfolge eines Datensatzes lautet: Welcher Datensatz soll überhaupt verschoben werden? Dies ist beim Listenfeld einfach zu beantworten – zumindest, wenn die erste Spalte die Werte des Primärschlüsselfeldes der Datensatzherkunft enthält. Dann liefert die Value-Eigenschaft des Listenfeldes, hier lstKunden, den gewünschten Wert. Diesen prüft man optimalerweise direkt zu Beginn der durch den Mausklick ausgelösten Prozedur und führt die Änderung der Reihenfolge nur durch, wenn auch ein Datensatz markiert ist.

Die Prozedur sieht wie in Listing 2 aus, dort befinden sich alle notwendigen Schritte in einer entsprechenden If...Then-Bedingung, die nur wahr ist, wenn ein Listenfeldeintrag markiert ist.

Private Sub cmdNachOben_Click()

     Dim db As DAO.Database

     Dim lngZielReihenfolgeID As Long

     Dim lngZuVerschiebenID As Long

     Dim lngZuVerschiebenReihenfolgeID As Long

     Dim lngReihenfolgeTemp As Long

     If Not IsNull(Me!lstKunden) Then

         Set db = CurrentDb

         lngZuVerschiebenID = Me!lstKunden

         lngZuVerschiebenReihenfolgeID = DLookup("ReihenfolgeID", "tblKunden", "KundeID = " & lngZuVerschiebenID)

         lngZielReihenfolgeID = DMax("ReihenfolgeID", "tblKunden", "ReihenfolgeID < " & lngZuVerschiebenReihenfolgeID)

         lngReihenfolgeTemp = DMax("ReihenfolgeID", "tblKunden") + 1

         db.Execute "UPDATE tblKunden SET ReihenfolgeID = " & lngReihenfolgeTemp & " WHERE KundeID = " _

             & lngZuVerschiebenID, dbFailOnError

         db.Execute "UPDATE tblKunden SET ReihenfolgeID = " & lngZuVerschiebenReihenfolgeID & " WHERE ReihenfolgeID = " _

             & lngZielReihenfolgeID, dbFailOnError

         db.Execute "UPDATE tblKunden SET ReihenfolgeID = " & lngZielReihenfolgeID & " WHERE KundeID = " _

             & lngZuVerschiebenID, dbFailOnError

         Me!lstKunden.Requery

     End If

End Sub

Listing 2: Verschieben eines Listeneintrags um eine Position nach oben

In diesem Fall speichert die Prozedur zunächst den Wert des Feldes KundeID in der Variablen lngZuVerschiebenID. Danach ermittelt die Prozedur die aktuelle ReihenfolgeID des zu verschiebenden Datensatzes, und zwar mit DLookup. Dieser Aufruf holt den Wert des Feldes ReihenfolgeID für den Datensatz der Tabelle tblKunden mit dem zuvor ermittelten Wert im Feld KundeID. Nun benötigen Sie die ReihenfolgeID des Zieldatensatzes, in diesem Fall der in der Reihenfolge direkt vor dem zu verschiebenden Datensatz liegende. Dazu verwenden Sie die DMax-Funktion, die den größten Wert des Feldes ReihenfolgeID liefert, der kleiner als die ReihenfolgeID des zu verschiebenden Datensatzes ist.

Schließlich fehlt noch ein temporärer ReihenfolgeID-Wert, den Sie dem zu verschiebenden Datensatz zuweisen können, während der Zieldatensatz mit der ReihenfolgeID des zu verschiebenden Datensatzes gefüllt wird. Zur Erinnerung: Das Feld ReihenfolgeID ist mit einem eindeutigen Index ausgestattet, Sie können also nicht einfach dem zu verschiebenden Datensatz die Ziel-ReihenfolgeID zuweisen oder umgekehrt – diese käme dann zweifach vor.

Die temporäre Reihenfolge holt die Prozedur mit der DMax-Funktion, wobei der größte Wert des Feldes ReihenfolgeID in der Tabelle tblKunden eingelesen und um eins erhöht wird.

Nun folgen genau drei UPDATE-Aktionsabfragen. Die erste stellt den Wert des Feldes ReihenfolgeID des zu verschiebenden Datensatzes (mit der Bedingung WHERE KundeID = 7 definiert) auf den temporären Wert ein, in diesem Beispiel 92.

Der vorherige Wert 7 ist nun nicht mehr vergeben. Somit kann die zweite UPDATE-Anweisung diesen dem Feld ReihenfolgeID des Zieldatensatzes zuweisen. Dieser wird über den vorherigen Wert im Feld ReihenfolgeID gekennzeichnet (WHERE ReihenfolgeID = 6).

Schließlich verschiebt die dritte UPDATE-Anweisung den nach hinten geschobene Datensatz an seine Zielposition und ein Aufruf der Requery-Methode des Listenfeldes sorgt für die Aktualisierung der Reihenfolge.

Das gelingt schließlich auch. Der zu verschiebende Datensatz wird mit jedem Klick auf die Schaltfläche Nach oben um einen Datensatz nach oben verschoben. Praktischerweise bleibt dieser im Listenfeld sogar noch markiert, sodass Sie diesen durch mehrfaches Anklicken der Schaltfläche auch um mehrere Positionen nach oben verschieben können.

Einen Datensatz an die erste Position verschieben

Wenn Sie einen Datensatz ganz nach oben verschieben möchten, sollte diese nur einen einzigen Mausklick erfordern. Dazu finden Sie im Formular die Schaltfläche mit der Beschriftung Ganz Nach­ Oben. Welche Schritte sind im Vergleich zum Verschieben des Datensatzes um eine Position erforderlich?

Der zu verschiebende Datensatz erhält wie im vorherigen Beispiel lediglich einen neuen Wert im Feld ReihenfolgeID. Diesen ermittelt die durch einen Mausklick auf die Schaltfläche cmdGanzNachOben ausgelöste Prozedur (siehe Listing 3) diesmal mit dem Aufruf der DMin-Funktion.

Private Sub cmdGanzNachOben_Click()

     Dim db As DAO.Database

     Dim rst As DAO.Recordset

     Dim lngZielReihenfolgeID As Long

     Dim lngZuVerschiebenID As Long

     Dim lngZuVerschiebenReihenfolgeID As Long

     Dim lngReihenfolgeTemp As Long

     If Not IsNull(Me!lstKunden) Then

         Set db = CurrentDb

         lngZuVerschiebenID = Me!lstKunden

         lngZuVerschiebenReihenfolgeID = DLookup("ReihenfolgeID", "tblKunden", "KundeID = " & lngZuVerschiebenID)

         lngZielReihenfolgeID = DMin("ReihenfolgeID", "tblKunden")

         lngReihenfolgeTemp = DMax("ReihenfolgeID", "tblKunden") + 1

         db.Execute "UPDATE tblKunden SET ReihenfolgeID = " & lngReihenfolgeTemp & " WHERE KundeID = " _

             & lngZuVerschiebenID, dbFailOnError

         Set rst = db.OpenRecordset("SELECT KundeID, ReihenfolgeID FROM tblKunden WHERE ReihenfolgeID < " _

             & lngZuVerschiebenReihenfolgeID & " ORDER BY ReihenfolgeID DESC", dbOpenDynaset)

         Do While Not rst.EOF

Sie haben das Ende des frei verfügbaren Teil dieses Artikels erreicht!

Wenn Sie mehr lesen und auf viele weitere Artikel zugreifen möchten, melden Sie sich als Abonnent unter Login an. Falls nicht, bestellen Sie doch einfach ein Jahresabonnement!