Objekte in VBA

Definition eines Objekts:

Ein Objekt ist eine Gruppierung von Daten und Prozeduren (z. B. Funktionen und Subs). Die Prozeduren werden verwendet, um Aufgaben auszuführen, die sich auf die Daten beziehen. Die Prozeduren werden auch als Methoden bezeichnet. Die von außen sichtbaren Daten werden als Eigenschaften bezeichnen. Objekte besitzen also Eigenschaften, können Methoden ausführen oder auf Ereignisse reagieren.

Objekte werden verwendet, um reale oder computerbasierte Gegenstände darzustellen. Objekte stellen ihre Funktionalität über offen gelegte Eigenschaften, Methoden und Funktionen zur Verfügung. Die eigentliche Funktionalität wird gekapselt, d. h. die Implementierungsdetails werden verborgen. Nutzer der Objekte brauchen die innere Funktionalität nicht zu kennen, um mit den Objekten umzugehen. Durch diese Kapselung kann man den Programmablauf übersichtlicher gestalten und besser verstehen.

 

Klassen

Untrennbar mit Objekten verbunden sind Klassen. Klassen sind die Vorlagen für die Objekte. Sie enthalten den eigentlichen
Programmcode, für die die daraus erzeugten Objekte. Mit einer Klasse lassen sich beliebig viele gleichartige Objekte erzeugen, die aber unabhängig voneinander existieren.

Ist VBA eine objekt-orientierte Programmiersprache?

Streng genommen ist VBA keine objekt-orientierte Programmiersprache. Wichtige Konzepte der objekt-orientierten Programmierung wie Vererbung oder Polymorphismus werden von VBA nicht unterstützt (in der Abbildung rot markiert). VBA teilt aber immer noch viele Konzepte von objekt-orientierten Programmiersprachen (in der Abbildung grün markiert).

Vordefinierte Objekte in Excel VBA

In Excel gibt es etwa 200 vordefinierte Objekte, die hierarchisch organisiert sind.  Ein Ausschnitt der Excel VBA Objekt Hierarchie ist  in der Abbildung gezeigt.

Ein Beispiel ist das Worksheet Objekt in VBA. Es hat Eigenschaften und Methoden:

  • Beispiele für Eigenschaften sind:
    Index – Index des Worksheets
    Name – Name des Worksheets
  • Beispiele für Methoden sind
    Activate – Legt das aktuelle Tabellenblatt (engl. Worksheet) als aktives Tabellenblatt fest.
    Delete – Löscht das Tabellenblatt

Das Worksheet Objekt hat viele weitere Eigenschaften und Methoden.

Eigene Objekte erstellen

Objekte werden über Klassen erzeugt. Eine Klasse beschreibt den Aufbau eines Objekts mit seinen Attributen und Methoden. Ein Objekt ist eine „Instanz“ einer Klasse.

Schritt 1: eine Klasse erstellen

Der erste Schritt besteht darin im Visual Basic Editor ein Klassenmodul einzufügen. Hierzu klickt man im Reiter „Einfügen“ auf Klassenmodul.

Im Projekt Explorer ist das neu angelegte Klassenmodul „Klasse1“  zu sehen. Der Name des Klassenmoduls lässt sich in den gewünschen Namen ändern. Dann wird das Klassenmodul mit Code befüllt.

Im Eigenschaftsfenster für die Klasse (in der Abbildung links unten) lässt sich der Name des Klassenmoduls in den gewünschen Namen ändern.

Beispiel:

In folgendem Beispiel wird die Klasse „clsAktie“ erstellt und mit Code befüllt.

Am Anfang des Klassenmoduls werden die Eigenschaftsvariablen deklariert. Der Schreib- oder Lesezugriff auf die Eigenschaftsvariablen erfolgt über Eigenschaftsprozeduren. Die Syntax der Eigenschaftsprozeduren ist
Property Let (Wert setzen)
Property Get (Wert auslesen)

