Im Listenfeld kann man mit den Einstellungen Mehrfach oder Erweitert auch leicht mehrere Datensätze auswählen. Was aber ist, wenn man diese Funktion in der Datenblattansicht bereitstellen will Klar, anklicken kann man die einzelnen Datensätze, man kann auch mehrere zusammenhängende Datensätze markieren – aber was ist, wenn Sie beispielsweise den ersten, dritten und fünften Datensatz in der Datenblattansicht markieren wollen Dann hilft nur ein spezieller Trick, den wir in diesem Artikel vorstellen.
Beispieldatenbank
Die Beispiele dieses Artikels finden Sie in der Datenbank 1703_SelektionImDatenblatt.accdb.
Datenselektion speichern
Wenn Sie die Daten einer Tabelle in der Datenblattansicht anzeigen, gibt es verschiedene Möglichkeiten, einen oder mehrere Datensätze zu markieren. Die erste Variante ist die Markierung eines einzelnen Datensatzes (siehe links in Bild 1). Hier klicken Sie einfach für den gewünschten Datensatz auf den grauen Bereich links im Datenblatt, also auf den sogenannten Datensatzmarkierer.
Bild 1: Beispiele für die Selektion von Datensätzen im Datenblatt
Die zweite Variante ist, mehrere zusammenhängende Datensätze zu markieren. Dazu markieren Sie zuerst den obersten Datensatz, halten dann die Umschalttaste gedrückt und markieren dann den unteren Datensatz. Das Ergebnis sehen Sie rechts im Bild.
Selektion abfragen
Um den oder die ausgewählten Datensätze abfragen zu können, fügen wir das Formular, das die Daten unserer Beispieltabelle in der Datenblattansicht anzeigt, als Unterformular in ein weiteres Formular ein. Im neuen Hauptformular legen wir dann ein paar Schaltflächen an, mit denen wir die selektierten Datensätze auslesen können (siehe Bild 2). Um einen einzelnen aktuell markierten Datensatz auszulesen, hinterlegen wir die folgende Prozedur für die Ereigniseigenschaft Beim Klicken der Schaltfläche cmdSelektionAusgebenEinzeln:
Bild 2: Formular zum Auswerten der aktuellen Selektion
Private Sub cmdSelektionAusgebenEinzeln_Click() Dim sfm As Form Set sfm = Me!frmKundenSelektieren.Form MsgBox "Selektierte Kunden-ID: " & sfm!KundeID End Sub
Wenn Sie nun bei gedrückter Umschalttaste mehr als einen Eintrag auswählen, liefert das Meldungsfenster die ID des zuerst ausgewählten Kunden. Wenn Sie also zuerst den Eintrag mit dem Wert 7 im Feld Kunde-ID wählen und dann bei gedrückter Umschalttaste den Kunden mit der ID 3 anklicken, zeigt die Meldung den Wert 7 an.
Nun fügen wir eine zweite Schaltfläche hinzu, welche alle markierten Datensätze liefern soll. Hier gibt es nur ein Problem: Wenn wir in der Datenblattansicht einen oder mehrere Datensätze markierten und dann auf eine Schaltfläche klicken, wird die Markierung wieder gelöscht. Wir müssen also die Informationen zur Markierung speichern, bevor wir diese ausgeben. Dazu eignet sich, so dachten wir, am besten eine der Ereignisprozeduren, die beim Selektieren der Einträge im Datenblatt ausgelöst werden.
Allerdings stellte sich heraus, dass es keine einfache Methode gab, auf das Selektieren eines Bereichs von Datensätzen zu reagieren. Was nun Ein Ereignis, dass vor dem Anklicken der Schaltlfäche, aber nach dem Selektieren der Datensätze ausgelöst wird, ist das Beim Verlassen-Ereignis des Unterformular-Steuerelements. Und das trifft sich besonders gut, denn das Unterformular-Steuerelement ist ja ein Steuerelement des Hauptformulars, was bedeutet, dass wir das Ereignis auch gleich im Klassenmodul des Hauptformulars implementieren können.
Anderenfalls hätten wir ein Ereignis des Unterformulars verwenden müssen, was aus folgendem Grund ungünstig ist: Wir wollen ja die aktuelle Selektion des Unterformulars erfassen und möglichst gleich in entsprechenden Variablen im Hauptformular speichern, wo wir dann per Klick auf die Schaltlfäche etwas mit dem markierten Datensätzen erledigen. Mit einem Ereignis im Unterformular hätten wir die gesuchten Werte, welche die Selektion repräsentieren, erst noch irgendwie in das Hauptformular bekommen müssen. Das können wir uns nun sparen.
Welche Eigenschaften benötigen wir, um die Selektion auszuwerten Dabei handelt es sich um die beiden Eigenschaften SelTop und SelLength. Langjährige Leser kennen diese beiden Eigenschaften vermutlich schon vom Textfeld-Steuerelement – dort wurde mit ähnlichen Eigenschaften (SelStart und SelLength) der markierte Text ermittelt. Im Falle der Datenblattansicht liefert SelTop den Index der obersten markierten Spalte und SelLength liefert die Anzahl der selektierten Zeilen. Um diese beiden Werte im Klassenmodul des Hauptformulars speichern zu können, legen wir die folgenden beiden Variablen im Kopf des Moduls an:
Dim intSelHeight As Integer Dim intSelTop As Integer
Damit diese beim Verlassen des Unterformular-Steuerelements gefüllt werden, legen wir für das Ereignis Bei Verlassen dieses Elements die folgende Ereignisprozedur an:
Private Sub frmKundenSelektieren_Exit(Cancel As Integer) intSelHeight = Me!frmKundenSelektieren.Form.SelHeight intSelTop = Me!frmKundenSelektieren.Form.SelTop End Sub
Wenn wir nun auf die Schaltfläche cmdSelektionAusgebenAlle klicken, wollen wir die folgende Ereignisprozedur auslösen:
Private Sub cmdSelektionAusgebenAlle_Click() MsgBox "Erste markierte Zeile: " & intSelTop _ & vbCrLf _ & "Anzahl markierter Zeilen: " & intSelHeight End Sub
Diese gibt dann einfach die Werte der beiden Variablen intSelTop und intSelHeight per Meldungsfenster aus.
Von der Position zum Datensatz
Nun wollen wir allerdings nicht nur auf die jeweiligen Zeilen der Datenblattansicht zugreifen, sondern auch auf die darin enthaltenen Daten. Das erledigen wir, indem wir die Prozedur cmdSelektionAusgebenAlle_Click wie in Listing 1 erweitern. Dazu fügen wir ein Form-, ein Recordset– und eine Integer-Variable hinzu. Die Form-Variable referenziert das Unterformular mit der Datenblattansicht.
Private Sub cmdSelektionAusgebenAlle_Click() Dim sfm As Form Dim rst As dao.Recordset Dim i As Integer Set sfm = Me!frmKundenSelektieren.Form Set rst = sfm.RecordsetClone For i = intSelTop - 1 To intSelTop + intSelHeight - 2 rst.AbsolutePosition = i Debug.Print rst!KundeID Next i End Sub
Listing 1: Ausgeben der Werte des Feldes KundeID für alle selektierten Datensätze des Datenblatts
Das Recordset-Objekt füllen wir mit einem Verweis auf den RecordsetClone des Recordsets des Formulars. Warum RecordsetClone Warum greifen wir nicht direkt auf das Recordset zu Weil wir im Folgenden die markierten Datensätze des Unterformulars durchlaufen wollen, die Position des Datensatzzeigers im Datenblatt aber nicht ändern wollen.
Mit dem RecordsetClone holen wir uns eine Kopie, die wir nach Lust und Laune durchlaufen können, ohne dass es die Darstellung des Datenblatts beeinflusst. Die Prozedur durchläuft dann in einer For…Next-Schleife alle Werte von der ersten bis zur letzten Position bezogen auf die markierten Datensätze. Da SelTop für die oberste Zeile den Wert 1 liefert, müssen wir diesen noch um 1 vermindern, da wir über die Eigenschaft AbsolutePosition auf die im Datenblatt angezeigten Datensätze zugreifen wollen.
Und diese Eigenschaft wiederum erwartet die Position als null-basierten Wert. Nachdem wir die Datensatzzeiger-Position des RecordsetClones auf die richtige Position eingestellt haben, können wir mit rst!KundeID leicht auf den Primärschlüsselwert des aktuellen Eintrags der Markierung zugreifen.
Wir könnten nun noch die Markierung im Unterformular wieder herstellen, allerdings müssten wir dann auch noch den Fokus zurück auf dieses Element verschieben, damit die Markierung wieder sichtbar ist. Dies können wir aber ebenfalls per Code erledigen, indem wir die Prozedur cmdSelektionAusgebenAlle_Click nochmals erweitern:
Private Sub cmdSelektionAusgebenAlle_Click() ... Me.frmKundenSelektieren.SetFocus sfm.SelTop = intSelTop sfm.SelHeight = intSelHeight sfm.SelWidth = 99 End Sub
Wir müssen hier allerdings nicht nur die oberste Position und die Höhe der Markierung einstellen, sondern auch die Breite – sonst wird nur die erste Spalte für die betroffenen Zeilen markiert.
Markierung nicht zusammenhängender Zeilen
Damit haben wir die beiden leichteren Varianten der Markierung im Datenblatt erledigt, nämlich die Markierung eines einzelnen Eintrag und die Markierung mehrerer zusammenhängender Einträge. Dies wird nicht mit eingebauten Mitteln möglich sein – Access erlaubt schlicht und einfach nicht das Markieren nicht zusammenhängender Zeilen in der Datenblattansicht. Also müssen wir uns mit ein paar Tricks behelfen. Als Erstes benötigen wir eine Möglichkeit, irgendwie abzuspeichern, ob ein Datensatz markiert ist oder nicht. Dazu erweitern wir die Tabelle tblKunden einfach um ein Feld namens Selektiert mit dem Datentyp Ja/Nein (siehe Bild 3). Natürlich können Sie das nicht machen, wenn die Tabelle beispielsweise von einer SQL Server-Datenbank stammt oder von einem Backend, dessen Entwurf Sie nicht ändern können. Für diesen Fall gibt es Alternativen, die wir später besprechen können.
Bild 3: Tabelle der Beispieldatenbank
Markierung speichern
Im zweiten Schritt müssen wir dafür sorgen, dass dieses Ja/Nein-Feld auf den Wert Ja eingestellt wird, wenn wir das erste Mal auf einen Eintrag klicken und auf Nein, wenn wir diesen erneut betätigen. Wir wollen uns hier auf das Anklicken des Datensatzmarkierers beschränken, damit wir nicht entsprechende Ereignisprozeduren für alle Steuer-elemente der Datenblattansicht implementieren müssen.
Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
Hier geht es zur Bestellung des Jahresabonnements des Magazins Access [basics]:
Zur Bestellung ...
Danach greifen Sie sofort auf alle rund 400 Artikel unseres Angebots zu - auch auf diesen hier!
Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein: