Im Beitrag Reihenfolge manuell anpassen (s. Shortlink 652) haben wir verschiedene Möglichkeiten für das Anpassen der Reihenfolge von Daten nach dem Inhalt eines speziellen ReihenfolgeID-Felds erläutert. Der vorliegende Beitrag setzt noch eins drauf: Er zeigt, wie Sie die Reihenfolge von Datensätzen in der Datenblattansicht eines Formulars per Drag and Drop anpassen können.
“Mit den Techniken aus dem Reihenfolge-Artikel kann ich zwar einfach per Schaltfläche Datensätze in der Datenblattansicht nach oben und unten verschieben, aber noch einfacher wäre das doch per Drag and Drop. Und das ListView-Steuerelement, mit dem dies ginge, kommt für mich nicht infrage, weil die Anwendung im Mehrbenutzerbetrieb laufen soll und man so nur mit viel Aufwand die Anzeige aktueller Daten sicherstellen kann.”
Bild 1 zeigt, was der Leser mit dieser Aussage meint: Er möchte einen Datensatz mit der Maus anklicken und diesen dann bei gedrückter Maustaste an eine andere Position im Datenblatt ziehen, wodurch dieser sich dann ober- oder unterhalb des Zieldatensatzes einordnet – und zwar darüber, wenn der Datensatz nach oben gezogen wird, und darunter, wenn er nach unten gezogen wird.
Bild 1: Drag and Drop in der Datenblattansicht
Hausgemachtes Drag and Drop
Welchen Weg geht man, um dieses von Access in keiner Weise unterstützte Verhalten nachzubilden Eine Internetrecherche war wenig hilfreich: Dort gab es bestenfalls Informationen darüber, wie man per Drag and Drop den Inhalt eines Textfeldes in ein anderes verschiebt, aber nicht viel mehr.
Bevor wir Hirnschmalz investieren, nehmen wir erstmal, was der oben erwähnte Beitrag Reihenfolge manuell anpassen liefert, und bauen das Beispielformular zusammen.
Als Tabelle mit zu sortierenden Daten dient die Tabelle tblPersonen, die lediglich die Felder ID (Primärschlüssel), Vorname, Nachname (beides Textfelder) und ReihenfolgeID (Zahlenfeld) enthält.
Außerdem fügen Sie aus der Beispieldatenbank des oben genannten Beitrags die Abfrage qryOrder und das Modul mdlOrder zu der Datenbank hinzu, die Drag and Drop in der Datenblattansicht ermöglichen soll. Die Abfrage qryOrder passen Sie wie in Bild 2 an, damit sie sich auf die relevanten Felder der Tabelle tblPersonen bezieht und als Grundlage der Routinen des Moduls mdlOrder dienen kann.
Bild 2: Diese Abfrage liefert die Grundlage für das Sortieren der Datensätze.
Das Formular frmDragAndDrop der Beispieldatenbank zu diesem Beitrag statten Sie nicht etwa mit der Tabelle tblPersonen als Datenherkunft aus, sondern mit einer Abfrage, die zwar alle Felder der Tabelle tblPersonen enthält, diese aber in aufsteigender Reihenfolge nach dem Feld ReihenfolgeID sortiert:
SELECT ID, Vorname, Nachname, ReihenfolgeID FROM tblPersonen ORDER BY ReihenfolgeID;
Ereignisreich
Schauen wir nun, was Access so an Einstiegspunkten für Drag and Drop in Formularen und speziell in der Datenblattansicht bietet. Da die Datenblattansicht im Prinzip komplett mit Steuerelementen bedeckt ist, konzentrieren wir uns auf die Ereigniseigenschaften der Steuerelemente. Für den Nachbau der Drag-and-Drop-Funktionalität brauchen wir mindestens zwei Ereignisse, die beim Anklicken und beim Loslassen der linken Maustaste ausgelöst werden. Wahrscheinlich brauchen wir auch noch das Ereignis, das beim Bewegen des Mauszeigers reagiert.
Bestenfalls soll es so laufen: Der Benutzer klickt auf die linke Maustaste, während sich der Mauszeiger auf dem zu verschiebenden Datensatz befindet. Dies löst die Ereignisprozedur Bei Maustaste ab aus und ist ein guter Zeitpunkt, um sich den betroffenen Datensatz zu merken. Dann zieht der Benutzer den Mauszeiger bei gedrückter Maustaste auf den Zieldatensatz und lässt die Maustaste wieder los. Hier tritt das Ereignis Bei Maustaste auf auf den Plan: Eine prima Gelegenheit, um den Datensatz zu ermitteln, auf dem sich der Mauszeiger aktuell befindet.
Zwischendurch kann man noch die Ereignisprozedur bemühen, die durch das Ereignis Bei Mausbewegung ausgelöst wird und, falls die linke Maustaste angeklickt ist, ein alternatives Mauszeigersymbol zur Verdeutlichung des Drag-and-Drop-Vorgangs einblendet.
So weit die Theorie – fangen wir also mit ein paar Fingerübungen an und sorgen dafür, dass der Mauszeiger sich beim Ziehen eines Datensatzes in ein anderes Symbol verwandelt. Diese Funktion soll in einer Routine namens MouseMove untergebracht werden, die von den entsprechenden Ereignisprozeduren aller im Datenblatt enthaltenen Steuerelemente aufgerufen werden kann. Der Aufruf sieht im Beispiel des Textfelds txtID mit dem Steuerelementinhalt ID so aus:
Private Sub txtID_MouseMove(button As Integer, µ Shift As Integer, X As Single, Y As Single) MouseMove button End Sub
Die eigentliche Routine verwendet eine Funktion des Access-Entwicklers Terry Kreft (http://www.mvps.org/access/api/api0044.htm), die als Parameter eine Konstante für das gewünschte Aussehen des Mauszeigers erwartet – und das je nachdem, ob gerade die linke Maustaste gedrückt ist oder nicht. Diese Information liefert die als Parameter übergebene Variable intButton, wobei der Wert 1 für die linke Maustaste, 2 für die rechte und 0 für gar keine gedrückte Maustaste steht:
Private Sub MouseMove(intButton As Integer) If intButton = 1 Then MouseCursor IDC_MouseCursor.HAND Else MouseCursor IDC_MouseCursor.ARROW End If End Sub