Option Explicit
' Eigenschaften
Private AktienName As String
Private CurDate As Date
Private strISIN As String
Private strWKN As String
Private dblKurs As Double
Private dblDividendenRendite As Double
'
Private Sub Class_Initialize()
End Sub
'
Private Sub Class_Terminate()
End Sub
'
Public Property Let Name(strName As String)
AktienName = strName
End Property
Public Property Let Datum(cDatum As Date)
CurDate = cDatum
End Property
Public Property Let ISIN(sISIN As String)
strISIN = sISIN
End Property
Public Property Let WKN(sWKN As String)
strWKN = sWKN
End Property
Public Property Let Kurs(dKurs As Double)
dblKurs = dKurs
End Property
Public Property Let DividendenRendite(dDividentenRendite As Double)
dblDividendenRendite = dDividentenRendite
End Property
'
Public Property Get Name() As String
Name = AktienName
End Property
Public Property Get Datum() As Date
Datum = CurDate
End Property
Public Property Get ISIN() As String
ISIN = strISIN
End Property
Public Property Get WKN() As String
WKN = strWKN
End Property
Public Property Get Kurs() As Double
Kurs = dblKurs
End Property
Public Property Get DividendenRendite() As Double
DividendenRendite = dblDividendenRendite
End Property
'
' Methode
Public Sub Ausgabe()
Debug.Print "Aktie: " & AktienName & ", Datum: " & CurDate & ", ISIN: " & strISIN & ", Kurs: " & dblKurs & " €, Dividendenredite: " & dblDividendenRendite
End Sub

In den ersten Zeilen werden die Eigenschaften der Klasse deklariert. Mit „Public Property Let“ werden die Eigenschaften gesetzt. Mit „Public Property Get“ werden die Eigenschaften zurückgegeben.

Schritt 2: ein Objekt durch Instanziierung erzeugen

Objekte werden durch Objektvariable dargestellt. Objektvariable sind Variable, die auf ein Objekt verweisen.

Deklaration einer Objektvariablen

Objektvariable werden mit einer Dim-Anweisung unter Zuweisung des Objekttyps deklariert. Die Syntax ist
Dim Objektvariable As Objekttyp

Wird in der Deklaration das Schlüssekwort „New“ verwendet, wird zusätzlich zur Deklaration eine neue Instanz des Objekttyps erstellt. Dies wird als Autoinstanziierende Variable bezeichnet. Die Syntax ist
Dim Objektvariable As New Objekttyp
Die Verwendung der Set-Anweisung für die Instanziierung bietet allerdings mehr Möglichkeiten und ist daher zu empfehlen.

Set-Anweisung

Die Set-Anweisung weist einer Objektvariablen einen Verweis auf ein Objekt zu. Wird das Schlüsselwort New in der Set-Anweisung verwendet, wird eine neue Instanz einer Klasse erstellt. Die Syntax ist
Set Objektvariable = {[ New ] Objektausdruck | Nothing }
wobei

  • Objektvariable  –  Name der Variable
  • New  –  Optional. wird verwendet, um eine neue Instanz einer Klasse zu erstellen. Wenn die Variable „Objektvariable“ bereits einen Verweis auf ein Objekt enthält, wird dieser Verweis beim Zuweisen des neuen Verweises freigegeben.
  • Objektausdruck  –  Name eines Objekts, einer deklarierten Variable des gleichen Objekttyps oder einer Funktion oder Methode die ein Objekt des gleichen Objekttyps zurückgibt.
  • Nothing  –  Optional. Löscht den Verweis der Variablen „Objektvariable“ auf das spezifische Objekt. Der Speicherplatz für die Variable Objektvariable“ wird freigegeben.

Beispiel 1: Verwendung des VBA Worksheet Objekts

Im ersten Beispiel wird das Excel Objekt „Worksheet“ verwendet, da das einfach zu verstehen ist.

