Objektorientierte Programmierung in VBA: Klassen erstellen

Lesezeit: 15 Minuten | Kategorie: VBA-Programmierung

Sie kennen VBA-Makros mit Subs und Functions – aber haben Sie schon eigene Klassen erstellt? Objektorientierte Programmierung (OOP) macht VBA-Code wartbarer, wiederverwendbarer und strukturierter. In diesem Advanced-Guide zeigen wir, wie Sie professionelle Klassen in VBA entwickeln.

Was ist OOP und warum in VBA?

Objektorientierte Programmierung bedeutet: Statt lose Funktionen zu schreiben, erstellen Sie Objekte mit Eigenschaften (Properties) und Methoden.

Beispiel: Kunde ohne OOP (prozedural)

Dim KundenName As String
Dim KundenNummer As Long
Dim KundenRabatt As Double

Sub KundeAnlegen(Name As String, Nummer As Long)
  KundenName = Name
  KundenNummer = Nummer
End Sub

Sub RabattBerechnen()
  If KundenNummer < 1000 Then
    KundenRabatt = 0.05
  Else
    KundenRabatt = 0.1
  End If
End Sub

Problem: Nur ein Kunde gleichzeitig, keine Struktur, schwer wartbar.

Mit OOP (objektorientiert)

Dim kunde1 As New Customer
kunde1.Name = "Max Mustermann"
kunde1.Nummer = 1234
Debug.Print kunde1.Rabatt ' → 0.1 (automatisch berechnet!)

Dim kunde2 As New Customer
kunde2.Name = "Anna Schmidt"
kunde2.Nummer = 500

Vorteile:

Erste Klasse erstellen (Class Module)

Schritt 1: Class Module einfügen

  1. VBA-Editor öffnen (Alt + F11)
  2. Einfügen → Klassenmodul
  3. Im Eigenschaftsfenster (F4): Name = "Customer"

Schritt 2: Eigenschaften definieren

' Klassenmodul: Customer
Option Explicit

' Private Variablen (von außen nicht sichtbar)
Private pName As String
Private pNummer As Long
Private pEmail As String
Namenskonvention: Prefix "p" für private Variablen (oder "m_" für "member variable").

Properties (Get/Let/Set) implementieren

Properties sind kontrollierte Zugriffsmethoden auf private Variablen.

Property Get (Wert lesen)

Public Property Get Name() As String
  Name = pName
End Property

Property Let (Wert schreiben – für einfache Datentypen)

Public Property Let Name(ByVal value As String)
  ' Validierung einbauen!
  If Len(value) > 0 Then
    pName = value
  Else
    Err.Raise 5, , "Name darf nicht leer sein!"
  End If
End Property

Property Set (für Objektreferenzen)

Private pAdresse As Address

Public Property Set Adresse(ByVal value As Address)
  Set pAdresse = value
End Property

Public Property Get Adresse() As Address
  Set Adresse = pAdresse
End Property
Regel: Let für Strings/Zahlen/Dates, Set für Objekte (Range, Worksheet, eigene Klassen).

Read-Only Property

Public Property Get Rabatt() As Double
  ' Automatisch berechnet, kein Let/Set!
  If pNummer < 1000 Then
    Rabatt = 0.05 ' 5%
  Else
    Rabatt = 0.1 ' 10%
  End If
End Property

Methoden implementieren

Methoden sind Functions oder Subs innerhalb der Klasse.

Public Function BestellungAufgeben(Betrag As Double) As Boolean
  ' Geschäftslogik
  If Betrag <= 0 Then
    BestellungAufgeben = False
    Exit Function
  End If

  ' Rabatt anwenden
  Dim Endpreis As Double
  Endpreis = Betrag * (1 - Me.Rabatt)

  ' Logging
  Debug.Print pName & " bestellt für " & Format(Endpreis, "0.00 €")

  BestellungAufgeben = True
End Function
Me-Keyword: Verwenden Sie Me.Rabatt statt Rabatt innerhalb der Klasse – macht klarer, dass es sich um eine Property handelt.

Initialize und Terminate Events

Diese speziellen Events werden automatisch ausgeführt.

Class_Initialize (Konstruktor)

Private Sub Class_Initialize()
  ' Wird beim "New Customer" ausgeführt
  pNummer = 0
  pName = ""
  Debug.Print "Neuer Kunde erstellt um " & Now
End Sub

Class_Terminate (Destruktor)

Private Sub Class_Terminate()
  ' Wird ausgeführt wenn Objekt freigegeben wird
  Debug.Print "Kunde " & pName & " wird gelöscht"
  ' Aufräumen: Datenbankverbindungen schließen, etc.
