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 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)
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:
- ✅ Mehrere Kunden gleichzeitig
- ✅ Logik gekapselt in der Klasse
- ✅ Wiederverwendbar in anderen Projekten
- ✅ Einfacher zu testen und debuggen
Erste Klasse erstellen (Class Module)
Schritt 1: Class Module einfügen
- VBA-Editor öffnen (Alt + F11)
- Einfügen → Klassenmodul
- Im Eigenschaftsfenster (F4): Name = "Customer"
Schritt 2: Eigenschaften definieren
Option Explicit
' Private Variablen (von außen nicht sichtbar)
Private pName As String
Private pNummer As Long
Private pEmail As String
Properties (Get/Let/Set) implementieren
Properties sind kontrollierte Zugriffsmethoden auf private Variablen.
Property Get (Wert lesen)
Name = pName
End Property
Property Let (Wert schreiben – für einfache Datentypen)
' 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)
Public Property Set Adresse(ByVal value As Address)
Set pAdresse = value
End Property
Public Property Get Adresse() As Address
Set Adresse = pAdresse
End Property
Read-Only Property
' 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.
' 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.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)
' Wird beim "New Customer" ausgeführt
pNummer = 0
pName = ""
Debug.Print "Neuer Kunde erstellt um " & Now
End Sub
Class_Terminate (Destruktor)
' 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
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)
' Später: Zugriff per Key
Dim gefunden As Customer
Set gefunden = kunden("1001")
Debug.Print gefunden.Name ' → "Max Mustermann"
Praxisbeispiel: Vollständige Customer-Klasse
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:
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
Call BerechneRabatt(kunde, betrag, datum)
' OOP (selbsterklärend):
kunde.BerechneEndpreis(betrag)
Best Practices für VBA-Klassen
- ✅ Option Explicit immer verwenden
- ✅ Private Variablen mit "p" oder "m_" prefixen
- ✅ Validierung in Properties einbauen (nicht blind schreiben)
- ✅ Read-Only Properties für berechnete Werte
- ✅ Fehlerbehandlung in Methoden (On Error GoTo)
- ✅ Kommentare für öffentliche Methoden
- ✅ Initialize für Standardwerte nutzen
- ✅ Terminate für Cleanup (Verbindungen schließen)
Wann OOP nutzen, wann nicht?
Nutzen Sie OOP wenn:
- Sie mehrere ähnliche Entitäten haben (Kunden, Produkte, Bestellungen)
- Komplexe Geschäftslogik strukturiert werden muss
- Code wiederverwendbar sein soll
- Mehrere Entwickler im Team arbeiten
Verzichten Sie auf OOP wenn:
- Es ein einfaches 20-Zeilen-Makro ist
- Einmalige Automatisierung ohne Wartung
- Performance kritisch ist (Klassen haben minimalen Overhead)
Fazit: VBA auf dem nächsten Level
Objektorientierte Programmierung macht aus VBA-Skripten professionelle Software:
- ✅ Klassen kapseln Daten und Logik
- ✅ Properties ermöglichen kontrollierte Zugriffe
- ✅ Methoden strukturieren Geschäftslogik
- ✅ Collections verwalten mehrere Objekte
- ✅ Events (Initialize/Terminate) für Setup/Cleanup
Investieren Sie Zeit in OOP – Ihr VBA-Code wird wartbarer, testbarer und professioneller!