Sub Objektvariable1()
' Deklaration der Objektvariablen ws als Worksheet Objekt
Dim ws As Worksheet
' Der Objektvariablen ws einen Verweis auf das Worksheet Objekt für das
' Tabellenblatt "Tabelle1" zuweisen
Set ws = Worksheets("Tabelle1")
'
' Jetzt kann die Objektvariable die Eigenschaften und Methoden
' des Worksheet Objekts nutzen
ws.Cells(1, 1).Value = "Test"
Debug.Print ws.Cells(1, 1).Value
'
' Speicherplatz fuer die Objektvariable ws freigeben
Set ws = Nothing
End Sub

Beispiel 2: Verwendung der Klasse „clsAktie“

In der folgenden Sub Prozedur wird die erstellte Klasse „clsAktie“ verwendet. Objekte werden in VBA durch Objektvariable dargestellt. In der Prozedur wird die Variable „TempAktie“ wird als Objekt des Typs „clsAktie“ deklariert. Mit „Set TempAktie = New clsAktie“ wird das Objekt TempAktie des Typs „clsAktie“ instanziiert und anschließend mit Werten befüllt. Für die Befüllung wird die Punktnotation verwendet, z. B. „TempAktie.Name = “ (Name ist eine Eigenschaft des Objekts). Dann wird das Object dem Dictionary „AktienDictionary“ hinzugefügt. Dieser Vorgang wird für vier Aktien durchgeführt. Am Ende der Prozedur werden die Daten der angelegten Objekte im Dictionary AktienDictionary im Direktfenster ausgegeben.

Option Explicit
Sub Aktien()
Dim AktienDictionary    As Object
Dim TempAktie           As clsAktie
Dim varItem As Variant

Set AktienDictionary = CreateObject("Scripting.Dictionary")

Set TempAktie = New clsAktie
TempAktie.Name = "Porsche Automobil Holding SE"
TempAktie.Datum = "30.08.2022"
TempAktie.ISIN = "DE000PAH0038"
TempAktie.Kurs = 73.44
TempAktie.DividendenRendite = 0.0575
AktienDictionary.Add TempAktie.Name, TempAktie
'
Set TempAktie = New clsAktie
TempAktie.Name = "Infineon"
TempAktie.Datum = "30.08.2022"
TempAktie.ISIN = "DE0006231004"
TempAktie.Kurs = 25.2
TempAktie.DividendenRendite = 0.0138
AktienDictionary.Add TempAktie.Name, TempAktie
'
Set TempAktie = New clsAktie
TempAktie.Name = "HelloFresh"
TempAktie.Datum = "30.08.2022"
TempAktie.ISIN = "DE000A161408"
TempAktie.Kurs = 25.6
TempAktie.DividendenRendite = 0#
AktienDictionary.Add TempAktie.Name, TempAktie
'
Set TempAktie = New clsAktie
With TempAktie
     .Name = "Zalando"
     .Datum = "30.08.2022"
     .ISIN = "DE000ZAL1111"
     .Kurs = 24.2
     .DividendenRendite = 0#
End With
AktienDictionary.Add TempAktie.Name, TempAktie
'
For Each varItem In AktienDictionary
    Set TempAktie = AktienDictionary(varItem)
    ' Methode ausfuehren
    Call TempAktie.Ausgabe
Next
'
Set TempAktie = Nothing
Set AktienDictionary = Nothing
End Sub


With …. End With
Im Beispiel wird With ……. End With verwendet, um mehrere Aktionen für dasselbe Objekt auszuführen.

Interface

In VBA ist ein Interface (deutsch Schnittstelle) ein Template für eine Klasse. Ein Interface definiert Eigenschaften (Variablen) und Methoden (Subs oder Funktionen), die in der Klasse definiert werden sollten, die die Schnittstelle implementiert.

Beispiel

Im ersten Schritt werden Interface Eigenschaften und Methoden deklariert. Dabei ist zu beachten, dass in VBA ein Interface in einem VBA-Klassenmodul definiert werden muss. Im zweiten Schritt wird die Schnittstelle in 2 Beispielklassen implementiert.

