Autor: Peter Haserodt --- Aus Excel VBA - Gruppe:
KlassenKlassen [5] - Events [1] - Steuerelemente
Autor: Peter Haserodt - Erstellt: -- - Letzte Revision: 201202Gruppenthema: 8 Folgen 1 2 3 4 5 6 7 8 Sie sind in Folge:6
Steuerelement Ereignisse - Eine nette Sache
Bevor ich lange um den heißen Brei rede, gleich das erste Beispiel:
Erstellen Sie ein Klassenmodul clsCommandButton und eine UserForm mit einem CommandButton.
Plazieren Sie diesen links oben und geben Sie der UF eine bisserl Platz.
Starten Sie dann die UF und klicken Sie ein wenig.
' **************************************************************
' Modul: clsCommandButton Typ = Klassenmodul
' **************************************************************
Option Explicit
Public WithEvents DerCmd As MSForms.CommandButton
Private Sub DerCmd_Click()
DerCmd.ControlTipText = "Geklickt"
DerCmd.BackColor = vbGreen
DerCmd.Font.Bold = Not DerCmd.Font.Bold
End Sub
Private Sub DerCmd_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
MsgBox "Double"
End Sub
' **************************************************************
' Modul: UserForm1 Typ = Userform
' **************************************************************
Option Explicit
Dim oCommand1 As clsCommandButton
Dim oCommand2 As clsCommandButton
Private Sub CommandButton1_Click()
MsgBox "Hallo"
End Sub
Private Sub UserForm_Initialize()
Dim oComTemp As MSForms.CommandButton
Set oCommand1 = New clsCommandButton
Set oCommand2 = New clsCommandButton
Set oCommand1.DerCmd = CommandButton1
Set oComTemp = _
Me.Controls.Add("Forms.CommandButton.1", "cmd" & "Test", True)
With oComTemp
.Left = 100
.Top = 100
.Height = 25
.Width = 100
.Caption = "Klick Mich"
End With
Set oCommand2.DerCmd = oComTemp
Set oComTemp = Nothing
End Sub
Private Sub UserForm_Terminate()
Set oCommand1 = Nothing
Set oCommand2 = Nothing
End Sub
Code Analyse Klassenmodul
Der Schlüsselsatz ist hier:
Public WithEvents DerCmd As MSForms.CommandButton
Das sieht ungeheuer kompliziert aus aber ist es gar nicht.
WithEvents ist einfach ein Schlüsselwort (genauso wie Dim oder Sub oder sonstwas) und man könnte es übersetzen:
Mach mit den Ereignissen was
DerCmd ist einfach ein Name den ich vergebe. Das könne auch Timbuktu sein aber dann wäre mein Code schwerer lesbar.
MSForms.CommandButton ist einfach der Typ des Controls welches ich abgreife, in unserem Fall ein CommandButton
Und davor steht, dass er zu MSForms gehört, ist einfach ein Rezept.
Dann kommen zwei Ereignisse, die ich abfangen will, nämlich das Klickereignis und das Doppelklickereignis.
(Ich weiß, Doppelklick gibt keinen Sinn bei einem cmd aber ist ja nur zur Demo)
Danach lege ich Ereignisse fest, auf die ich reagieren will.
Dies funktioniert in der Art:
Mein oben definierter Name in WithEvents und danach Underscore und Ereignis.
Aber woher soll man wissen was dort hinkommt?
Nun ganz einfach:
Man nimmt sich einfach ein Steuerelement in einer Userform und kopiert das Ereignis welches man haben will.
(Alles hinter dem Namen, inkl. Underscore)
Dann schreibt man seinen eigenen Namen und fügt noch ein, so einfach. Inklusiv der Argumente.
Vorab aber schon der Wehmutstropfen:
Es werden nur wenige Ereignisse von Steuerelementen unterstützt. Später noch mehr dazu.
Code Analyse Userform
Ich habe zwei Variablen für zwei Instanzen der Klasse:
oCommand1 und oCommand2.
Diese Sette ich in meiner Initialize auf new.
Eine kleine Zwischenbemerkung hier:
Tatsächlich könnte ich mir in Initialize das Set .. = new ... sparen, wenn ich im Deklarationsteil schreiben würde:
Dim .. as new clsCommandbutton.
Dies würde hier problemlos funzen. Aber dem ist nicht immer so. Deswegen habe ich mir weitgehend diese Reihenfolge angewöhnt. Aber die Info sollen Sie haben.
Jetzt wird es aber wirklich interessant:
Unser Ausdruck WithEvents DerCmd ... steht uns nun hier zur Verfügung, um der Klasse den CommandButton zu übergeben.
Betrachten wir es für den CommandButton1:
Set oCommand1.DerCmd = CommandButton1
Mit dieser Zeile sage ich der Instanz der Klasse, dass sie sich auf den CommandButton1 bezieht.
Es ist eigentlich immer wieder das Gleiche:
Dim oBlatt as Worksheet Set oBlatt=ActiveSheet
Hier ist es nur ein klein wenig anderer Konstrukt aber vom Prinzip her ...
Im weiteren Verlauf der Initialize erzeugen wir einen CommandButton zu Laufzeit und Setten ihn auf unsere zweite Instanz der Klasse.
Vom Prinzip her die gleiche Vorgehensweise.
Sinn und ...
Gibt es denn einen Sinn, ein Ereignis eines Steuerelementes abzufangen, welches mir sowieso in meiner UF zur Verfügung steht ( wie bei CommandButton1) ?
Nicht wirklich aber dies diente nur der Demonstration, dass es auch bei zur Entwurfszeit kreierten Steuerelementen funktioniert.
Sinn gibt das Ganze erst wirklich bei dynamisch erstellent Steuerelementen, wie aufgezeigt.
Denn dort habe ich die Ereignisse ja nicht zur Entwurfszeit zur Verfügung!
Aber aber aber ....
Bevor Sie nun wild dynamisch Steuerlemente kreieren und mit Klassen traktieren wollen:
Es werden nur wenige Ereignisse unterstützt. Zumeist Klickereignisse.
Sie müssen selbst austesten, welches Steuerelement was unterstützt.
Es gibt eine Seite, die sich mit diesen Limitationen beschäftigt, die auch sehr zu empfehlen ist:
http://www.xlam.de/xlimits/index.htm
Zum Abschluss ein kleines Beispiel für dynamische Controls,
was ich mal vor längerer Zeit für ein Forum aus Spaß geschrieben hatte.
Sie benötigen eine leere Userform (darf ruhig etwas größer sein) und das Klassenmodul clsButton:
' **************************************************************
' Modul: UserForm1 Typ = Userform
' **************************************************************
'Code by Peter Haserodt 2002
Option Explicit
Dim aCommands(100) As New clsButton
Private Sub UserForm_Initialize()
Dim i As Integer, obTemp As MSForms.CommandButton
For i = 1 To 100
Set obTemp = Me.Controls.Add("Forms.CommandButton.1", "cmd" & i, True)
obTemp.Width = 25
obTemp.Height = 25
obTemp.Left = ((i - 1) Mod 10) * 30
obTemp.Top = (((i - 1) - ((i - 1) Mod 10)) / 10) * 30
obTemp.Caption = "" & i
obTemp.ControlTipText = "" & i
Set aCommands(i).DieCmds = obTemp
Next i
End Sub
' **************************************************************
' Modul: clsButton Typ = Klassenmodul
' **************************************************************
'Code by Peter Haserodt 2002
Option Explicit
Public WithEvents DieCmds As MSForms.CommandButton
Private Sub DieCmds_Click()
DieCmds.ControlTipText = "Geklickt"
DieCmds.BackColor = vbGreen
DieCmds.Font.Bold = True
End Sub
Events Application(Klassen [6])Weitere Artikel der Gruppe: Klassen Aus Excel VBA
Nach oben