Tausendsassa Datenblatt - Teil 1

15.01.2006 von André Minhorst
Das Anzeigen von Daten in tabellarischer Form ist mindestens auf die folgenden drei Arten möglich: als Endlosformular, als Listenfeld oder in der Datenblattansicht. Letztere ist definitiv die flexibelste und am schnellsten erstellte. Trotzdem werden die anderen Ansichten oft vorgezogen – ohne Grund, wie der vorliegende Artikel zeigen wird.

Die Datenblattansicht ist diejenige, die Sie schon von Tabellen und Abfrageergebnissen her kennen – und auch in Formularen ist sie zu finden. Dort hat sie allerdings Konkurrenz in Form der Listenfelder und der Endlosansicht. Alle drei kommen zum Einsatz, wenn Daten in tabellarischer Form angezeigt werden sollen.

Alle haben Vor- und Nachteile, die über den Zuschlag für die jeweilige Variante führen. Listenfelder ermöglichen etwa eine erweiterte Auswahl, das heißt, dass Sie mehrere, nicht zusammenhängende Datensätze markieren können. Die Daten in Listenfeldern lassen sich definitiv nicht verändern. Klicks zur Auswahl eines Datensatzes können auf der gesamten Breite des Listenfeldes ausgeführt werden, ebenso Doppelklicks zum Ausführen beliebiger Aktionen.

Die Endlosansicht offeriert die umfangreichsten Designmöglichkeiten. Sie können praktisch alles mit den Feldern eines Formulars in der Endlosansicht
machen – wenn eine besondere Darstellung erforderlich ist, ist die Endlosansicht sicher die beste Wahl. Üblicherweise sollte man allerdings nicht von den Standards abweichen und dementsprechend keine grünen Textfelder mit blauer Schrift präsentieren.

Die Datenblattansicht hat ihre Vorteile in der leichten Anpassbarkeit und dem geringsten Aufwand zur Erstellung: Sie ziehen einfach die gewünschten Felder aus der Feldliste in das Formular und wechseln in die Datenblattansicht – fertig. Zusätzlich stellen Sie, ohne auch nur eine Zeile zu programmieren, Funktionen zum Sortieren der Datensätze, zum Einstellen der Breite,
der Reihenfolge und der Sichtbarkeit der Felder sowie zum Löschen, Hinzufügen und zum Bearbeiten zur Verfügung.

Diesen Vorteilen widmet sich dieser Artikel. Er stellt die Möglichkeiten vor, die sich aus der Verwendung der Datenblattansicht ergeben. Vor allem aber zeigt er, wie Sie die Datenblattansicht noch flexibler gestalten können. Allerdings werden Sie hier nicht ohne Programmcode auskommen.

Eins, zwei, Datenblatt

Als Beispiel dient in den folgenden Abschnitten ein Formular mit Unterformular, das die Kategorien und die enthaltenen Artikel aus der Nordwind-Datenbank anzeigt. Das Formular ist schnell zusammengeklickt Erstellen Sie das Hauptformular namens frmArtikelNachKategorie und stellen Sie seine Datenherkunft auf die Tabelle Kategorien ein.

  1. Erstellen Sie das Hauptformular namens frmArtikelNachKategorie und stellen Sie seine Datenherkunft auf die Tabelle Kategorien ein.

  2. Ziehen Sie die Felder der Tabelle in den Detailbereichdes Formulars.

  3. Erstellen Sie das Unterformular und speichern Sie es unter dem Namen sfmArtikel- NachKategorie. Als Datenherkunft dient hier die Tabelle Artikel.

  4. Ziehen Sie alle Felder mit Ausnahme des Feldes Kategorie-Nr in den Detailbereich.

  5. Stellen Sie die Eigenschaft Standardansicht des Unterformulars auf Datenblatt ein.

  6. Schließen Sie das Unterformular und ziehen Sie es aus dem Datenbankfenster in den Detailbereich
    des Hauptformulars.

  7. Prüfen Sie, ob Access das Feld für die Verknüpfung zwischen Haupt- und Unterformular richtig eingestellt hat. Es handelt sich dabei um die beiden Eigenschaften Verknüpfen von und Verknüpfen nach des Unterformularsteuerelements. Enthalten beide den Wert Kategorie- Nr, sind Sie schon fertig.