End Sub

Collections von Objekten

Mit Collections verwalten Sie mehrere Objekte gleichzeitig.

Kunden-Collection erstellen

Sub KundenVerwaltung()
  Dim kunden As New Collection

  ' Kunden hinzufügen
  Dim k1 As New Customer
  k1.Name = "Max Mustermann"
  k1.Nummer = 1001
  kunden.Add k1

  Dim k2 As New Customer
  k2.Name = "Anna Schmidt"
  k2.Nummer = 500
  kunden.Add k2

  ' Alle Kunden durchgehen
  Dim kunde As Customer
  For Each kunde In kunden
    Debug.Print kunde.Name & " - Rabatt: " & kunde.Rabatt
  Next kunde
End Sub

Collection mit Key (eindeutige ID)

kunden.Add k1, CStr(k1.Nummer) ' Key = Kundennummer

' Später: Zugriff per Key
Dim gefunden As Customer
Set gefunden = kunden("1001")
Debug.Print gefunden.Name ' → "Max Mustermann"

Praxisbeispiel: Vollständige Customer-Klasse

' Klassenmodul: Customer
Option Explicit

Private pNummer As Long
Private pName As String
Private pEmail As String
Private pErstellt As Date

' === PROPERTIES ===
Public Property Get Nummer() As Long
  Nummer = pNummer
End Property

Public Property Let Nummer(ByVal value As Long)
  If value > 0 Then
    pNummer = value
  Else
    Err.Raise 5, , "Kundennummer muss > 0 sein"
  End If
End Property

Public Property Get Name() As String
  Name = pName
End Property

Public Property Let Name(ByVal value As String)
  If Len(Trim(value)) > 0 Then
    pName = Trim(value)
  Else
    Err.Raise 5, , "Name darf nicht leer sein"
  End If
End Property

Public Property Get Email() As String
  Email = pEmail
End Property

Public Property Let Email(ByVal value As String)
  If InStr(value, "@") > 0 Then
    pEmail = LCase(Trim(value))
  Else
    Err.Raise 5, , "Ungültige E-Mail-Adresse"
  End If
End Property

Public Property Get Rabatt() As Double
  ' Geschäftslogik: Stammkunden bekommen mehr
  If pNummer < 1000 Then
    Rabatt = 0.05
  ElseIf pNummer < 5000 Then
    Rabatt = 0.1
  Else
    Rabatt = 0.15
  End If
End Property

' === METHODEN ===
Public Function BerechneEndpreis(Bruttopreis As Double) As Double
  BerechneEndpreis = Bruttopreis * (1 - Me.Rabatt)
End Function

Public Sub SendeEmail(Betreff As String, Text As String)
  ' Hier: Outlook-Integration
  Debug.Print "E-Mail an " & pEmail & ": " & Betreff
End Sub

' === EVENTS ===
Private Sub Class_Initialize()
  pErstellt = Now
  pNummer = 0
  pName = ""
  pEmail = ""
End Sub

Private Sub Class_Terminate()
  ' Cleanup
End Sub

Verwendung:

Sub TestCustomerKlasse()
  Dim kunde As New Customer

  kunde.Nummer = 1234
  kunde.Name = "PREDOC GmbH"
  kunde.Email = "[email protected]"

  Debug.Print "Rabatt: " & Format(kunde.Rabatt, "0%")
  Debug.Print "1000€ kosten: " & kunde.BerechneEndpreis(1000) & "€"

  kunde.SendeEmail "Angebot", "Vielen Dank..."
End Sub

Vorteile gegenüber prozeduralem Code

1. Wiederverwendbarkeit

Kopieren Sie das Klassenmodul in andere Projekte → Sofort einsatzbereit!

2. Wartbarkeit

Änderungen nur an einer Stelle (in der Klasse) statt in 50 Subs verstreut.

3. Datenkapselung

Private Variablen können nicht von außen verändert werden → Validierung erzwingbar!

4. Testbarkeit

Klassen können isoliert getestet werden.

5. Lesbarkeit

' Prozedural (unklar):
Call BerechneRabatt(kunde, betrag, datum)

' OOP (selbsterklärend):
kunde.BerechneEndpreis(betrag)

Best Practices für VBA-Klassen

Wann OOP nutzen, wann nicht?

Nutzen Sie OOP wenn:

Verzichten Sie auf OOP wenn:

Fazit: VBA auf dem nächsten Level

Objektorientierte Programmierung macht aus VBA-Skripten professionelle Software:

Investieren Sie Zeit in OOP – Ihr VBA-Code wird wartbarer, testbarer und professioneller!


Das könnte Sie auch interessieren:

VBA-Projekt anfragen