Autor: Peter Haserodt  --- Aus Excel VBA - Gruppe: Klassen

Klassen [6] - Events [2] - Application

Autor: Peter Haserodt - Erstellt: --      - Letzte Revision: --Gruppenthema: 8 Folgen 1 2 3 4 5 6 7 8 Sie sind in Folge:7
Die Application Ereignisse abgreifen - einfach und doch tückisch

Jedem, der bis hier vorgedrungen ist, ist es bekannt, dass man auf Ereignisse in einer Mappe, in einem Sheet reagieren kann.
Ob Worksheet_Change oder was weiß ich ...

Aber diese Ereignisse sind Workbook gebunden und es kann durchaus interessant sein, die Ereignisse in der aktiven Application zu verfolgen.


Weiterhin gibt es Ereignisse, die dass Application Object zur Verfügung stellt, die im Workbook nicht zur Verfügung stehen.


Die Testumgebung:

Hier habe ich versucht, E97 freundlich zu sein, also das man dies auch dort gut testen kann.
Für alle die VBA6 (ab E2000) benutzen, empfehle ich, die Userform nonmodal zu starten, da kann man noch besser die Ereignisse verfolgen, indem man die UF offen hat und ein paar Aktionen in Excel selbst ausführt.
(Und wenn jetzt ein besonders Schlauer sagt : Eh, dass kann man doch auch in E97 mit Api etc.. dann soll er das machen und glücklich werden)


Erstellen Sie eine Userform mit 1 Commandbutton und ein Klassenmodul namens clsExcelApp

Klicken Sie dann auf CommandButton1 und verfolgen Sie die MsgBoxen.



' **************************************************************
'  Modul:  clsExcelApp  Typ = Klassenmodul
' **************************************************************

Option Explicit
Public WithEvents ExcelWatch As Application
	
Private Sub ExcelWatch_WorkbookActivate(ByVal Wb As Workbook)
	MsgBox "Das Workbook " & Wb.Name & " wurde aktiviert"
End Sub
	
Private Sub ExcelWatch_SheetActivate(ByVal Sh As Object)
	MsgBox "Das Sheet " & Sh.Name & " von Mappe: " & _
	Sh.Parent.Name & " wurde aktiviert"
End Sub
	
Private Sub ExcelWatch_NewWorkbook(ByVal Wb As Workbook)
	MsgBox "Es wurde eine neue Mappe: " & Wb.Name & " erstellt"
End Sub


' **************************************************************
'  Modul:  UserForm1  Typ = Userform
' **************************************************************

Option Explicit
Dim oKlasseExcel As clsExcelApp
	
Private Sub CommandButton1_Click()
	Workbooks.Add
	If Sheets.Count > 2 Then Sheets(2).Activate
	ThisWorkbook.Activate
End Sub
	
Private Sub UserForm_Initialize()
	Set oKlasseExcel = New clsExcelApp
	Set oKlasseExcel.ExcelWatch = Application
End Sub
	
Private Sub UserForm_Terminate()
	Set oKlasseExcel = Nothing
End Sub

Kurze Code Analyse

Viel erklären muss ich hier nicht, da alles aus den Ereignissen mit Steuerelementen bekannt ist.
Bei WithEvents vergebe ich den Namen und habe hier nun die Application als Objekt und nicht mehr ein Steuerelement der Userform. Ansonsten sollte es uns alles bekannt vorkommen (Bis auf die spezifischen Ereignisse)

In der Userform haben wir einfach einen Testcode, um die Ereignisse zu verfolgen.
Experimentieren Sie selbst ein wenig damit.

Die Onlinehilfe im Zwielicht

Ein großes Problem mit Ereignissen der Application ist die Onlinehilfe.
Hier wird schon über alle Excelversionen hinweg sehr unglücklich agiert. (selbst in E2003)


Um sich die möglichen Ereignisse anzuschauen, gibt man in der OH Ereignisse ein und sucht dann nach Ereignissen des Applicationobjektes (jedenfalls ab E2000 in der OH)

Dort bekommt man auch eine schöne Liste, die durch verschiedene Schriftdicken auch zeigt,ob dies zusätzliche Ereignisse der Application sind (z.B. NewWorkbook)

