Die Datenblattansicht ist sehr hilfreich, wenn man die Daten aus Tabellen oder Abfragen in tabellarischer Form darstellen möchte. Sie bietet außerdem Funktionen zum Anpassen der Spalten, der Sortierung und auch der Filter. Zusätzlich können wir damit nicht nur einen Datensatz markieren, sondern gleich mehrere. Wir erhalten zwar nicht den Komfort wie im Listenfeld, wo wir nicht nur zusammenhängende, sondern auch einzelne Einträge selektieren können, aber immerhin ist es grundsätzlich möglich, bei gedrückter Maustaste mehr als einen Eintrag zu auszuwählen. Die Frage ist nur: Was machen wir mit diesem selektierten Bereich? Das Listenfeld bietet eigene Eigenschaften, mit denen wir auf die markierten Elemente zugreifen können. Das ist in der Datenblattansicht nicht der Fall. Das soll uns jedoch nicht davon abhalten, die gewünschten Daten weiterzuverarbeiten.
Wenn wir uns eine Datenblattansicht wie in Bild 1 ansehen, können wir verschiedene Arten von Selektion durchführen. Die einfachste ist, einfach in ein Feld zu klicken. Dies fügt dort an der Stelle des Klicks die Einfügemarke ein. Den Wert dieses Feldes können wir beispielsweise vom Direkbereich des VBA-Editors aus mit dem folgenden Ausdruck ermitteln:
Bild 1: Selektieren eines einzelnen Feldes
Debug.Print Screen.ActiveControl.Value
Knuth
Wir können auch den Namen des aktuellen Steuerelements abrufen:
Debug.Print Screen.ActiveControl.Name
txtVorname
Werte der anderen Felder des markierten Datensatzes auslesen
Auch wenn sich die Einfügemarke nur in einem Feld befindet, so wird doch der vollständige Datensatz markiert.
Aus dem Direktbereich heraus können wir wie folgt auf einen Wert eines anderen Steuerelements dieses Datensatzes zugreifen und diesen beispielsweise dort ausgeben:
Debug.Print Screen.ActiveForm!sfmMitarbeiterUebersicht!MitarbeiterID
8
Direkt vom Klassenmodul des Unterformulars sfmMitarbeiterUebersicht greifen wir noch einfacher auf diesen Wert zu:
Debug.Print Me!MitarbeiterID
Auf die gleiche Weise können wir auch auf die Inhalte der übrigen Felder per Feldname oder Steuerelementname zugreifen.
Markieren eines kompletten Datensatzes
Auch wenn das Anklicken eines einzigen Feldes bereits die gesamte Zeile markiert hat, gibt es noch eine weitere Abstufung. Wenn wir auf den grauen Bereich links vom Datensatz klicken, den sogenannten Datensatzmarkierer, markieren wir den vollständigen Datensatz (siehe Bild 2).
Bild 2: Markieren eines vollständigen Datensatzes
Der Unterschied ist, dass nun kein einzelnes Steuerelement mehr die Einfügemarke anzeigt, sondern alle Felder markiert und von einem Rahmen umgeben werden.
Screen.ActiveControl.Name liefert nun den Namen des ersten sichtbaren Steuerelements der Zeile.
Wenn wir auf die Daten des aktuell markierten Datensatzes zugreifen wollen, können wir einfach auf die einzelnen Steuerelemente zugreifen – diese liefern die Werte für den aktuellen Datensatz.
Markieren mehrerer Datensätze
Damit kommen wir zum Kern des Beitrags, dem Markieren zweier oder mehrerer zusammenhängender Datensätze gleichzeitig. Das gelingt beispielsweise auf die folgenden Arten:
- mit der Maus durch Markieren des Datensatzmarkierers des obersten oder untersten zu markieren Datensatzes und Ziehen bis zum Datensatzmarkierer am anderen Ende der Markierung,
- durch Anklicken des Datensatzmarkierers des ersten zu markierenden Datensatzes und Anklicken des Datensatzmarkierers eines anderen Datensatzes bei gedrückter Umschalttaste oder
- durch Anklicken des Datensatzmarkierers des ersten zu markierenden Datensatzes und Erweitern der Markierung mit den Tastenkombinationen Umschalt + Nach oben oder Umschalt + Nach unten.
Wir klicken mit der Maus auf den Datensatzmarkierer des obersten oder untersten zu markierenden Datensatzes und ziehen die Maus bei gedrückter Maustaste nach oben oder unten, je nachdem, in welche Richtung wir die Markierung erweitern wollen.
Ein Datenblatt mir mehreren markierten Datensätzen sehen wir in Bild 3.
Bild 3: Markieren mehrerer Datensätze in der Datenblattansicht
Der folgende Ausdruck liefert nun den Wert des linken, oberen Feldes des Datensatzes, der als Erstes markiert wurde:
Debug.Print Screen.ActiveControl.Value
Sollten wir also einen Datensatz markieren und die Markierung nach unten erweitern, werden die Daten des obersten Datensatzes geliefert. Wenn wir die Markierung nach oben ziehen, erhalten wir die Daten des untersten Datensatzes der Markierung.
Wenn wir wie folgt gezielt auf ein Steuerelement zugreifen wollen, erhalten wir ebenfalls die Werte der Steuerelemente der Zeile der Markierung, die als erste selektiert wurde:
Debug.Print Forms!frmMitarbeiterUebersicht!sfmMitarbeiterUebersicht!Vorname
Auslesen aller Zeilen der Markierung
Die eingebauten Mitteln zum Auslesen der Markierung sind zwar gegeben, allerdings kommen wir nicht ohne Weiteres an die in den markierten Zeilen enthaltenen Daten heran.
Die Markierung jedoch können wir mit den folgenden Eigenschaften auslesen:
- SelLeft: Index der linken Spalte der Selektion inklusive der ausgeblendeten Spalten, beginnt immer mit dem Wert 2
- SelTop: Index der obersten Spalte der Selektion
- SelWidth: Anzahl der Spalten der Selektion, inklusive der ausgeblendeten
- SelHeight: Anzahl der Zeilen der Selektion
Diese Daten lassen wir uns mit der folgenden Prozedur für das im Formular frmMitarbeiterUebersicht enthaltene Unterformular sfmMitarbeiterUebersicht ausgeben:
Public Sub MarkierungErfassen() Dim sfm As Form Set sfm = Forms!frmMitarbeiterUebersicht! sfmMitarbeiterUebersicht.Form With sfm Debug.Print "SelLeft: " & .SelLeft Debug.Print "SelTop: " & .SelTop Debug.Print "SelWidth: " & .SelWidth Debug.Print "SelHeight: " & .SelHeight End With End Sub
In Bild 4 sehen wir die beispielhafte Ausgabe dieser Werte für die angezeigte Markierung. SelLeft liefert unerwarteterweise den Wert 2, obwohl bereits die erste Spalte markiert ist. Die Werte für die anderen Eigenschaften sind nachvollziehbar.
Bild 4: Ausgabe der Selektion in Zahlen
Auslesen der Daten der Selektion
Wir wollen nun die Primärschlüsselwerte der selektierten Zeilen ermitteln.
Wie oben erwähnt, gelingt uns das durch Referenzieren des Feldes MitarbeiterID nur für den ersten Datensatz der Selektion – und hier erscheint auch noch der Wert des Datensatzes, mit dem die Markierung gestartet wurde.
Im Beispiel wäre das, wenn wir die Markierung ausgehend von der oberen Zeile aus angelegt hätten, der Wert 6. Wenn wir die Markierung jedoch unten begonnen hätten, würde sfm!MitarbeiterID den Wert 9 liefern.
Wie kommen wir nun an die MitarbeiterID-Werte der markierten Datensätze heran? Hier nutzen wir eine Kombination aus den zuvor ermittelten Koordinaten für die Markierung und dem RecordsetClone-Objekt.
Mit dem RecordsetClone eines Recordsets, in diesem Fall des zu untersuchenden Formulars, erstellen wir einen Klon des Recordsets. Es ist kein Verweis auf das bestehende Recordset, sondern eine eigene Kopie.
In dieser können wir verschiedene Dinge tun, zum Beispiel darin navigieren. Die Idee ist, dass wir das RecordsetClone-Objekt nutzen, um darin zunächst die Position der ersten Zeile der Markierung einzunehmen und dann durch die Anzahl der markierten Zeilen zu navigieren und die jeweiligen Primärschlüsselwerte zu ermitteln.
Der Code sieht wie in Listing 1 aus.
Public Sub DatenDerMarkierungErmitteln() Dim sfm As Form Dim rstClone As DAO.Recordset Dim i As Long Dim lngSelTop As Long Dim lngSelHeight As Long Dim lngCount As Long Dim arrBookmarks() As Variant Set sfm = Forms!frmMitarbeiterUebersicht!sfmMitarbeiterUebersicht.Form Set rstClone = sfm.RecordsetClone lngSelTop = sfm.SelTop lngSelHeight = sfm.SelHeight If lngSelHeight > 0 Then ReDim arrBookmarks(1 To lngSelHeight) rstClone.MoveFirst For i = 1 To lngSelTop - 1 rstClone.MoveNext Next i lngCount = lngSelHeight For i = 1 To lngSelHeight If rstClone.AbsolutePosition = -1 Then lngCount = lngSelHeight - 1 Exit For End If arrBookmarks(i) = rstClone.Bookmark rstClone.MoveNext Next i For i = 1 To lngCount rstClone.Bookmark = arrBookmarks(i) Debug.Print "ID: " & rstClone!MitarbeiterID Next i Else MsgBox "Bitte mindestens einen Datensatz markieren." End If End Sub
Listing 1: Anpassung der Prozedur für das Vergrößern und Verkleinern
In der Prozedur deklarieren wir neben dem Formular-Objekt sfm (für das Unterformular) ein Recordset-Objekt für das RecordsetClone sowie eine Laufvariable namens i und zwei Variablen zum Speichern der relevanten Markierungskoordinaten.
Schließlich benötigen wir noch ein Variant-Array namens arrBookmarks, in dem wir Bookmarks auf die betroffenen Datensätze des RecordsetClones speichern.
Die Prozedur referenziert das zu untersuchende Formular in der Datenblattansicht mit der Variablen sfm. Dann weist sie rstClone das RecordsetClone des Formulars zu.
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
den kompletten Artikel im PDF-Format mit Beispieldatenbank
diesen und alle anderen Artikel mit dem Jahresabo