AW: Userform dynamisch anpassen
23.07.2014 09:22:52
Erik
Hallo Mullit,
erst einmal: baie baie dankie für dieses Futter! Ich habe es gleich ausprobiert. Wenn ich deinen Code unverändert übernehme, passiert folgendes, wenn ich das Userform öffne:
Ich sehe 9 Buttons in einer Matrix mit 3 mal 3 Zeilen und Spalten. Wenn ich den letzten Button anklicke (Button 9), dann fügt dein Konstrukt dem Userform einen weiteren Button hinzu. Wenn ich den neuen letzten Button (Button 10) drücke, wird wieder ein neuer Button hinzugefügt usw.
Nun bin ich gerade am Verstehen deines Codes und habe zu bestimmten Stellen ein paar Fragen.
---
UserForm1
Option Explicit
Private mlngBlockStep As Long
Private mcolCommandButtons As Collection
Fragerunde 1:
Soweit ich den Teil verstehe, passiert hier folgendes:
- Du legst eine Variable vom Typ Long fest, die später die Anzahl der Spalten auf der Userform trägt.
- Du legst eine Collection fest, in die später sämtliche zur Laufzeit erstellte Buttons abgelegt werden.
Liege ich soweit richtig?
Private Sub UserForm_Activate()
Const MAX_BUTTON As Long = 9
Dim aobjButton(1 To MAX_BUTTON) As clscmdButton
Dim ialngIndex As Long
prplngBlockStep = 3
Fragerunde 2:
- Du legst hier eine Konstante fest, mit der du die Anzahl der zu erstellenden Buttons dimensionierst.
- Du initialisierst eine Variable vom Typ Long, mit der du später in der For-Schleife arbeitest
- Du legst fest, dass es drei Spalten auf dem UserForm gibt.
Habe ich das auch richtig interpretiert?
Set mcolCommandButtons = New Collection
For ialngIndex = 1 To MAX_BUTTON
Set aobjButton(ialngIndex) = New clscmdButton
With aobjButton(ialngIndex)
Set .prpcmdButton = Controls.Add(bstrProgID:="Forms.CommandButton.1", Visible:=True)
With .prpcmdButton
If ialngIndex > 1 Then
If (ialngIndex - 1) Mod prplngBlockStep = 0 Then
.Top = aobjButton(ialngIndex - 1).prpcmdButton.Top + _
aobjButton(ialngIndex - 1).prpcmdButton.Height + 20
Else
.Top = aobjButton(ialngIndex - 1).prpcmdButton.Top
End If
ElseIf ialngIndex = 1 Then
.Top = 5
End If
If (ialngIndex - 1) Mod prplngBlockStep = 0 Or ialngIndex = 1 Then _
.Left = 5 _
Else: .Left = aobjButton(ialngIndex - 1).prpcmdButton.Left + _
aobjButton(ialngIndex - 1).prpcmdButton.Width + 20
.Width = 150
.Height = 30
.Caption = "Weiter" & ialngIndex
End With
End With
prpcolCommandButtons.Add aobjButton(ialngIndex)
Next
Erase aobjButton
Fragerunde 3:
- Das meine ich gut zu verstehen: Du initialisierst eine Collection als Sammelbehälter für alle Buttons.
- Du erzeugst anhand der Klasse clscmdButton neun Buttons, deren Eigenschaften du anhand der vorhergehenden Buttons (.Left/.Top) festlegst.
- Du speicherst jeden Button in der Collection.
- Du löschst anschließend den Inhalt von aobjButton.
Habe ich das richtig wiedergegeben?
End Sub
Private Sub UserForm_Terminate()
Set mcolCommandButtons = Nothing
End Sub
- Du gibst die Collection wieder frei bzw. du zerstörst das Objekt.
Friend Property Get prpcolCommandButtons() As Collection
Set prpcolCommandButtons = mcolCommandButtons
End Property
Friend Property Get prplngBlockStep() As Long
prplngBlockStep = mlngBlockStep
End Property
Friend Property Let prplngBlockStep(ByVal pvlngVariable As Long)
mlngBlockStep = pvlngVariable
End Property
Fragerunde 4:
- Wozu dieser Teil? Ich weiß, dass es sich um Eigenschaften handelt. Sind das Eigenschaften des Userforms? Einmal handelt sich um die Button-Collection und einmal um die Spaltenanzahl.
---
Modul1
Dim objCmdButton As clscmdButton
Dim objCommandButton As clscmdButton
Dim lngIndex As Long
Set objCommandButton = New clscmdButton
With objCommandButton
Set .prpcmdButton = UserForm1.Controls.Add( _
bstrProgID:="Forms.CommandButton.1", Visible:=True)
- Du hast eine neue Instanz der Klasse clscmdButton erstellt.
- Die Klasse hat die Eigenschaft prpcmdButton, die einen Button darstellt.
- Anschließend erstellst du einen Button.
Soweit so gut?
With .prpcmdButton
Set objCmdButton = _
UserForm1.prpcolCommandButtons.Item(UserForm1.prpcolCommandButtons.Count)
Die Eigenschaft prpcolCommandButtons stellt die Buttons-Collection des Userforms dar, oder?
Hier verstehe ich das Set nicht ganz, da doch im weiteren Verlauf die Eigenschaften von prpcmdButton angepasst werden?
If UserForm1.prpcolCommandButtons.Count Mod UserForm1.prplngBlockStep = 0 Then
.Left = 5
.Top = objCmdButton.prpcmdButton.Top + _
objCmdButton.prpcmdButton.Height + 20
Else
.Top = objCmdButton.prpcmdButton.Top
.Left = objCmdButton.prpcmdButton.Left + _
objCmdButton.prpcmdButton.Width + 20
End If
.Width = 150
.Height = 30
.Caption = "WeiterNeu" & UserForm1.prpcolCommandButtons.Count + 1
End With
End With
UserForm1.prpcolCommandButtons.Add objCommandButton
Hier wird der neue Button der Button Collection hinzugefügt?
Set objCommandButton = Nothing
Set objCmdButton = Nothing
End Sub
Hier werden die beiden Objekte zerstört.
---
Klasse clscmdButton
Private WithEvents mcmdButton As CommandButton
Private Sub Class_Terminate()
Set mcmdButton = Nothing
End Sub
Wenn die Instanz zerstört wird, dann soll auch das Objekt zerstört werden.
Private Sub mcmdButton_Click()
MsgBox mcmdButton.Name
If mcmdButton.Name = TypeName(mcmdButton) & UserForm1.prpcolCommandButtons.Count Then _
Call prcNewButton
End Sub
Hieraus lese ich, dass nur der letzte Button einen neuen Button generiert. :)
Friend Property Get prpcmdButton() As CommandButton
Set prpcmdButton = mcmdButton
End Property
Friend Property Set prpcmdButton(ByVal pvcmdButton As CommandButton)
Set mcmdButton = pvcmdButton
End Property
Hier werden Eigenschaften der Klasse bestimmt. Die letzte Eigenschaft verstehe ich nicht. Kannst du mir den Zusammenhang erkären?
Mullit, ich hoffe, ich quäle dich nicht. Ich freue mich, wenn du mir eine Rückmeldung gibst, du kannst aber auch schreiben, dass du keinen Bock hast. :)
Dank im Voraus in jedem Fall!
Gruß
Erik