Aber ab hier ist man dem eigenen Verständnis ausgeliefert und am Anfang chancenlos.
Schaut man sich das Beispiel zu NewWorkbook an, wird der Zusammenhang mit der Klasse noch einigermaßen verständlich.

Gemein wird es bei Ereignissen, die auch im Workbook zur Verfügung stehen, z.B. SheetActivate oder SheetBeforeRightClick und die auch auf diese Art vom Objekt genutzt werden.
(Schauen Sie es sich an, ich will es nicht hier hinein kopieren)

Tatsächlich unterscheiden diese beiden sich schon ob überhaupt ein Hinweis auf das Application Objekt gegeben wird.

Viel schlimmer ist es aber, dass das Beispiel jeweils sich auf das Workbook bezieht.
Zwar steht oben ein Hinweis Application oder Workbook aber wie soll das ein Einsteiger in Klassen jemals verstehen.

Ich komme in der Hilfe aus Ereignissen mit dem Application Objekt, bekomme aber dort kein Beispiel wie ich es in einer Klasse anwende.

Tatsächlich müssen Sie in diesen Beispielen immer nur Workbook (vor der Ereignisbezeichnung) durch Ihre WithEvents Variable ersetzen.

Betrachten wir es für unser Beispiel:

In der Onlinehilfe steht:
Private Sub Workbook_
SheetActivate(ByVal Sh As Object)
MsgBox Sh.Name
End Sub


Um dieses Ereignis in unserer Klasse zu nutzen, mussten wir nur Workbook durch ExcelWatch ersetzen.

Ganz verwirrend wird es aber, wenn man sich das Ereignis WorkbookNewSheet anschaut.
Dies hat im Beispiel :
App_WorkbookNewSheet
Wir können es erahnen. Hier muss ich App durch meinen Namen ExcelWatch ersetzen.
(Tatsächlich gibt es das Ereignis ja auch im Workbook - NewSheet, hier wird aber ein anderer Ereignisname eingesetzt)

Zusammengefasst : Wie bringe ich die Beispiele in der OH zum laufen:

Letztendlich sollte ein kleiner Merksatz genügen (aber ohne Garantie):

Ich ersetze den Ausdruck in der OH der vor dem ersten Underscore steht mit meiner WithEvents Variablen





Zum Schluss ein paar weitere Tipps und Bemerkungen:

Selbstverständlich sollten Sie erstmal mit Ereignissen experimentieren, weitere Ereignisse implementieren.
Mit der gezeigten Testumgebung sollte dies kein Problem darstellen.

Eine Userform als Conatainer für unseren Klassenbezug ist relativ unproblematisch, da ich die Klasse dort initialisiere.
(Tatsächlich ist es ein interessantes Übungsobjekt, eine nonmodale UF mit einem TreeView aufzubauen, welches jeweils die aktuellen Mappen und deren Tabellen anzeigt- nur dass man leider irgendwas einbauen muss, um nach einem BeforeClose Event zu prüfen ob die Mappe auch wirklich geschlossen wurde, eine Art Timer. Viel Spass mit diesem Experiment, ich versichere Ihnen, dass man dies "weitgehend" machen kann.)

Häufiger werde ich aber die Klasse in einem Workbook verankern und im WorkbookOpen diese initialisieren.
(Und im BeforeClose natürlich terminieren)

Aber gerade während der Testphase sollte man hier aufpassen, da bei Codeänderungen sich da schnell der Bezug verliert.
Hier empfehle ich eine Art StartProzedur zu schreiben, mit der man dies immer wieder ankicken kann.
(Wer sich bis hierher durchgetankt hat, sollte mit diesem Hinweis etwas anfangen können)

Vergessen darf man aber auch nicht, dass diese Ereignisse über EnableEvents auch ausgeschaltet werden könnten und dass man sich nie sicher sein kann ob die Ereignisse ausgelöst werden (Wenn Fremdmappen involviert werden)

Aber hier sollte auch nur gezeigt werden , wie und dass es funktioniert.

Eigene Events(Klassen [7])

Weitere Artikel der Gruppe: Klassen Aus Excel VBA
Nach oben