Optik-Tuning

Ein bisschen Nacharbeit ist natürlich noch nötig. So sollten Sie die Schriftgröße des Unterformulars an die der im Hauptformular verwendeten Felder anpassen – standardmäßig wird in normalen Textfeldern die Schriftgröße 8 verwendet, in Datenblattansichten aber Schriftgröße 10. Um die Schrifteigenschaften der Datenblattansicht anzupassen, öffnen Sie das Unterformular ohne das Hauptformular in der Datenblattansicht und klicken mit der rechten Maustaste auf die Titelleiste. Wählen Sie im Kontextmenü den Eintrag Zeichen aus und nehmen Sie die gewünschten Änderungen vor.

Wenn Sie das Unterformular auf die richtige Breite gezogen haben, um alle Felder inklusive Feldnamen optimal erkennen zu können, tritt ein Nachteil der Datenblattansicht offen zu Tage: In Feldern, die zwar lange Feldnamen, aber nur kurze Inhalte wie etwa den aus wenigen Zahlen bestehenden Lagerbestand enthalten, wird eine Menge Platz verschenkt. Zwei- oder mehrzeilige Feldüberschriften sind nicht möglich, also wählt man als Kompromiss eine Abkürzung. Anschließend sieht das Formular wie in Bild 1 aus.

Bearbeiten verhindern


Oft kommen Listenfelder zum Zuge statt der Datenblattansicht, die kein Bearbeiten der enthaltenen Daten erlaubt. Fälschlicherweise wird angenommen, dass dies in der Datenblattansicht nicht möglich ist. Tatsächlich geht das sehr wohl. Sie müssen einfach nur die Eigenschaft Recordsettyp des entsprechenden Formulars auf Snapshot einstellen – prompt ist der üblicherweise angezeigte leere Datensatz hinter dem letzten Datensatz verschwunden, und auch der Versuch, die Daten eines vorhandenen Datensatzes zu ändern, schlägt fehl.

Markieren wie im Listenfeld


Ein weiterer eher optischer Grund für den Vorzug von Listenfeldern ist, dass die Auswahl von Datensätzen in der Datenblattansicht nicht intuitiv erscheint. Wählt man im Listenfeld einen Eintrag aus, wird er direkt komplett schwarz hinterlegt. In der Datenblattansicht bewirkt ein Klick auf einen Datensatz lediglich das Setzen der Einfügemarke in dem betreffenden Feld. Das können Sie per VBA leicht ändern – vorausgesetzt, die Ansicht ist nicht zum Bearbeiten der Daten, sondern zum Auswählen vorgesehen. Sie legen einfach für alle in Frage kommenden Steuerelemente eine Prozedur an, die durch das Ereignis Beim Klicken ausgelöst wird. Diese Routinen enthalten lediglich die Anweisung

56DoCmd.RunCommand acCmdSelectRecord

Klicken Sie anschließend auf das Steuerelement, für das Sie eine passende Ereignisprozedur angelegt haben, wird direkt der komplette Datensatz markiert.

Bild 1: Optisch getunte Datenblattansicht im Unterformular.

Bei Kombinationsfeldern und Kontrollkästchen funktioniert dies allerdings nicht, hier müssen Sie die Anweisung in die Prozedur eintragen, die durch das Ereignis Maustaste ab ausgelöst wird. Festzuhalten ist, dass diese Vorgehensweise nur zum Markieren jeweils einer Zeile geeignet ist.

Und der Codieraufwand


Sie werden zu Recht sagen: Wenn ich für jedes Steuerelement in jedem Formular, das ich in der Datenblattansicht anzeigen möchte, eine neue Prozedur anlegen muss, wird das ziemlich zeitaufwendig. Es gibt allerdings ein Gegenmittel, mit dem Sie einmal Codieraufwand haben und anschließend nur noch wenige Zeilen je Formular hinzufügen müssen.