Definition des Interfaces “IAuto”.

'Name der Klasse: IAuto
Public Name As String
Public TopSpeed As Long
Public Sub PrintInfo() ' Nur eine Deklaration ist ausreichend

Definition der Klasse „clsFordMustang“, die das Interface „IAuto“ implementiert:

' Name der Klasse: clsFordMustang
Implements IAuto
 
' Variablen zum Zweck der IAuto-Implementierung, das Präfix spielt keine Rolle
Private i_name As String
Private i_topSpeed As String
' Die Implementierung von IAuto-Variablen erfordert die Implementierung von Let- und Get-Eigenschaften
Private Property Let IAuto_Name(ByVal Name As String)
    i_name = Name
End Property
Private Property Get IAuto_Name() As String
   IAuto_Name = i_name
End Property
Private Property Let IAuto_TopSpeed(ByVal TopSpeed As Long)
    i_topSpeed = TopSpeed
End Property
Private Property Get IAuto_TopSpeed() As Long
   IAuto_TopSpeed = i_topSpeed
End Property
 
' Implementierung der Methoden des Interfaces "IAuto"
Private Sub IAuto_PrintInfo()
    Debug.Print "Automarke und Modell: " & IAuto_Name
    Debug.Print "Höchstgeschwindigkeit: " & IAuto_TopSpeed & " km/h"
End Sub
 
'Werte für den Ford Mustang definieren
Private Sub Class_Initialize()
    i_name = "Ford Mustang"
    i_topSpeed = "250" ' in [km/h]
End Sub

Definition der Klasse „clsVWGolf“, die das Interface „IAuto“ implementiert:

' Name der Klasse: clsVWGolf
Implements IAuto
 
' Variablen zum Zweck der IAuto-Implementierung, das Präfix spielt keine Rolle
Private i_name As String
Private i_topSpeed As String
' Die Implementierung von IAuto-Variablen erfordert die Implementierung von Let- und Get-Eigenschaften
Private Property Let IAuto_Name(ByVal Name As String)
    i_name = Name
End Property
Private Property Get IAuto_Name() As String
   IAuto_Name = i_name
End Property
Private Property Let IAuto_TopSpeed(ByVal TopSpeed As Long)
    i_topSpeed = TopSpeed
End Property
Private Property Get IAuto_TopSpeed() As Long
   IAuto_TopSpeed = i_topSpeed
End Property
 
' Implementierung der Methoden des Interfaces "IAuto"
Private Sub IAuto_PrintInfo()
    Debug.Print "Automarke und Modell: " & IAuto_Name
    Debug.Print "Höchstgeschwindigkeit: " & IAuto_TopSpeed & " km/h"
End Sub
 
' Werte für den VW Golf definieren
Private Sub Class_Initialize()
    i_name = "VW Golf"
    i_topSpeed = "202" ' in [km/h]
End Sub

Erstellen und Verwenden des Interfaces:

Sub Main()
Dim objFordMustang As New clsFordMustang
Dim objVWGolf As New clsVWGolf
Dim Autos(0 To 1) As IAuto, Auto As Variant

Set Autos(0) = objFordMustang
Set Autos(1) = objVWGolf

'Information fuer alle Autos ausgeben
For Each Auto In Autos
    Auto.PrintInfo
Next Auto
End Sub

Dank des VBA-Interfaces können jetzt alle Autoklassen ähnlich behandelt werden, was die Arbeit mit ihnen viel einfacher macht. Offensichtlich können jetzt eine für die Marke/das Modell des Autos spezifische Logik und einzigartige Methoden implementiert werden.

