Programmierungen am Visual Basic Editor
Der folgende Beitrag stammt von einem meiner US-MVP-Kollegen:
Chip Pearson
Er hat mir erlaubt, einen seiner veröffentlichten Beiträge zu übersetzen
und hier zu publizieren.
Ein herzliches Dankeschön!
Den englische Originaltext findest Du hier:
http://www.cpearson.com/excel/vbe.htm
Übersetzt am: 5. September 2004 - Monika Weber -
http://www.jumper.ch
Inhaltsverzeichnis
1.) Einführung
2.) VBE Objekte
3.) Ein Objekt referenzieren
4.) Ein Modul in eine Mappe einfügen
5.) Ein Modul aus einer Mappe entfernen
6.) Eine Prozedur in ein Modul einfügen
7.) Eine Ereignis-Prozedur erzeugen
8.) Eine Prozedur aus einem Modul entfernen
9.) Alle Prozeduren aus einem Modul entfernen
10.) Alle Module einer Mappe
auflisten
11.) Alle Prozeduren eines Moduls
auflisten
12.) Alle Module in ein Projekt
exportieren
13.)
Sämtlichen VBA-Code eines Projekts löschen
14.) Module
zwischen Projekten kopieren
15.) Prüfen, ob ein Modul oder eine Prozedur existiert
Der Visual Basic Editor (VBE) wird verwendet, um Visual Basic for Applications (VBA) Prozeduren und Module zu erstellen, verändern und verwalten. VBA gibt Dir die Möglichkeit, Mappen und Tabellenblätter zu verändern, indem Excel als Schnittstelle dient. VBA erlaubt zudem, VBA Komponenten und Code Module zu bearbeiten, indem VBE das Interface darstellt. Diese Seite bezieht sich lediglich auf Excel 97 und höhere Versionen. Ältere Versionen werden nicht unterstützt.
Diese Seite beschreibt einige Objekt, Methoden und Eigenschaften von VBE, die mittels VBA manipuliert werden können. In Excel 97 sind diese Objekte, Methoden und Eigenschaften nicht in der VBA-Hilfe-Datei beschrieben. Es muss die Datei VEENOB3.hlp verwendet werden. Diese Datei wurde möglicherweise nicht auf Deinem System installiert, als Du Office 97 installiert hast. Ab Office 2000 sind diese Themen in der Standard VBA Hilfe enthalten.
Bevor Du mit dem Programmieren durch die VBE beginnen kannst, musst Du den Verweis auf die Bibliothek "Extensibility" setzen. Du findest Sie im VBA Editor unter dem Menü "Extras/Verweise". Aktiviere das Kontrollkästchen "Microsoft Visual Basic for Applications Extensibility". Dies ermöglicht VBA die Definitionen der Objekte zu finden. Wenn Excel 97 verwendet wird, erscheint die Bibliothek in der Referenzliste ohne Versionsnummer. Wenn Du mit einer neueren Version arbeitest, ist es die Version 5.3 ("Microsoft Visual Basic for Applications Extensibility 5.3"). Es ist sehr wichtig, dass die richtige Bibliothek referenziert wird. Wenn die Falsche oder gar keine verwendet wird, wird ein Fehler beim Ausführen der nachfolgenden Codes erzeugt.
Informationen zur Programmierung von VBE Menüs findest Du unter Adding Menus To The VBA Editor (englisch).
Hinweis: In der Version Excel 2002 wurde ein zusätzlicher Sicherheitslevel eingeführt. Um VBE Projekt Objekte zu manipulieren, so wie es hier beschrieben ist, müsst Du Deine Sicherheitseinstellungen ändern. Verwende in Excel das Menü "Extras/Makro/Sicherheit". Aktiviere das Register "Vertrauenswürdige Quellen". Aktiviere darin das Kontrollkästchen "Zugriff auf Visual Basic-Projekt vertrauen".
Hinweis: Für alle Excel-Versionen gilt, dass das Projekt nicht geschützt werden darf. Wenn dies der Fall ist, schlägt die Prozedur fehl.
Zusätzliche Fehler können entstehen, wenn versucht wird aus einem Modul her Veränderungen im selben Modul vorzunehmen. Damit ist der Zugriff von z.B. Modul1 auf Modul1 gemeint. Es ist zu empfehlen, dies nicht zu tun.
Wir werden drei Objekte in unseren Codes verwenden:
VBProject
Das ist der gesamte Satz von VBA Modulen und Referenzen, die mit einer Mappe
verbunden sind.
VBComponent
Das sind die individuellen Komponenten innerhalb von VBProject. Zum Beispiel ein
UserForm und ein Standard-Modul sind VBComponenten. Die VBComponents Kollektion
enthält alle existierenden VBComponent Objekte.
CodeModule
Dieses Objekt repräsentiert den aktuellen Code innerhalb von VBComponent. Wenn
Du beispielsweise einen Code in Modul1 eintippst, gibst Du den Code in das
CodeModule Objekt ein in der VBComponenten mit dem Namen "Modul1".
Wir werden programmiertechnisch durch das Workbook Objekt zu diesen Komponenten "navigieren". Du kannst diese Komponenten auch über den Application.VBE Objekt-Pfad ansteuern, aber das werden wir hier nicht tun.
Es gibt verschiedene Typen an VBComponents, identifiziert durch die Typen-Eigenschaft des Objekt VBComponent.
| Typen Konstanten | Beschreibung |
| vbext_ct_ClassModule | Dies ist ein Klassenmodul, das verwendet werden kann, um eigene Objekte zu erzeugen. Wir werden das hier nicht benutzen. |
| vbext_ct_Document | Dies ist die Komponente für ein Tabellenblatt, Diagrammblatt oder eine Mappe (ThisWorkbook). |
| vbext_ct_MSForm | Dies ist die Komponente für ein UserForm. |
| vbext_ct_StdModule | Dies ist die Komponente für ein Standard Code Modul. Die meisten unserer Prozeduren werden diesen Typ verwenden. |
Der erste Schritt in der Programmierung mit VBE ist, das Objekt, das für die Arbeit benötigt wird, zu referenzieren.
VBProject
Dim
VBProj As VBProject
Set VBProj = ThisWorkbook.VBProject
VBComponent
Dim VBComp As VBComponent
Set VBComp = ThisWorkbook.VBProject.VBComponents("Modul1")
CodeModule
Dim
VBCodeMod As CodeModule
Set VBCodeMod = ThisWorkbook.VBProject.VBComponents("Modul1").CodeModule
In allen Beispielen auf dieser Seite werden wir mit dem ThisWorkbook Objekt arbeiten -- das bedeutet, wir werden die VBA Komponenten über die Mappe ansprechen. Natürlich können jegliche Arten an offenen Mappen verwendet werden AktiveWorkbook oder Workbooks(IrgendeineMappe.xls).
4.) Ein Modul in eine Mappe einfügen
Die untenstehende Prozedur fügt ein neues Modul mit dem Namen "NeuesModul" in ThisWorkbook ein.
Sub AddModule()
Dim VBComp As VBComponent
Set VBComp = ThisWorkbook.VBProject.VBComponents. _
Add(vbext_ct_StdModule)
VBComp.Name = "NeuesModul"
Application.Visible = True
End Sub
Wenn dieser Code von Excel her ausgeführt wird, während der VBE offen ist, wirst Du direkt zum neuen Modul geführt und die Prozedur wird beendet. Wenn der Code ausgeführt wird, wenn der VBE geschlossen ist, wird der Fokus an die Excel Applikation zurückgegeben. Der VBE wird nicht geöffnet.
5.) Ein Modul aus einer Mappe entfernen
Die folgende Prozedur löscht das Modul "NeuesModul" aus ThisWorkbook.
Sub DeleteModule()
Dim VBComp As VBComponent
Set VBComp = ThisWorkbook.VBProject. _
VBComponents("NeuesModul")
ThisWorkbook.VBProject.VBComponents.Remove VBComp
End Sub
Ein ThisWorkbook Code Modul oder ein Sheet Code Modul oder ein Chart Code Modul kann nicht gelöscht werden.
6.) Eine Prozedur in ein Modul einfügen
Die nächste Prozedur fügt eine neue Prozedur mit dem Namen "MeineNeueProzedur" in das Modul mit dem Namen "NeuesModul" in ThisWorkbook ein. Das Modul "NeuesModul" muss vorhanden sein, ansonsten entsteht eine Fehlermeldung.
Sub AddProcedure() Dim VBCodeMod As CodeModule Dim LineNum As Long
Set VBCodeMod = ThisWorkbook.VBProject. _
VBComponents("NeuesModul").CodeModule
With VBCodeMod
LineNum = .CountOfLines + 1
.InsertLines LineNum, _
"Sub MeineNeueProzedur()" & Chr(13) & _
" Msgbox ""Hier ist die neue Prozedur"" " & Chr(13) & _
"End Sub"
End With
Application.Run "MeineNeueProzedur" End Sub
Beachte den Weg, wie die .InsertLines Methode verwendet wird. Die gesamte Prozedur wird als ein Argument aufbereitet. Mit dem Chr(13) werden die Zeilenumbrüche erzeugt. Die Anweisung
Application.Run "MeineNeueProzedur"
bewirkt, dass die Prozedur gleich gestartet wird. Anstatt die Prozedur direkt aufzurufen (Call), musst Du die Anweisung Application.Run verwenden. Damit kann ein eventueller Compile-Time Error vermieden werden. Die Methode Call wird nur funktionieren, wenn Du Code in ein anderes Code Modul einfügst. Wenn Code im selben Modul eingefügt wird, musst Du ein Application.OnTime einsetzen. Auf diese Weise wird die Kontrolle an Excel zurückgegeben und das Modul kann kompiliert und geladen werden. Mit der Benutzung von Application.OnTime können unter Umständen Synchronisierungsprobleme entstehen. Du solltest vermeiden, eine Prozedur aufzurufen, die gerade erst ins selbe Modul eingefügt wurde ohne, dass zuvor alle VBA Prozeduren die Möglichkeit hatten beendet zu werden.
Application.OnTime Now, "NeueProzedurName"
7.) Eine Ereignis-Prozedur erzeugen
Das CodeModul Objekt verfügt über eine Methode mit dem Namen CreateEventProc, die benutzt werden kann, um eine Prozedur in einem Document-Modul zu erstellen. Z.B. Ein Tabellenmodul, oder das DieseArbeitsmappe-Modul. Der Vorteil der Benutzung von CreateEventProc über InsertLines besteht darin, dass CreateEventProc automatisch die gesamte Prozedur Deklaration, inklusive aller korrekten Parameter einfügt.
CreateEventProc gibt die Zeilennummer zurück, in welcher die Prozedur beginnt. Wenn Du einem CreateEventProc aufrufst, addierte eins zum Ergebnis und verwende dies mit InsertLines um den Kern der Ereignisprozedur einzufügen. Zum Beispiel: der untenstehende Code erzeugt eine Workbook_Open-Prozedur mit einer MsgBox. Der Code wird in DieseArbeitsmappe eingefügt.
Sub CreateEvent()
Dim StartLine As Long
With ActiveWorkbook.VBProject. _
VBComponents("DieseArbeitsmappe").CodeModule
StartLine = .CreateEventProc("Open", "Workbook") + 1
.InsertLines StartLine, _
"Msgbox ""Hallo Welt"",vbOkOnly"
End With
End Sub
8.) Eine Prozedur aus einem Modul entfernen
Die nachfolgende Prozedur löscht die Prozedur mit dem Namen "MeineNeueProzedur" aus dem Modul "NeuesModul" in ThisWorkbook.
Sub DeleteProcedure() Dim VBCodeMod As CodeModule Dim StartLine As Long Dim HowManyLines As Long
Set VBCodeMod = ThisWorkbook.VBProject. _
VBComponents("NeuesModul").CodeModule
With VBCodeMod
StartLine = .ProcStartLine("MeineNeueProzedur", vbext_pk_Proc)
HowManyLines = .ProcCountLines("MeineNeueProzedur", vbext_pk_Proc)
.DeleteLines StartLine, HowManyLines
End With
End Sub
9.) Alle Prozeduren aus einem Modul entfernen
Die untenstehende Prozedur löscht sämtlichen Code aus dem Modul mit dem Namen "NeuesModul".
Sub DeleteAllCodeInModule() Dim VBCodeMod As CodeModule Dim StartLine As Long Dim HowManyLines As Long
Set VBCodeMod = ThisWorkbook.VBProject. _
VBComponents("NeuesModul"). _
CodeModule
With VBCodeMod
StartLine = 1
HowManyLines = .CountOfLines
.DeleteLines StartLine, HowManyLines
End With
End Sub
10.) Alle Module einer Mappe auflisten
Die nächste Prozedur listet, in einer MsgBox, alle Module in ThisWorkbook auf. Es wird eine Funktion mit dem Namen CompTypeToName verwendet, um eine Textbeschreibung vom Typ des Modul zu erhalten. Die Funktion ist ebenfalls nachfolgend zu finden.
Sub ListModules() Dim VBComp As VBComponent Dim Msg As String
For Each VBComp In ThisWorkbook.VBProject.VBComponents
Msg = Msg & VBComp.Name & " Type: " & _
CompTypeToName(VBComp) & Chr(13)
Next VBComp
MsgBox Msg
End Sub
Function CompTypeToName(VBComp As VBComponent) As String
Select Case VBComp.Type
Case vbext_ct_ActiveXDesigner
CompTypeToName = "ActiveX Designer"
Case vbext_ct_ClassModule
CompTypeToName = "Class Module"
Case vbext_ct_Document
CompTypeToName = "Document"
Case vbext_ct_MSForm
CompTypeToName = "MS Form"
Case vbext_ct_StdModule
CompTypeToName = "Standard Module"
Case Else
End Select
End Function
11.) Alle Prozeduren eines Moduls auflisten
Die nächste Prozedur listet, in einer MsgBox, alle Prozeduren eines Standard Moduls auf. Das Standard Modul hat den Namen "NeuesModul" in ThisWorkbook. Die Prozeduren werden in der Reihenfolge aufgelistet, in der sie im Modul enthalten sind.
Sub ListProcedures() Dim VBCodeMod As CodeModule Dim StartLine As Long Dim Msg As String Dim ProcName As String
Set VBCodeMod = ThisWorkbook.VBProject. _
VBComponents("NeuesModul").CodeModule
With VBCodeMod
StartLine = .CountOfDeclarationLines + 1
Do Until StartLine >= .CountOfLines
Msg = Msg & .ProcOfLine(StartLine, vbext_pk_Proc) & _
Chr(13)
StartLine = StartLine + _
.ProcCountLines(.ProcOfLine _
(StartLine, vbext_pk_Proc), _
vbext_pk_Proc)
Loop
End With
MsgBox Msg
End Sub
Beachte den folgenden Hyperlink für mehr Informationen zu CodeName Eigenschaften von VBComponents: Code Modules And Code Names (englisch).
12.) Alle Module in ein Projekt exportieren
Die nachfolgende Prozedur exportiert alle Module in den Ordner, in dem die Mappe abgespeichert ist. Damit kann eine schnelle Sicherung der VBA Prozeduren erfolgen, ohne dass jedes einzelne Modul exportiert werden muss.
Sub ExportAllVBA() Dim VBComp As VBIDE.VBComponent Dim Sfx As String
For Each VBComp In ActiveWorkbook.VBProject.VBComponents
Select Case VBComp.Type
Case vbext_ct_ClassModule, vbext_ct_Document
Sfx = ".cls"
Case vbext_ct_MSForm
Sfx = ".frm"
Case vbext_ct_StdModule
Sfx = ".bas"
Case Else
Sfx = ""
End Select
If Sfx <> "" Then
VBComp.Export _
Filename:=ActiveWorkbook.Path & "\" & _
VBComp.Name & Sfx
End If
Next VBComp
End Sub
13.) Sämtlichen VBA-Code eines Projekts löschen
Die folgende Prozedur löscht sämtliche Codezeilen aus dem gesamten Projekt. Du solltest diese Prozedur mit Vorsicht genießen, da der Code nicht wieder hergestellt werden kann. Es werden Standardmodule, UserForms und Klassenmodule entfernt. Ebenso wird der Code in ThisWorkbook-Modulen gelöscht. Zur Sicherheit könntest Du den vorangegangenen Code verwenden, um vor dem Löschen eine Sicherungskopie der Codes zu erstellen.
Sub DeleteAllVBA() Dim VBComp As VBIDE.VBComponent Dim VBComps As VBIDE.VBComponents
Set VBComps = ActiveWorkbook.VBProject.VBComponents
For Each VBComp In VBComps
Select Case VBComp.Type
Case vbext_ct_StdModule, vbext_ct_MSForm, _
vbext_ct_ClassModule
VBComps.Remove VBComp
Case Else
With VBComp.CodeModule
.DeleteLines 1, .CountOfLines
End With
End Select
Next VBComp
End Sub
14.) Module zwischen Projekten kopieren
Es gibt nicht einfach eine Methode, um Module zwischen Projekten zu kopieren. Der Code eines Projektes muss zuerst exportiert werden. Danach kann dieser in ein anderes Projekt importiert werden. Die folgende Prozedur exportiert das "Modul1" von der "Mappe2" in die "Mappe1".
Sub CopyOneModule() Dim FName As String
With Workbooks("Mappe2")
FName = .Path & "\code.txt"
.VBProject.VBComponents("Modul1").Export FName
End With
Workbooks("Mappe1").VBProject.VBComponents.Import FName
End Sub
Ändere lediglich "Modul1" in den Namen des Moduls, das Du tatsächlich kopieren möchtest. Wenn Du alle Module kopieren möchtest (mit Ausnahme von DieseArbeitsmappe und den Tabellenmodulen), kannst Du den folgenden Code benutzen.
Sub CopyAllModules() Dim FName As String Dim VBComp As VBIDE.VBComponent
With Workbooks("Mappe2")
FName = .Path & "\code.txt"
If Dir(FName) <> "" Then
Kill FName
End If
For Each VBComp In .VBProject.VBComponents
If VBComp.Type <> vbext_ct_Document Then
VBComp.Export FName
Workbooks("Mappe1").VBProject.VBComponents. _
Import FName
Kill FName
End If
Next VBComp
End With
End Sub
15.) Prüfen, ob ein Modul oder eine Prozedur existiert
Du kannst das VBA Extensibility Tool nutzen, um zu prüfen, ob ein Modul existiert, oder ob eine bestimmte Prozedur in einem Modul.
Function ProcedureExists(ProcedureName As String, _
ModuleName As String) As Boolean
On Error Resume Next
If ModuleExists(ModuleName) = True Then
ProcedureExists = ThisWorkbook.VBProject. _
VBComponents(ModuleName) _
.CodeModule.ProcStartLine _
(ProcedureName, vbext_pk_Proc) <> 0
End If
End Function
Dear Chip,
many thans for allowing me to share this
great article with German speaking users.
We appreciate it.
Greetings,
Monika
PS: I see it as a birthday present ;-)