Stellen Sie sich einmal vor, Sie müssen dem Formular, das in der Datenblattansicht angezeigt werden und das per Mausklick auf ein beliebiges Steuerelement die komplette Zeile markieren soll, nur noch die folgenden Zeilen Code einfügen:

Dim objForm As clsForm
Private Sub Form_Open(Cancel As Integer)
Set objForm = New clsForm
Set objForm.Formular = Me
End Sub


Das wäre wohl ein vertretbarer Aufwand. Vor allem, wenn man damit noch viel mehr bewirken kann, als nur
einen kompletten Datensatz beimKlick auf ein einziges Feld zu markieren – dazu jedoch später mehr.

Und wie funktioniert das? Immerhin muss sich ja irgendwo die Funktionalität verbergen, die sonst in den Ereignissen Bei Maus Ab der Steuerelemente verborgen hat. Und auch die entsprechenden Ereignisse müssen irgendwie berücksichtigt werden.

Option Compare Database
Option Explicit
Dim WithEvents mForm As Form
Dim mColControls As Collection
Dim mControl As clsControl
Public Property Set Formular(frmFormular As Form)
Dim ctl As Control
Set mForm = frmFormular
Set mColControls = New Collection
For Each ctl In mForm.Controls
If ctl.ControlType = acTextBox Or ctl.ControlType = _
acComboBox Or ctl.ControlType = acCheckBox Then
Set mControl = New clsControl
Set mControl.FormControl = ctl
mColControls.Add mControl
End If
Next ctl
End Property

Formularereignisse kapseln


Die oben vorgestellte Methode, die beim Öffnen des Formulars ausgelöst wird, instanziert die Klasse aus Listing 1. Diese Klasse hat nur eine einzige öffentlich schreibbare Eigenschaft namens Formular. Dieser Eigenschaft übergibt die obige Ereignisprozedur lediglich einen Verweis auf das Formular, von dem sie aufgerufen wird. Die Member-Variable der Klasse, der der Verweis auf das Formular zugewiesen wird, ist mit dem Schlüsselword WithEvents deklariert, was bedeutet, dass es auf die Ereignisse des Formulars lauscht und auf diese reagiert, wenn ein entsprechender Ereignishandler angelegt ist. In diesem Fall benötigen Sie dies noch nicht, Sie sollten den Grund der Verwendung des Schlüsselworts WithEvents aber im Hinterkopf behalten.

Eigentlich sollen ja hier auch keine Ereignisse des Formulars, sondern der enthaltenen Steuerelemente gekapselt werden. Und dazu müssen Sie diese Steuerelemente erst einmal durchlaufen und analysieren. Dafür sorgt eine For-Each- Schleife über alle Steuerelemente des Formulars. In dieser Schleife wird überprüft, ob es sich bei dem Steuerelement um ein Textfeld, ein Kombinationsfeld oder ein Kontrollkästchen handelt. Tritt einer dieser Fälle ein, kommt eine weitere Klasse ins Spiel, die ähnlich funktioniert wie die Klasse clsFormular, sich allerdings auf Steuerelemente bezieht: Die aufrufende Klasse clsFormular erzeugt eine Instanz der Klasse clsControl und übergibt der Eigenschaft FormControl einen Verweis auf das aktuell in der For-Each-Schleife befindliche Steuerelement. Dort wird das Steuerelement erneut hinsichtlich seines Typs überprüft und in Abhängigkeit davon einer der drei Membervariablen mTextbox, mComboBox oder mCheckbox zugewiesen.

Diese sind wiederum mit dem Schlüsselwort WithEvents deklariert, was in diesem Fall auch direkt gerechtfertigt ist: Um zu erkennen, was dies bedeutet, wählen Sie im linken Kombinationsfeld im oberen Bereich des Codefensters im VBA-Editor den Eintrag mTextbox aus. Wenn Sie dann das rechte Kombinationsfeld aufklappen, finden Sie dort sämtliche Ereignisprozeduren, die für das Steuerelement auch im Formularmodul zur Verfügung stehen (Bild 2).

