Dynamische Bereichshöhe im Endlosformular

Ein Leser stellt mir neulich die Frage, ob und wie man die Höhe der einzelnen Bereiche im Endlosformular dynamisch so einstellen kann, dass beispielsweise immer drei Datensätze angezeigt werden – auch, wenn der Benutzer die Höhe des Endlosformulars während der Anzeige ändert. Dieser Beitrag zeigt, wie das möglich ist. Dabei behelfen wir uns einer Ereignisprozedur, die immer beim Ändern der Größe eines Formulars ausgelöst wird – und eines kleinen Tricks, der wegen der enthaltenen Steuerelemente nötig wurde.

Aufgabenstellung

Zum besseren Verständnis hilft der Screenshot aus Bild 1. Wenn der Benutzer die Höhe des Formulars ändert, dann sollen die drei angezeigten Detailbereiche ihre Höhe automatisch so ändern, dass sie immer jeweils 1/3 des verfügbaren Platzes einnehmen.

So soll die Höhe der Detailbereiche angepasst werden, wenn der Benutzer die Höhe des Formulars ändert.

Bild 1: So soll die Höhe der Detailbereiche angepasst werden, wenn der Benutzer die Höhe des Formulars ändert.

1/3 deshalb, weil wir für das Beispiel in diesem Beitrag dazu entschieden haben, dass das Endlosformular immer drei Datensätze anzeigen soll (außer natürlich, es enthält weniger als drei Datensätze oder der Benutzer scrollt ganz nach unten).

Beispielformular

Als Beispiel verwenden wir das Formular frmEndlosformularHoehe. Es verwendet die Tabelle tblInhalte als Datensatzquelle. Diese Tabelle enthält nur die beiden Felder ID und Inhalt (Felddatentyp Langer Text).

Wir ziehen nur das Feld Inhalt aus der Feldliste in den Detailbereich und passen Höhe von Detailbereich und Textfeld einander an. Außerdem stellen wir die Eigenschaft Standardansicht auf Endlosformular ein und aktivieren die in Endlosformularen häufig sichtbaren Bereiche Formularkopf und Formularfuß (siehe Bild 2).

Entwurf des Formulars

Bild 2: Entwurf des Formulars

Umsetzung mit dem Ereignis “Bei Größenänderung”

Wer schon ein wenig mit Formularen programmiert hat, der weiß: Wir werden vermutlich mit dem Ereignis Bei Größenänderung arbeiten, um das gewünschte Ergebnis zu erreichen.

Und wir benötigen einige Kenntnisse über die Eigenschaften, mit denen wir die Höhen verschiedener Bereiche des Formulars und des Formulars selbst ermitteln können.

Höhe der verschiedenen Bereiche

Man mag vermuten, dass man die Höhe eines Formulars mit einer Eigenschaft wie Me.Height ermitteln kann. Weit gefehlt: Diese Eigenschaft bietet das Formular gar nicht an. Die Height-Eigenschaft finden wir allerdings für die verschiedenen Bereiche des Formulars vor – für den Detailbereich, den Formularkopf und den Formularfuß beispielsweise. Wenn wir allerdings ermitteln wollen, wie hoch der Detailbereich sein darf, damit genau drei Datensätze im Bereich zwischen Formularkopf und Formularfuß sichtbar sind, benötigen wir eine Information über die gesamte Höhe des Formulars.

Ein genauerer Blick in das Objektmodell liefert schnell die Eigenschaft InsideWidth. InsideWidth liefert genau die Höhe des sichtbaren Bereichs innerhalb des Formularrahmens. Damit können wir die Höhe des Detailbereichs für drei Datensätze nach der Formel (Gesamthöhe – Formularkopf – Formularfuß) / 3 berechnen.

In einem ersten, naiven Ansatz könnten wir also die folgende Anweisung in die Ereignisprozedur schreiben, die durch das Ereignis Bei Größenänderung ausgelöst wird:

Private Sub Form_Resize()
     Me.Detailbereich.Height = (Me.InsideHeight - _
         Me.Formularkopf.Height - Me.Formularfuß.Height) / 3
End Sub

Damit kommen wir schon erstaunlich weit. Gleich beim Öffnen zeigt das Formular so drei Detailbereiche an, die genau den Platz zwischen Formularkopf und Formularfuß einnehmen. Wenn wir die Höhe des Formulars vergrößern, passt sich die Höhe der Detailbereiche automatisch an. Wenn wir die Höhe des Formulars allerdings so weit verkleinern, dass die im Entwurf eingestellte Höhe der Detailbereiche unterschritten wird, verkleinert die Prozedur die Höhe der Detailbereiche nicht mehr (siehe Bild 3).

Die Detailbereiche werden nur bis zur Entwurfshöhe verkleinert.

Bild 3: Die Detailbereiche werden nur bis zur Entwurfshöhe verkleinert.

Warum ist das der Fall? Der Grund ist schnell gefunden: Die enthaltenen Textfelder ändern ihre Höhe nicht analog zu der Höhe der Detailbereiche. Auch die Einstellung der Eigenschaft Horizontaler Anker auf den Wert Beide bewirkt keine Änderung. Die erste alternative Idee hierzu ist, die Höhe des Textfeldes Inhalt einfach auf die gleiche Höhe einzustellen wie den Detailbereich:

Private Sub Form_Resize()
     Me.Detailbereich.Height = (Me.InsideHeight - _
         Me.Formularkopf.Height - Me.Formularfuß.Height) / 3
     Me!Inhalt.Height = Me.Detailbereich.Height
End Sub

Das klappt auch, solange man die Höhe des Formulars nur vergrößert. Sobald wir die Höhe verkleinern, tut sich nichts mehr – weder die Höhe des Detailbereichs noch die des Textfeldes ändert sich. Auch dafür gibt es einen guten Grund. Wir versuchen hier, zuerst die Höhe des Detailbereichs zu ändern und dann erst die des Textfeldes. Beim Vergrößern gelingt das, weil wir erst die Höhe des Detailbereichs vergrößern und dann die des Textfeldes. Andersherum gelingt es nicht: Wir können den Detailbereich nicht verkleinern, wenn das enthaltene Textfeld nicht kleiner ist.

Verkleinern oder vergrößern?

Also müssen wir noch prüfen, ob der Benutzer gerade die Höhe des Formulars vergrößert oder verkleinert. Wenn er vergrößert, muss erst der Detailbereich angepasst werden und dann das Textfeld, wenn er das Formular verkleinert, müssen wir erst das Textfeld verkleinern und dann den Detailbereich. Um herauszufinden, ob das Formular gerade vergrößert oder verkleinert wird, müssen wir die vorherige Höhe in einer Variablen speichern und beim Ausführen der Prozedur Form_Resize prüfen, ob die neue Höhe größer oder kleiner als die vorherige Höhe ist.

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

Schreibe einen Kommentar