Dieser Beitrag hat 3 Kommentare

  1. Alois

    hallo
    habe wieder mal ein problem
    habe ein excel arbeitsblatt mit sehr vielen autoformen (Shapes) die ich bis auf 5 formen alle löschen möchte
    habe den vba code
    dim form as shape
    for each form in activesheet.shapes
    if form.name „dreieck“ or form.name“raute“ then shapes.delete
    next form
    das funktioniert aber leider nicht es werden alle shapes bis auf das erste (dreieck) gelöscht.
    mit einer if bedingung funktioniert das.
    ich weis das ich von dir noch sehr viel lernen kann und habe auch diesmal die hoffnung auf hilfe von dir.

    1. admin

      Hallo Alois,

      es ist nicht ganz einfach, Dein Problem nachzuvollziehen. Zunächst bin ich darüber gestolpert, dass Du unter VBA deutsche Namen für die Shapes verwendest und meiner Meinung nach fehlt im If Statement ein Gleichheitszeichen:
      if form.name = „dreieck“ or form.name = „raute“ then shapes.delete

      In einem ersten Schritt habe ich eine Excel Datei erstellt und verschiedene Autoformen eingefügt: ein gleichschenkliges Dreieck, ein Oval und eine Raute. Dann habe ich ein Skript geschrieben, um die Namen der Shapes auszugeben:

      Sub Shape_Namen_ausgeben()
      Dim form As Shape, ws As Worksheet
      Set ws = Worksheets(„Tabelle1“)
      For Each form In ws.Shapes
      Debug.Print form.Name
      Next form

      Set ws = Nothing
      End Sub

      Damit werden folgende Namen ausgegeben
      Isosceles Triangle 1
      Oval 2
      Diamond 3
      also der Name des Shapes gefolgt von seiner Nummer in der Liste der Shapes. In meinem Fall werden englische Namen für die Shapes ausgegeben.

      Mit folgendem Code kann ich beispielsweise das ovale Shape löschen:

      Sub Delete_Shape()
      Dim form As Shape, ws As Worksheet
      Set ws = Worksheets(„Tabelle1“)
      For Each form In ws.Shapes
      If InStr(1, form.Name, „Oval“) > 0 Then form.Delete
      Next form

      Set ws = Nothing
      End Sub

      Ich habe hier die InStr Funktion verwendet, da sich der Shape Name aus Namen und Nummer in der Liste der Shapes zusammensetzt. Den Befehl „shapes.delete“ konnte ich bei einer Internet Recherche leider nicht finden.

      Hilft Dir meine Antwort weiter?

      Viele Grüße

      Stefan

  2. Alois

    Hallo Stefan

    Sub Formen_löschen()
    ThisWorkbook.Worksheets(1).Activate
    Dim Form As Shape

    For Each Form In ActiveSheet.Shapes
    If Form.Name „Dreieck“ Then
    Form.Delete
    End If
    Next Form
    End Sub

    Der Code oben funktioniert einbandfrei es wird alles bis auf das Dreieck gelöscht (die deutschen Namen kommen daher weil ich die Namen im Excelblatt im Namensfeld selber benannt habe)

    Aber in meinem Blatt habe ich 5 Schaltflächen die ich eben nicht löschen möchte aber ich schaffe es nur eine nicht zu löschen ich hoffe jetzt verstehst du mein Gefassel etwas besser, Es ist dabei auch das Dreick und eine Schaltfläche über die ich mit alle verfügbaren Shapes von 1 – 183 anzeigen lassen und mit Index beschriften kann die möchte ich nach dem aussuchen des Shapes das ich einfügen möchte wieder löschen, also alle Shapes auf dem Blatt außer den benannten 5 Stück.
    Wie gesagt es funktioniert aber nur das erste angegebene bleibt stehen habe schon mehr Bedingungen probiert

    Sub Formen_löschen()
    ThisWorkbook.Worksheets(1).Activate
    Dim Form As Shape

    For Each Form In ActiveSheet.Shapes
    If Form.Name „Dreieck“ or Form.Name Raute Then (usw eben alle 5)
    Form.Delete
    End If
    Next Form
    End Sub

    Immer nur das erste bleibt erhalten.

    Nun aber genug

    Gruß und schönen Sonntag Alois

    Hoffe du hast verstanden was ich erreichen will.

Schreibe einen Kommentar