Home > Artikel > Ausgabe 3/2017 > Selektion im Datenblatt

Selektion im Datenblatt

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).

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.

Beispiele für die Selektion von Datensätzen im Datenblatt

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:

Formular zum Auswerten der aktuellen Selektion

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.

Tabelle der Beispieldatenbank

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.

Für dieses neue Beispiel kopieren wir die beiden bereits verwendeten Formulare in neue Formulare, deren Namen wir um ...Mehrfachauswahl erweitern. Außerdem fügen wir dem Unterformular noch das Feld Selektiert hinzu (siehe Bild 4).

Entwurf für das zweite Beispiel mit Mehrfachauswahl

Bild 4: Entwurf für das zweite Beispiel mit Mehrfachauswahl

Für die Ereignisprozedur Beim Klicken des Formulars selbst hinterlegen wir die Ereignisprozedur aus Listing 2. Diese erstellt ein Database-Objekt auf Basis der aktuellen Datenbank, ermittelt den Wert des Feldes KundeID für den angeklickten Datensatz und stellt den Wert des Feldes Selektiert für diesen Datensatz auf den Wert Ja oder Nein ein – je nachdem, welchen Wert das Feld vorher hatte.

Private Sub Form_Click()

     Dim lngKundeID As Long

     Dim db As DAO.Database

     Set db = CurrentDb

     lngKundeID = Me!KundeID

     db.Execute "UPDATE tblKunden SET Selektiert = NOT Selektiert WHERE KundeID = " & lngKundeID, dbFailOnError

End Sub?

Listing 2: Aktualisieren der Daten für alle zu markierenden Datensätze

Auf diese Weise sehen wir nun schon einmal, dass wir einzelne Datensätze durch Anklicken des Datensatzmarkierers als selektiert oder nicht selektiert markieren können (siehe Bild 5).

Das Aus- und Abwählen einzelner Einträge funktioniert bereits.

Bild 5: Das Aus- und Abwählen einzelner Einträge funktioniert bereits.

Nun wollen wir noch einen Weg finden, um die Selektion anders als durch das Kontrollkästchen der Spalte Selektiert anzuzeigen.

Selektion per bedingter Formatierung hervorheben

Hier greifen wir nun auf eine Funktion der neueren Version von Access zurück: die bedingte Formatierung. Damit können wir festlegen, unter welcher Bedingung ein oder mehrere Felder mit einer bestimmten Formatierung versehen werden. In diesem Fall wollen wir dafür sorgen, dass die markierten Datensätze, also solche mit dem Wert Ja im Feld Selektiert, auch entsprechend hervorgehoben werden, damit wir dieses Feld ausblenden können.

Also klicken Sie, während sich das Formular noch in der Formularansicht befindet, in das Datenblatt des Unterformulars und betätigen dann den Befehl Datenblatt|Formatierung|Bedingte Formatierung des Ribbons. Es erscheint der Dialog aus Bild 6, wo Sie auf die Schaltfläche Neue Regel klicken.

Hinzufügen einer neuen Formatierungsregel

Bild 6: Hinzufügen einer neuen Formatierungsregel

Danach finden Sie den Dialog aus Bild 7 vor. Hier behalten Sie den angegebenen Regeltyp bei, wählen im ersten Kombinationsfeld aber den Wert Ausdruck ist aus. Dadurch erscheint rechts ein leeres Textfeld, in das Sie den als Bedingung zu verwendenden Ausdruck eingeben. Dieser lautet:

Definieren der Formatierungsregel

Bild 7: Definieren der Formatierungsregel

[Selektiert] = -1

Das heißt, dass die nachfolgend festgelegten Formatierungen nur angewendet werden, wenn das Feld Selektiert den Wert -1 aufweist. Damit legen wir nun noch die gewünschte Formatierung an, beispielsweise eine hellblaue Hintergrundfarbe wie in der Abbildung.

Schließen Sie diesen Dialog nun und haben bereits einige Datensätze mit dem Wert Ja für das Feld Selektiert versehen, erhalten Sie die Ansicht aus Bild 8. Wie Sie sehen, werden hier bereits die Felder der ersten Spalte mit dem gewünschten Hintergrund versehen.

Die erste Spalte wird bereits wie gewünscht formatiert.

Bild 8: Die erste Spalte wird bereits wie gewünscht formatiert.

Wenn wir diese bedingte Formatierung nun auch noch für die übrigen Felder hinterlegen, erscheinen die selektierten Felder mit der gewünschten Markierung.

Markierte Datensätze auslesen

Das Auslesen der Datensätze gerät hier zur Nebensache: Die markierten Datensätze haben ja den entsprechenden Wert im Feld Selektiert, sodass die Datensätze einfach über ein Recordset erfasst und ausgegeben werden können (siehe Listing 3).

Private Sub cmdSelektionAusgebenAlle_Click()

     Dim db As DAO.Database

     Dim rst As DAO.Recordset

     Set db = CurrentDb

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!