HERBERS Excel-Forum - VBA-Basics

Thema: Klassenmodule

Inhaltsverzeichnis
  • 1 Die Module
  • 2 Allgemeingültiges Worksheet_Change-Ereignis
  • 3 Eine Ereignisprozedur für mehrere CommandButtons
  • 4 Ein- und Auslesen einer Kundenliste
  • 5 Ereignissteuerung einer Serie von Labels
  • Die Module

    Module sind Container für Code und für Variablen. Code ist jede Funktion, die einen oder mehrere Werte zurückgibt oder ein Makro, dass keine Werte zurückliefert. Ein Modul ist also ein Container für VBA-Routinen.

    Excel/VBA kennt Standard- und Klassenmodule. In Standardmodule wird Code zum allgemeinen Programmablauf hinterlegt, Klassenmodule verwalten Objekte mit ihren Eigenschaften, Methoden und Ereignissen.

    In Excel gibt es eine Vielzahl von vordefinierten Klassen, um einige zu nennen:

    • WorkBook
      In der Entwicklungsumgebung standardmäßig mit dem Objektnamen DieseArbeitsmappe bzw. ThisWorkbook benannt.

    • WorkSheet
      In der Entwicklungsumgebung standardmäßig mit den jeweiligen Arbeitsblattnamen benannt.

    • Chart
      In der Entwicklungsumgebung standardmäßig mit den jeweiligen Chart-Namen benannt.

    • UserForm
      In der Entwicklungsumgebung standardmäßig mit dem jeweiligen UserForm-Namen benannt.

    Die vorgenannten eingebauten Excel-Klassen können mit ihren Ereignissen in neue Klassen eingebunden werden. Sinnvoll ist dies beispielsweise, wenn eine Worksheet_Change-Ereignisprozedur allgemeingültig werden, sich also nicht nur auf die Arbeitsmappe beschränken soll, in der sich der Code befindet.

    Allgemeingültiges Worksheet_Change-Ereignis

    Hier wird eine dem WorkBook-Objekt übergeordnete Klasse, also das Application-Objekt als Ausgangspunkt benötigt. In der Entwicklungsumgebung wird über das Menü Einfügen ein neues Klassenmodul erstellt. Der Name des neuen Klassenmoduls kann mit dem Aufruf der Eigenschaften mit der F4-Taste geändert werden.

    In das Klassenmodul wird zum einen eine Public-Variable für das Ereignis des Application-Objekts und zum anderen der zugehörige Ereigniscode eingetragen:

    
    Public WithEvents App As Application
    
    Private Sub App_SheetChange( _
       ByVal Sh As Object, _
       ByVal Target As Range)
       MsgBox "Zelle " & Target.Address(False, False) & _
          " aus Blatt " & ActiveSheet.Name & _
          " aus Arbeitsmappe " & ActiveWorkbook.Name & _
          " wurde geändert!"
    End Sub
    
    

    In der Workbook_Open-Prozedur wird die neue App-Klasse deklariert und initialisiert:

    
    Dim AppClass As New clsApp
    
    Private Sub Workbook_Open()
       Set AppClass.App = Application
    End Sub
    

    Eine Ereignisprozedur für mehrere CommandButtons

    In das Klassenmodul wird zum einen eine Public-Variable für das Ereignis des CommandButton-Objekts und zum anderen der zugehörige Ereigniscode eingetragen:

    
    Public WithEvents Btn As CommandButton
    
    Private Sub Btn_Click()
       MsgBox "Aufruf erfolgt von Schaltfläche " & Right(Btn.Caption, 1)
    End Sub
    
    

    Die Deklaration und Initialisierung der Btn-Klasse erfolgt in der Workbook_Open-Prozedur:

    
    Dim CntBtn(1 To 4) As New clsButton
    
    Private Sub Workbook_Open()
       Dim intCounter As Integer
       For intCounter = 1 To 4
          Set CntBtn(intCounter).Btn = ThisWorkbook.Worksheets("Buttons").OLEObjects(intCounter).Object
       Next intCounter
    End Sub
    

    Ein- und Auslesen einer Kundenliste

    Zusätzlich zu diesen vordefinierten können neue, benutzerdefinierte Klassen geschaffen werden, mit denen es auf programmiertechnisch elegante Art möglich ist, eigene Typen zu bilden und z.B. mit Plausibilitätsprüfungsroutinen auf dies zuzugreifen.

    In das Klassenmodul werden zum einen die Public-Variablen für Elemente des Kunden-Objekts und zum anderen eine Prüfroutine eingetragen:

    
    Option Explicit
    Public strNA As String
    Public strNB As String
    Public strS As String
    Public strC As String
    Public strPLZ As String
    
    Property Let strP(strP As String)
       If Not IsNumeric(strP) Then
          MsgBox strP & " ist eine ungültige Postleitzahl"
          strPLZ = "?????"
       Else
          strPLZ = strP
       End If
    End Property
    

    Die Deklaration und die die allgemeinen Codes werden in einem Standardmodul hinterlegt:

    
    Dim NeuerKunde As New clsKunden
    Dim colKunden As New Collection
    
    Sub Einlesen()
       Dim intCounter As Integer
       Set colKunden = Nothing
       For intCounter = 2 To 11
          Set NeuerKunde = New clsKunden
          With NeuerKunde
             .strNA = Cells(intCounter, 1).Value
             .strNB = Cells(intCounter, 2).Value
             .strS = Cells(intCounter, 3).Value
             .strP = Cells(intCounter, 4).Value
             .strC = Cells(intCounter, 5).Value
          End With
          colKunden.Add NeuerKunde
       Next intCounter
    End Sub
    
    Sub AdressenAusgeben()
       Dim knd As clsKunden
       For Each knd In colKunden
          With knd
             MsgBox .strNA & vbLf & .strNB & vbLf & .strS & _
                  vbLf & .strPLZ & " " & .strC
          End With
       Next
    End Sub
    
    

    Ereignissteuerung einer Serie von Labels

    Mit den nachfolgenden Prozeduren werden 256 Labels einer UserForm mit MouseMove, MouseClick- und anderen Ereignissen versehen.

    In das Klassenmodul werden zum einen die Public-Variable für die Ereignisse des Label-Objekts und zum anderen die zugehörigen Ereigniscodes eingetragen:

    
    Public WithEvents LabelGroup As MSForms.Label
    
    Private Sub LabelGroup_Click()
       With frmChar.txtString
          .Text = .Text & Me.LabelGroup.Caption
       End With
    End Sub
    
    Private Sub LabelGroup_DblClick( _
       ByVal Cancel As MSForms.ReturnBoolean)
       frmChar.txtString.Text = Me.LabelGroup.Caption
    End Sub
    
    Private Sub LabelGroup_MouseDown(ByVal Button As Integer, _
       ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
       Me.LabelGroup.ForeColor = &H80000009
       Me.LabelGroup.BackColor = &H80000012
    End Sub
    
    Private Sub LabelGroup_MouseMove(ByVal Button As Integer, _
       ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
       Dim strChar As String
       Dim intChar As Integer
       frmChar.lblChar.Caption = Me.LabelGroup.Caption
       strChar = Me.LabelGroup.Name
       intChar = CInt(Right(strChar, Len(strChar) - 5)) - 1
       frmChar.lblShortCut.Caption = "Alt+" & intChar
       frmChar.lblZeichen.Caption = "=ZEICHEN(" & intChar & ")"
    End Sub
    
    Private Sub LabelGroup_MouseUp(ByVal Button As Integer, _
       ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
       Me.LabelGroup.ForeColor = &H80000012
       Me.LabelGroup.BackColor = &H80000009
    End Sub
    
    

    Die Deklaration und Initialisierung der Labels-Klasse erfolgt in einem Standardmodul:

    
    Dim Labels(1 To 256) As New clsFrm
    
    Sub ClsSymbolAufruf()
       Dim intCounter As Integer
       For intCounter = 1 To 256
          Set Labels(intCounter).LabelGroup = frmChar.Controls("Label" & intCounter)
       Next intCounter
       frmChar.Show
    End Sub