Bild 2: Mit WithEvents deklarierte Objekte liefern die ihrem Typ entsprechenden Ereignisprozeduren mit.

Option Compare Database
Option Explicit

Dim WithEvents mTextbox As TextBox
Dim WithEvents mCombobox As ComboBox
Dim WithEvents mCheckbox As CheckBox

Public Property Set FormControl(ctl As Control)
Select Case ctl.ControlType
Case acTextBox
Set mTextbox = ctl
ctl.OnMouseDown = "[Event Procedure]"
Case acComboBox
Set mCombobox = ctl
ctl.OnMouseDown = "[Event Procedure]"
Case acCheckBox
Set mCheckbox = ctl
ctl.OnMouseDown = "[Event Procedure]"
End Select
End Property

Private Sub mCheckbox_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Control_MouseDown
End Sub

Private Sub mCombobox_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Control_MouseDown
End Sub

Private Sub mTextbox_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Control_MouseDown
End Sub

Private Sub Control_MouseDown()
DoCmd.RunCommand acCmdSelectRecord
End Sub

Um in dieser Klasse nun ein Ereignis für eines der Formularsteuerelemente festzulegen, sind zwei Schritte notwendig:

  1. Weisen Sie der Ereigniseigenschaft des
    Steuerelements (hier repräsentiert durch die
    Objektvariable mTextbox, mCombobox oder
    mCheckbox) den Wert [Event Procedure] zu. Dies
    entspricht dem Auswählen des entsprechenden
    Eintrags im Eigenschaftsfenster des Steuerelements.

  2. Fügen Sie zu der Klasse eine Ereignisprozedur
    hinzu, die der soeben festgelegten Ereigniseigenschaft
    entspricht.

Nun werden ja direkt mehrere dieser Steuerelement- Klassen erzeugt – genauso genommen für jedes Textfeld, Kombinationsfeld oder Kontrollkästchen eine. Damit diese nicht vergessen werden, speichert die Formular-Klasse aus Listing 1 die Steuerelement-Klassen in einer Collection, indem es dieser das Steuerelement-Objekt einfach mit der Add-Methode zuweist.

Den in der Steuerelement-Klasse angelegten Ereignisprozeduren müssen Sie nun noch aktivieren: Da alle Steuerelementtypen das Gleiche tun sollen, fügen Sie zu allen Ereignisprozeduren einfach den Aufruf einer weiteren Prozedur namens Control_Mousedown hinzu, in der dann die Anweisung zum Markieren des kompletten Datensatzes aufgerufen wird:

DoCmd.RunCommand acCmdSelectRecord

Wiederverwendbarkeit ist Trumpf

Wenn Sie in nur einem Formular in der Datenblattansicht diese oder eine ähnliche Funktionalität einbauen möchten, ist es vielleicht einfacher, allen Steuerelementen die benötigte Funktionalität zu verpassen. Die oben beschriebene Vorgehensweise ist jedoch viel eleganter und hat nicht nur den Vorteil der Wiederverwendbarkeit. Wenn Sie beispielsweise noch einmal ein Feld zum Formular hinzufügen, müssen Sie sich um die Funktionalität zum Markieren des kompletten Datensatzes nicht kümmern – die Formular-Klasse durchläuft sowieso alle Steuerelemente und berücksichtigt das neue ganzm automatisch

Wie gehts es weiter?

Der Vor- und gleichzeitig auch Nachteil von Formularen in der Datenblattansicht ist die Flexibilität des Layouts. Die Benutzer können die Spaltenbreite und die Zeilenhöhe ändern, Spalten ein- und ausblenden und so weiter. Da kommt dann schnell der Anruf eines verzweifelten Benutzers, der plötzlich und „ohne etwas berührt zu haben“ einige wichtigen Informationen im Formular vermisst.

Im zweiten Teil dieser Beitragsreihe erfahren Sie unter anderem, wie Sie die Datenblattansicht sicher machen und dem Benutzer die Möglichkeit bieten, blitzschnell den Ausgangszustand wiederherzustellen.