CreateObject in VBA
Objekterzeugung
Die Funktion »VBA.Interaction.CreateObject« ergibt ein neues Objekt der Klasse, deren Namen ihr als Argument übergeben wird.
Ein Objekt einer Klasse nennt man auch ein Exemplar jener Klasse.
Im folgenden Programm wird ein neues Exemplar der Klasse »Scripting.Dictionary« angelegt. Die Objektvariable »O« wird dann an jenes Objekt gebunden.
Modul1
Option Explicit
Sub Main()
Dim O As Object
Debug.Print VBA.Information.VarType( O )
Debug.Print VBA.Information.TypeName( O )
Debug.Print VBA.Information.IsObject( O )
Debug.Print
Set O = VBA.Interaction.CreateObject( "Scripting.Dictionary" )
Debug.Print VBA.Information.VarType( O )
Debug.Print VBA.Information.TypeName( O )
Debug.Print VBA.Information.IsObject( O )
Stop
End Sub
transcript
9
Nothing
Wahr
9
Dictionary
Wahr
Welche Klassennamen verwendet werden können, hängt von der Version des Betriebssystems und der darauf installierten Software ab. Die Klasse mit dem Namen »Scripting.Dictionary« gehört zur Software “Windows Script Host ” (früher: “Windows Scripting Host ”), die auf aktuellen Windows -Versionen vorhanden sein sollte (Stand 2015).
Die für »VBA.Interaction.CreateObject« verwendeten Klassen können übrigens nicht nur in VBA, sondern auch in verschiedenen anderen Programmiersprachen verwendet werden.
Prozeduren in Objekten
Objekte können Prozeduren enthalten. Welche Prozeduren ein Objekt enthält, wird durch die Klasse des Objekts bestimmt.
Prozeduren, die in einem Objekt enthalten sind, werden auch als Methoden bezeichnet.
Ein Objekt der Klasse »Scripting.Dictionary« stellt ein Wörterbuch bereit, zu dem mit dem enthaltenen Sub »Add« Einträge hinzugefügt werden können.
Ein Eintrag eines Wörterbuchs ist ein Paar, welches aus einem Schlüssel und einer Variablen besteht. (Diese Variable wurde aber nicht von unserem Programm dimensioniert und hat in unserem Programm keinen eigenen Namen.)
Mit der enthaltenen Funktion »Item« kann die Variable eines Schlüssels dann wieder abgefragt werden.
Eine Prozedur eines Objekts kann wie die uns bisher bekannten Prozeduren aufgerufen werden, dabei ist dem Aufruf ein Ausdruck für das die Prozedur enthaltende Objekt mit einem Punkt ».« getrennt voranzustellen.
Bei Schlüsseln ist die Groß- und Kleinschreibung signifikant, wenn nichts anderes eingestellt wurde, das heißt, ein kleines »a« ist ein anderer Schlüssel als ein großes »A«.
Modul1
Option Explicit
Sub Main()
Dim V As Object
Set V = CreateObject( "Scripting.Dictionary" )
V.Add "A", "Anton"
V.Add "B", "Berta"
Debug.Print V.Item( "A" )End Sub
transcript
Anton
Wird ein Schlüssel abgefragt, der nicht definiert wurde, ergibt sich keine Fehlermeldung sondern ein Objekt vom Typ »Empty«, welches das Fehlen eines Wertes ausdrückt.
Modul1
Option Explicit
Sub Main()
Dim V As Object
Set V = CreateObject( "Scripting.Dictionary" )
Debug.Print V.Item( "A" )
Debug.Print VBA.Information.TypeName( V.Item( "A" ))End Sub
Protokoll
Empty
Objekte können Informationen über ihre gesamte Existenz hinweg speichern, wie wir ja schon an Feldern wie »VBA.Err.Number« gesehen haben. Dadurch kann die Methode »Item« eine Information aus dem Verzeichnisobjekt »V« zurückgeben, die zuvor mit der Methode »Add« in dieses Objekt geschrieben wurde.
Im folgenden Beispiel werden zwei Objektvariablen an dasselbe Objekt gebunden. Sie sind danach dann praktisch überall miteinander austauschbar.
Das Feld »Count« enthält die Anzahl der in einem Wörterbuch eingetragenen Paare.
Modul1
Option Explicit
Sub Main()
Dim V As Object
Dim W As Object
Set V = CreateObject( "Scripting.Dictionary" )
Set W = V
V.Add "A", "Anton"
W.Add "B", "Berta"
Debug.Print W.Item( "A" )
Debug.Print V.Count
Debug.Print W.CountEnd Sub
transcript
Anton
2
2
Im folgenden Beispiel werden zwei verschiedene Objekte angelegt.
Modul1
Option Explicit
Sub Main()
Dim V As Object
Dim W As Object
Set V = CreateObject( "Scripting.Dictionary" )
Set W = CreateObject( "Scripting.Dictionary" )
V.Add "A", "Anton"
W.Add "A", "Alpha"
Debug.Print V.Item( "A" )
Debug.Print W.Item( "A" )
Debug.Print V.Count
Debug.Print W.CountEnd Sub
transcript
Anton
Alpha
1
1- Dokumentation der Zuordnungsklasse »Scripting.Dictionary«
https://msdn.microsoft.com/en-us/library/x4k5wbx4(v=vs.84).aspx
Das Lokalfenster
Modul1
Option Explicit
Sub Main()
Dim V As Object
Set V = CreateObject( "Scripting.Dictionary" )
V.Add "A", "Anton"End Sub
Aktuelle Informationen über ein Objekt können während des Programmablaufs betrachtet werden, indem das Lokal-Fenster geöffnet (Ansicht>Lokal-Fenster) oder eine Überwachung zu der Variablen »V« hinzugefügt wird (Kontextmenü>Überwachung hinzufügen…).
Wenn das Programm dann im Einzelschrittmodus ausgeführt wird (F8), kann man nach jedem Schritt das Objekt in »V« inspizieren (im Lokal-Fenster oder im Fenster „Überwachungsausdrücke“). Gegebenenfalls kann man nach dem Aktivieren von »+« (Entfalten in der Baum-Ansicht) noch mehr Details sehen.
Variablenfunktionen
Oft wird gerätselt, ob »Item« Eigenschaft oder Methode sei, weil dem Ergebnis eines Aufrufs jener Funktion ein Wert zugewiesen werden kann.
Wir interpretieren »Item« als eine Funktion, die eine Variable ergibt, und nennen sie daher auch eine Variablenfunktion. (Diese zurückgegebene Variable wurde aber nicht von unserem Programm dimensioniert und hat in unserem Programm keinen eigenen Namen.)
Das heißt, im folgenden Programm ist »W.Item« eine Funktion und »W.Item( "A" )« eine Variable. Beleg: Wir können »W.Item« wie eine Funktion auf ein Argument anwenden, und wir »W.Item( "A" )« wie eine Variable verwenden.
Modul1
Option Explicit
Sub Main()
Dim W As Object
Set W = CreateObject( "Scripting.Dictionary" )
Debug.Print W.Count
Let W.Item( "A" )= "Anton"
Debug.Print W.Count
Debug.Print W.Item( "A" )End Sub
transcript
0
1
Anton
Fehlprozeduren
Eine Fehlprozedur ist eine Prozedur eines Objektes, die angenommen wird, wenn an einer Stelle, an der die Angabe einer Prozedur erwartet wird, nur ein Objekt angegeben wird.
Die Fehlprozedur von Scripting.Dictionary-Objekten ist »Item«. Entsprechend können wir das vorige Programm auch so umschreiben, daß wir ».Item« immer weglassen.
Modul1
Option Explicit
Sub Main()
Dim W As Object
Set W = CreateObject( "Scripting.Dictionary" )
Debug.Print W.Count
Let W( "A" )= "Anton"
Debug.Print W.Count
Debug.Print W( "A" )End Sub
transcript
0
1
Anton
Späte Bindung
Die Zuweisung eines mit »CreateObject« erzeugten Objekts an eine Variable vom Typ »Object« bezeichnet man auch als späte Bindung, weil der genau Typ des Objektes in der Variablen damit erst bei der Programmausführung festgelegt wird.
Dies hat den Vorteil, daß der Typ damit flexibel an Hand von Informationen, die erst während der Programmausführung bekannt sind, festgelegt werden kann.
Ein Nachteil besteht darin, daß die Entwicklungsumgebung den genauen Typ des verwendeten Objektes nicht kennt, und daher dem Bediener weniger Hilfstellungen dazu geben kann.
Auflösung von Objekten
Wenn der Block, in dem eine Variable deklariert wurde, verlassen wird endet die Lebensdauer der Variablen und sie ist an kein Objekt mehr gebunden.
Wenn eine Variable ein Objekt enthält und dann ein anderes Objekt oder »Nothing« (mit »Set«) an jene Variable gebunden wird, so enthält sie das ursprüngliche Objekt nicht mehr.
Wenn es keine Variable mehr gibt, die an ein Objekt gebunden ist, dann wird das Objekt „freigegeben“, das heißt, es belegt dann keinen Speicherplatz mehr.
Übungsfragen
? Übungsfrage
Welche Ausgabe erzeugt das folgende Programm?
Modul1
Option Explicit
Sub Main()
Dim o As Object
Set o = CreateObject( "Scripting.Dictionary" )
o.Add "x", "alpha"
o.Add "y", "beta"
o.Add "z", "gamma"
Debug.Print o.Item( "z" )
Debug.Print o.Item( "y" )
Debug.Print o( "y" )End Sub
? Übungsfrage
Welche Ausgabe erzeugt das folgende Programm?
Modul1
Option Explicit
Sub Main()
Dim p As Object
Set p = CreateObject( "Scripting.Dictionary" )
Dim q As Object
Set q = CreateObject( "Scripting.Dictionary" )
p.Add "x", "alpha"
Debug.Print q( "x" )End Sub
? Übungsfrage
Welche Ausgabe erzeugt das folgende Programm?
Modul1
Option Explicit
Sub Main()
Dim p As Object
Set p = CreateObject( "Scripting.Dictionary" )
Dim q As Object
Set q = p
p.Add "x", "alpha"
Debug.Print q( "x" )End Sub
Übungsaufgaben
/ Übungsaufgabe
Legen Sie ein Wörterbuch-Objekt an, welches die folgenden Paare enthält und fragen Sie dann den Wert für den Schlüssel »Nachname« ab.
- Paare
Schluessel Wert
Vorname Robert
Nachname Schoo
/ Übungsaufgabe
Legen Sie zwei Wörterbuch-Objekte an, welche die folgenden Paare enthalten.
- Paare des ersten Objektes
Schluessel Wert
Vorname Robert
Nachname Schoo- Paare des zweiten Objektes
Schluessel Wert
Vorname Norbert
Nachname Hiller
Legen Sie nun noch ein weiteres Wörterbuch-Objekt namens »rolle« an, welches für den Schlüssel »Vorsitzender« das erste Objekt als Wert enthält und für die Rolle »Stellvertreter« das zweite. Geben Sie dann den Wert der Ausdrücke »rolle( "Vorsitzender" )( "Nachname" )« und »rolle( "Stellvertreter" )( "Vorname" )« aus.
ProgIDs *
(Dieser Absatz enthält Zusatzinformationen, die zum Verständnis des restlichen Kurses nicht benötigt werden. Er richtet sich an fortgeschrittene Leser mit umfangreicheren Vorkenntnissen.)
Der Klassenname, welcher an »CreateObject« übergeben wird ist eine sogenannte ProgID. Dabei handelt es sich um einen Klartextnamen, der in der Windows -Registrierung unter dem Schlüssel »HKEY_CLASSES_ROOT« zu finden ist. Er verweist auf eine GUID, die CLSID der Klasse, welche dann unter »HKEY_CLASSES_ROOT\CLSID« zu finden ist.
Das Programm »OleView.exe« aus dem Windows -SDK kann zur Anzeige der installierten Klassen herangezogen werden. Es zeigt auch die Implementation (wie beispielsweise »C:\Windows\SysWOW64\scrrun.dll«) an. Die Implementation kann dann in diesem Programm wiederum in den Dialog File/View TypeLib… eingegeben werden, wodurch die einzelnen Schnittstellen in der IDL betrachtet werden können.