Fliegende Steuerelemente üblicherweise positionieren Sie Textboxen, Labels und Kombinationsfelder fest im Entwurf eines Formulars und ändern an der ergonomischen Gestalt zur Laufzeit nichts mehr. Doch manchmal gibt es gute Gründe für ein dynamisches Layout, bei dem Steuerelemente ihren angestammten Platz verlassen. Einige Anregungen dazu liefert dieser Beitrag.
Beispieldatenbank
Die Beispiele dieses Artikels finden Sie in der Datenbank 1607_FlyingCtls.accdb.
Steuerelemente verschieben
Für die Position jedes Steuerelements sind dessen Eigenschaften Links und Oben im Formular- oder Berichtsentwurf verantwortlich, die Sie entweder durch Ziehen der Elemente mit der Maus ändern, oder durch einen direkten Eintrag im Eigenschaftenblatt. Gleiches gilt für die Breite und Höhe eines Controls.
Unter VBA greifen Sie auf diese Eigenschaften über die Properties Left und Top zu, sowie über Width und Height. Diese Methoden sind nicht schreibgeschützt, so dass Sie über entsprechende Wertzuweisungen die Positionen zur Laufzeit ändern können. Ein Textfeld txtName bringen Sie etwa so in eine andere Position und auf neue Abmessungen:
txtName.Left = 300
txtName.Top = 120
txtName.Width = 2100
txtName.Height = 270
Das Ganze können Sie auch über einen With-Block auf das Control umsetzen und setzen besser noch den Container Me des Steuerelements voran:
With Me!txtName .Left = 300 .Top = 120 .Width = 2100 .Height = 270 End With
Die Einheit dieser Werte ist unter Access immer Twips. 15 Twips entsprechen in der Regel 15 Pixeln und ein Zentimeter entspricht etwa 567 Twips. Die Positionsangaben beziehen sich grundsätzlich auf die linke obere Ecke des Steuerelements als seinen Ursprung und sind, entgegen der Aussage in der Access-Hilfe, relativ zum jeweiligen Container. Das kann der Detailbereich sein, aber auch der Kopf- oder Fußbereich. Bei Berichten kommen noch weitere Containerflächen hinzu.
Eine Alternative zum direkten Zuweisen der Werte an Left und Top stellt die Move-Methode dar, die allen Steuerelementen zueigen ist. Mit ihr können Sie die vier Eigenschaften auf einen Schlag einstellen:
Me!txtName.Move 300, 120, 2100, 270
Alle vier Angaben sind optional. Sie können also mit dieser Methode etwa nur Position oder nur die Abmessungen ändern, indem Sie die anderen Parameter weglassen:
Me!txtName.Move 300,120 Me!txtName.Move , , 2100, 270
Schließlich gibt es mit der DoCmd-Anweisung MoveSize noch eine weitere Methode, die in ihren Parametern der Move-Methode der Controls entspricht. Sie wirkt allerdings nicht nur auf Steuerelemente, sondern genauso auf Formularfenster. Das macht zur Bedingung, dass das zu positionierende Element zum Zeitpunkt ihres Aufrufs den Fokus besitzt:
Me!txtName.SetFocus DoCmd.MoveSize 300, 120, 2100, 270
Auch hier sind alle Parameter optional. Die Methode entkoppelt die Anweisung vom Steuerelement und eignet sich daher nur für Fälle, in denen das Control-Objekt ungewiss ist.
Fliegende Steuerelemente
Das weitgehend sinnfreie Formular frmFlying der Beispieldatenbank demonstriert die Verschiebeeffekte zur Laufzeit (Bild 1). In einer VBA-Schleife werden über den Timer des auf Adressdatensätzen basierenden Formulars sämtliche Steuerelemente fortlaufend verschoben. Damit sie nicht über den Rand hinaus geraten, was Access ohnehin mit einer Fehlermeldung quittieren würde, reflektieren sie quasi billardmäßig von den Seiten. Den Code, der beim Starten des Formulars zunächst ausgeführt wird, finden Sie in Listing 1. Er ist auf den ersten Blick nicht selbsterklärend.
Bild 1: Das Formular frmFlying zeigt in der Gegend herumfliegende Steuerelemente
Modulweit gelten die Variablen colCtl (Collection-Objekt) und das Array arrXY. Die Collection versammelt indiziert die Namen aller Controls des Formulars, arrXY ist zweidimensional und speichert deren Positionen. Die For-Each-Schleife durchläuft alle Steuerelemente über die Iteratorvariable ctl. Das können Textboxen, Comboboxen oder Labels sein. In colCtl werden per Add-Methode die Indizes (i) der Controls aufgenommen, wobei als Schlüssel jeweils der Steuerelementname herhält. Das Array arrXY wird über ReDim in der zweiten Dimension auf die Zahl der Steuerelemente dimensioniert (Controls.Count) und andererseits auf 1 in der ersten Dimension, was bedeutet, dass zu jedem Array-Element zwei Werte abgespeichert werden können: ein X– und ein Y-Wert für die Positionsverschiebungen. Die Collection dient dazu, um später aus einem Steuerelementnamen seinen Index für arrXY bestimmen zu können. Außerdem wird das Array mit X– und Y-Verschiebefaktoren vorgefüllt, die sich aus Zufallszahlen (Rnd) ergeben. Der Ausdruck
1 + 5 * (Rnd - 0.5)
bewirkt, dass die Klammer positiv oder negativ wird, wenn Rnd größer oder kleiner ist, als 0.5. Der Bereich des Klammerausdrucks beträgt damit -2.5 bis +2.5.
Abschließend wird der Timer des Formulars aktiviert und auf 20 Millisekunden eingestellt, was zu 50 Wiederholungen pro Sekunde führen sollte. Die Prozedur des Timer-Events in Listing 2 nimmt nun die eigentlichen Steuerelementverschiebungen vor und wertet aus, ob sie am Rand des Formulars reflektiert werden sollen.
Private Sub Form_Timer() Dim ctl As Access.Control Dim i As Long For Each ctl In Me.Controls i = colCtl(ctl.Name) ctl.Left = ctl.Left + 30 * arrXY(0, i) ctl.Top = ctl.Top + 30 * arrXY(1, i) If (ctl.Left < 91) Then arrXY(0, i) = -arrXY(0, i) ctl.Left = 90 End If If ((ctl.Left - 91) > (Me.InsideWidth - ctl.Width)) Then arrXY(0, i) = -arrXY(0, i) ctl.Left = Me.InsideWidth - ctl.Width - 90 End If If (ctl.Top < 91) Then arrXY(1, i) = -arrXY(1, i) ctl.Top = 90 End If If ((ctl.Top + 91) > (Me.InsideHeight - ctl.Height)) Then arrXY(1, i) = -arrXY(1, i) ctl.Top = Me.InsideHeight - ctl.Height - 90 End If Next ctl DoEvents End Sub
Listing 2: Timer-Prozedur des Formulars zum Bewegen der Steuerelemente
Auch hier wird eine Schleife auf alle Controls des Formulars gesetzt. Aus colCtl wird jeweils erst über den Namen der Control-Variable ctl dessen Index für das Array arrXY errechnet und in der Variablen i abgespeichert. Dann wird zu Left und Top des Controls der mit 30 multiplizierte Verschiebewert aus dem Array hinzuaddiert. Je höher dieser Multiplikator, desto schneller bewegt sich das Steuerelement zur Laufzeit über das Formular.
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: