Variablen: Unterschied zwischen den Versionen

Aus VBA-wiki
Zur Navigation springen Zur Suche springen
(Die Seite wurde neu angelegt: „Eine Variable ist ein Speicherort, an dem ein Wert abgelegt werden kann, der später in der Programmierung abgerufen oder verändert werden soll. == Variablen…“)
 
Keine Bearbeitungszusammenfassung
 
(24 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
[[Category:vba-wiki]]
Eine Variable ist ein Speicherort, an dem ein Wert abgelegt werden kann, der später in der Programmierung abgerufen oder verändert werden soll.
Eine Variable ist ein Speicherort, an dem ein Wert abgelegt werden kann, der später in der Programmierung abgerufen oder verändert werden soll.


Zeile 5: Zeile 6:
=== Deklaration ===
=== Deklaration ===


Um eine Variable verwenden zu können, muss sie deklariert werden. Damit wird der Speicherort reserviert und der Name der Variable dient als Kennung, damit später auf genau diesen Wert zugegriffen werden kann. Der reservierte Platz und die Art des Speicherplatzes wird mit dem angegebenen [[Datentypen|Datentyp]] bestimmt. So wird bei der Deklaration festgelegt, ob z. B. eine Zahl oder ein Text oder ein Datum erwartet wird. Den Datentyp kann man nur bei der Deklaration angeben und später nicht ändern. Bei der Deklaration können mehrere Variablen in einer Zeile gemeinsam angegeben werden und werden dann durch Kommata voneinander getrennt: Dim strName As String, strAddress As String Public FirstName As String, LastName As String, Phone as String Sie können auch Variablen von verschiedenen Datentypen in einer Zeile deklarieren, sollten dies jedoch vermeiden, um Ihres Programmcode nicht unnötig kompliziert zu gestalten!
Um eine Variable verwenden zu können, muss sie deklariert werden. Damit wird der Speicherort reserviert und der Name der Variable dient als Kennung, damit später auf genau diesen Wert zugegriffen werden kann.  
 
Der reservierte Platz und die Art des Speicherplatzes wird mit dem angegebenen [[Datentypen|Datentyp]] bestimmt. So wird bei der Deklaration festgelegt, ob z. B. eine Zahl oder ein Text oder ein Datum gespeichert wird.  
 
Den Datentyp kann man nur bei der Deklaration angeben und später nicht ändern.  
 
Bei der Deklaration können mehrere Variablen in einer Zeile gemeinsam angegeben werden und werden dann durch Kommata voneinander getrennt:  
 
<span style="Color:blue">Dim </span>strName<span style="Color:blue"> As String</span><span style="Color:gray">,</span> strAddress<span style="Color:blue"> As String
Public </span>FirstName<span style="Color:blue"> As String</span><span style="Color:gray">,</span> LastName<span style="Color:blue"> As String</span><span style="Color:gray">,</span> Phone<span style="Color:blue"> as String</span>
 
'''Bitte beachten:'''
* Sie können zwar mehrere Variablen von verschiedenen Datentypen in einer Zeile deklarieren, sollten dies jedoch vermeiden, um Ihres Programmcode nicht unnötig kompliziert zu gestalten!
* Wenn Sie mehrere Variablen in einer Zeile deklarieren, müssen Sie jedes Mal mit 'As' den Datentyp angeben, sonst wird die Variable als 'Variant' deklariert.


=== Datentyp ===
=== Datentyp ===


Der [[Datentypen|Datentyp]] wird bei allen Variablen mit dem Schüsselwort <code>As</code> und dem Bezeichner des Datentyps angegeben. Eine vollständige Liste der in VBA möglichen Datentypen finden Sie hier: [[Datentypen|Datentypen]]
Der [[Datentypen|Datentyp]] wird bei allen Variablen mit dem Schüsselwort <code>As</code> und dem Bezeichner des Datentyps angegeben.  
 
Eine vollständige Liste der in VBA möglichen Datentypen finden Sie hier: [[Datentypen|Datentypen]]


=== Benennung ===
=== Benennung ===


Um den Zweck der Variablen klar zu kennzeichnen, sollten Sie eindeutige, sprechende Namen wählen, welche jederzeit und für jedermann und innerhalb des Kontextes eine klare Bedeutung haben. '''Beispiele:''' Dim strFirstName As String, strLastName As String Die Bezeichnung und der Datentyp, welcher Teil des Namens ist (im Beispiel das vorangestellte 'str') lassen keinen Zweifel zu, welche Daten diese Variablen enthalten. Der Grund für die ausdrückliche Angabe des Datentyps auch im Variablennamen wird mit diesem Beispiel verdeutlicht: Dim strItem As String Dim lngItem As Long Dim colCollection As New Collection colCollection.Add "One" colCollection.Add "Two" For lngItem = 1 To colCollection.Count strItem = colCollection.Item(lngItem) Next lngItem Der Name 'Item' wird zweimal unabhängig voneinander belegt, einmal als Zeichenkette, die einen Wert entgegennimmt, und dann als Zählvariable für die For-Schleife. In beiden Fällen ist der Name 'Item' gerechtfertigt, durch das vorangestellte 'str' bzw. 'lng' können beide trotzdem klar voneinander unterschieden werden. Weitere Angaben zur Bezeichnung des Datentyps im Variablennamen finden Sie [[Anhang#Benennung|im Anhang]].
Um den Zweck der Variablen klar zu kennzeichnen, sollten Sie eindeutige, sprechende Namen wählen, welche jederzeit und für jedermann und innerhalb des Kontextes eine klare Bedeutung haben.  
 
'''Beispiele:'''  
 
<span style="Color:blue">Dim </span>strFirstName<span style="Color:blue"> As String</span><span style="Color:gray">,</span> strLastName<span style="Color:blue"> As String</span>
 
Die Bezeichnung und der Datentyp, welcher Teil des Namens ist (im Beispiel das vorangestellte 'str') lassen keinen Zweifel zu, welche Daten diese Variablen enthalten.  
 
Der Grund für die ausdrückliche Angabe des Datentyps auch im Variablennamen wird mit diesem Beispiel verdeutlicht:  
 
<span style="Color:blue">Dim </span>strItem<span style="Color:blue"> As String
Dim </span>lngItem<span style="Color:blue"> As Long
Dim </span>colCollection<span style="Color:blue"> As New </span>Collection
colCollection<span style="Color:gray">.</span>Add <span style="Color:gray">"One"</span>
colCollection<span style="Color:gray">.</span>Add <span style="Color:gray">"Two"</span><span style="Color:blue">
For </span>lngItem <span style="Color:gray">=</span> <span style="Color:gray">1</span><span style="Color:blue"> To </span>colCollection<span style="Color:gray">.</span>Count
    strItem <span style="Color:gray">=</span> colCollection<span style="Color:gray">.</span>Item<span style="Color:gray">(</span>lngItem<span style="Color:gray">)</span><span style="Color:blue">
Next </span>lngItem
 
Der Name 'Item' wird zweimal unabhängig voneinander belegt, einmal als Zeichenkette, die einen Wert entgegennimmt, und dann als Zählvariable für die For-Schleife. In beiden Fällen ist der Name 'Item' gerechtfertigt, durch das vorangestellte 'str' bzw. 'lng' können beide trotzdem klar voneinander unterschieden werden.  
 
Weitere Angaben zur Bezeichnung des Datentyps im Variablennamen finden Sie [[Anhang#Benennung|im Anhang]].
 
=== Reihenfolge ===
 
Die Reihenfolge, in der Datentypen deklariert werden, hat keine Auswirkung auf die Ausführung des Programmcodes, durchaus jedoch auf die Lesbarkeit für uns Programmierer!
 
Gewöhnen Sie es sich daher gerne an, Ihre Deklarationen immer in der gleichen Reihenfolge anzulegen, um später schnell ermitteln zu können, welche Variablen schon angelegt wurden und welche Rolle diese in dieser Prozedur spielen.
 
Die von mir persönlich verwendete Reihenfolge gestaltet sich folgendermaßen:
 
* Zeichenketten
* Zahlenwerte nach Größe sortiert (Integer, Long, Single, Double)
* Collections
* Eigene Objekte (zum Beispiel Klassen), Enums und benutzerdefinierte Datentypen
* Anwendungsobjekte wenn möglich nach Größe sortiert (zum Beispiel Bereich, Dokument, Anwendung in Word oder Zelle, Arbeitsblatt, Arbeitsmappe in Excel)


== Der gespeicherte Wert ==
== Der gespeicherte Wert ==
Zeile 31: Zeile 83:
=== Werte ändern ===
=== Werte ändern ===


'''Bitte beachten:''' Anders als in vielen anderen Programmiersprachen können Sie in VBA '''nicht''' bei der Deklaration der Variablen einen Wert zuweisen. Folgendes ist also '''nicht''' möglich: Dim strValue As String = "Hallo!" ' Verursacht Fehler!!!!!
'''Bitte beachten:''' Anders als in vielen anderen Programmiersprachen können Sie in VBA '''nicht''' bei der Deklaration der Variablen einen Wert zuweisen. Folgendes ist also '''nicht''' möglich:
<span style="Color:blue">Dim </span>strValue<span style="Color:blue"> As String </span><span style="Color:gray">=</span> <span style="Color:gray">"Hallo!"</span>    <span style="Color:green">' Verursacht einen Syntaxfehler!!!!!</span>


==== Natürliche Datentypen ====
==== Natürliche Datentypen ====


Um den Speicherplatz einer Variablen sinnvoll nutzen zu können, kann man ihm mit dem Ist Gleich-Operator (=) einen Wert zuweisen. strValue = "Hallo!"
Um den Speicherplatz einer Variablen sinnvoll nutzen zu können, kann man ihm mit dem Ist Gleich-Operator (=) einen Wert zuweisen.
strValue <span style="Color:gray">=</span> <span style="Color:gray">"Hallo!"</span>


==== Objektvariablen ====
==== Objektvariablen ====


Objektvariablen bekommen mit dem zusätzlichen Schlüsselwort <code>Set</code> eine Instanz des Objektes zugewiesen: Dim objApplication As Application Set objApplication = Application Klassenobjekte, UserFormen und Collections müssen erst mit dem Schlüsselwort <code>New</code> neu erzeugt werden, bevor sie verwendet werden können: Dim myVariables As clsVariables Set myVariables = New clsVariables myVariables.FirstName = "Max" Dim myDialog As frmDialog Set myDialog = New frmDialog myDialog.Show Dim colList As Collection Set colList = New Collection colList.Add "Value" Zusätzlich ist eine Kurzschreibweise möglich, welche eine Objektvariable bei der Deklaration Initialisiert. Diese sollte jedoch nur dann verwendet werden, wenn absolut klar ist, dass Sie das (Klassen-)Objekt, den Dialog oder die Collection auf jeden Fall verwenden werden. Wenn Sie z.&nbsp;B. vor dem Anzeigen eines Dialoges sicher stellen müssen, dass der Dialog angezeigt werden kann, sollten Sie den Dialog erst dann Instanziieren, wenn Sie ihn auch anzeigen werden. Dim myVariables As New clsVariables myVariables.FirstName = "Max" Dim myDialog As New frmDialog myDialog.Show Dim colList As New Collection colList.Add "Value"
Objektvariablen bekommen mit dem zusätzlichen Schlüsselwort <code>Set</code> eine Instanz des Objektes zugewiesen:
<span style="Color:blue"> Dim </span>objApplication<span style="Color:blue"> As </span>Application
 
<span style="Color:blue"> Set </span>objApplication <span style="Color:gray">=</span> Application  
 
Klassenobjekte, UserFormen und Collections müssen erst mit dem Schlüsselwort <code>New</code> neu erzeugt werden, bevor sie verwendet werden können:
 
<span style="Color:blue">Dim </span>myVariables<span style="Color:blue"> As </span>clsVariables
<span style="Color:blue">
Set </span>myVariables <span style="Color:gray">=</span><span style="Color:blue"> New </span>clsVariables
myVariables<span style="Color:gray">.</span>FirstName <span style="Color:gray">=</span> <span style="Color:gray">"Max"</span>
 
<span style="Color:blue">Dim </span>myDialog<span style="Color:blue"> As </span>frmDialog
<span style="Color:blue">
Set </span>myDialog <span style="Color:gray">=</span><span style="Color:blue"> New </span>frmDialog
myDialog<span style="Color:gray">.</span>Show
 
<span style="Color:blue">Dim </span>colList<span style="Color:blue"> As </span>Collection
<span style="Color:blue">
Set </span>colList <span style="Color:gray">=</span><span style="Color:blue"> New </span>Collection
colList<span style="Color:gray">.</span>Add <span style="Color:gray">"Value"</span>
 
'''Wichtig:''' Anwendungsobjekte (Document, Workbook, Range, Font, ...) können '''nicht''' mit <code>New</code> neu erzeugt werden, denn sie existieren schon, sobald die Anwendung gestartet wurde. Wenn Sie ein neues Dokument erzeugen möchten, verwenden Sie stattdessen folgende Vorgehensweise:
 
<span style="Color:blue">Dim </span>doc<span style="Color:blue"> As </span>Document
<span style="Color:blue">
Set </span>doc <span style="Color:gray">=</span> Application<span style="Color:gray">.</span>Documents<span style="Color:gray">.</span>Add    <span style="Color:green">' erzeugt ein neues Blanko-Dokument und übergibt es an die Variable 'doc'</span>
 
Zusätzlich ist eine Kurzschreibweise möglich, welche eine Objektvariable bei der Deklaration Initialisiert.  
 
<span style="Color:blue">Dim </span>myVariables<span style="Color:blue"> As New </span>clsVariables
myVariables<span style="Color:gray">.</span>FirstName <span style="Color:gray">=</span> <span style="Color:gray">"Max"</span>
 
<span style="Color:blue">Dim </span>myDialog<span style="Color:blue"> As New </span>frmDialog
myDialog<span style="Color:gray">.</span>Show
 
<span style="Color:blue">Dim </span>colList<span style="Color:blue"> As New </span>Collection
colList<span style="Color:gray">.</span>Add <span style="Color:gray">"Value"</span>
 
Diese Kurzschreibweise sollte jedoch nur dann verwendet werden, wenn absolut sicher ist, dass Sie das (Klassen-)Objekt, den Dialog oder die Collection auf jeden Fall verwenden werden.
 
Wenn Sie z.&nbsp;B. vor dem Anzeigen eines Dialoges sicher stellen müssen, dass der Dialog angezeigt werden kann, sollten Sie den Dialog erst dann Instanziieren, wenn Sie ihn auch anzeigen werden.
 
<span style="Color:blue">Dim </span>dlg<span style="Color:blue"> as </span>frmDialog
<span style="Color:blue">
If </span>DialogMustBeShown <span style="Color:gray">=</span><span style="Color:blue"> True Then</span>
    <span style="Color:blue"> Set </span>dlg <span style="Color:gray">=</span><span style="Color:blue"> New </span>frmDialog
    dlg<span style="Color:gray">.</span>Show
    <span style="Color:green">' ...</span>
<span style="Color:blue">End If</span>


== Geltungsbereich, Lebensdauer und Formen der Deklaration ==
== Geltungsbereich, Lebensdauer und Formen der Deklaration ==
Zeile 45: Zeile 152:
Jede Variable hat einen klar definierten Geltungsbereich, der sich aus dem Ort, an dem sie definiert wurde und den Schlüsselwörtern Private / Public ergibt:
Jede Variable hat einen klar definierten Geltungsbereich, der sich aus dem Ort, an dem sie definiert wurde und den Schlüsselwörtern Private / Public ergibt:


==== Prozedurale Variable ====
=== Prozedurale Variable ===
 
Diese befindet sich innerhalb einer Prozedur (einer Funktion, einer Eigenschaft) und wird wie folgt mit dem Schlüsselwort <code>Dim</code> deklariert: 
<span style="Color:blue">Sub </span>TemporaryProceduralVariable<span style="Color:gray">()</span>
    <span style="Color:blue"> Dim </span>strVariable<span style="Color:blue"> As String
End Sub</span>
 
Eine prozedurale Variable gilt ausschließlich innerhalb der Prozedur, in der sie definiert wurde. Die Werte sind nicht von anderen Prozeduren aus sichtbar oder veränderbar. Sobald die Prozedur verlassen wird, wird der Speicherplatz freigegeben, die Variable ist somit inklusive ihrem Wert gelöscht.
 
=== Statische prozedurale Variable ===
 
Eine mit dem Schlüsselwort <code>Static</code> deklarierte prozedurale Variable hat den gleichen Geltungsbereich wie die mit <code>Dim</code> deklarierte Variable, wird jedoch nach Verlassen der Prozedur nicht gelöscht, sondern bleibt solange erhalten, wie das Modul, in dem sich die Prozedur befindet, besteht (bei Modulen so lange das Projekt geladen ist, bei Klassen und UserForms so lange eine Instanz deren besteht).
 
<span style="Color:blue">Sub </span>PermanentProceduralVariable<span style="Color:gray">()</span>
    <span style="Color:blue"> Static </span>strVariable<span style="Color:blue"> As String
End Sub</span>
 
So bleibt der Wert der Variable erhalten und kann bei nachfolgenden Aufrufen der Prozedur weiter verwendet werden.
 
'''Bitte beachten:''' Das Schlüsselwort <code>Static</code> darf nicht außerhalb von Prozeduren verwendet werden.
 
=== Funktionsname ===
 
Der Name einer Funktion kann innerhalb der Funktion wie eine Variable (vom Datentyp der Funktion) verwendet werden und erfüllt zusätzlich den Zweck, den Rückgabewert der Funktion entgegenzunehmen.


Diese befindet sich innerhalb einer Prozedur (einer Funktion, einer Eigenschaft) und wird wie folgt mit dem Schlüsselwort <code>Dim</code> deklariert: Sub TemporaryProceduralVariable() '''Dim''' strVariable As String End Sub Eine prozedurale Variable gilt ausschließlich innerhalb der Prozedur, in der sie definiert wurde. Die Werte sind nicht von anderen Prozeduren aus sichtbar oder veränderbar. Sobald die Prozedur verlassen wird, wird der Speicherplatz freigegeben, die Variable ist somit inklusive ihrem Wert gelöscht.
<span style="Color:blue">Private Function </span>ApplicationName<span style="Color:gray">()</span><span style="Color:blue"> As String </span>
    ApplicationName <span style="Color:gray">=</span> Application<span style="Color:gray">.</span>Name <span style="Color:blue">
End Function </span>


==== Statische prozedurale Variable ====
Der Wert der Variablen, die den Funktionsnamen trägt, kann ausschließlich innerhalb der Funktion geändert werden. Der Wert der Funktion kann wie folgt abgefragt werden:


Eine mit dem Schlüsselwort <code>Static</code> deklarierte prozedurale Variable hat den gleichen Geltungsbereich wie die mit <code>Dim</code> deklarierte Variable, wird jedoch nach Verlassen der Prozedur nicht gelöscht, sondern bleibt solange erhalten, wie das Modul, in dem sich die Prozedur befindet, besteht (bei Modulen so lange das Projekt geladen ist, bei Klassen und UserForms so lange eine Instanz deren besteht). Sub PermanentProceduralVariable() '''Static''' strVariable As String End Sub So bleibt der Wert der Variable erhalten und kann bei nachfolgenden Aufrufen der Prozedur weiter verwendet werden. '''Bitte beachten:''' Das Schlüsselwort <code>Static</code> darf nur in Prozeduren verwendet werden. Wenn sich die Prozedur in einer Klasse befindet, wird auch eine statisch deklarierte Variable bei der Terminierung der Klasse zerstört.
<span style="Color:blue">Sub </span>Example<span style="Color:gray">()</span>  
    <span style="Color:blue"> Dim </span>strAppName<span style="Color:blue"> As String </span>
 
    strAppName <span style="Color:gray">=</span> ApplicationName<span style="Color:gray">()</span>
    strAppName <span style="Color:gray">=</span> ApplicationName <span style="Color:blue">
End Sub </span>


==== Funktionsname ====
Die leeren runden Klammern hinter dem Funktionsnamen sind beim Aufruf optional, wenn keine Parameter erwartet werden.


Der Name einer Funktion kann innerhalb der Funktion wie eine Variable (vom Datentyp der Funktion) verwendet werden und erfüllt zusätzlich den Zweck, den Rückgabewert der Funktion entgegenzunehmen. Private Function ApplicationName() As String ApplicationName = Application.Name End Function Der Wert der Variablen, die den Funktionsnamen trägt, kann ausschließlich innerhalb der Funktion geändert werden. Der Wert der Funktion kann wie folgt abgefragt werden: Sub Example() Dim strAppName As String strAppName = ApplicationName() strAppName = ApplicationName End Sub Die leeren runden Klammern hinter dem Funktionsnamen sind beim Aufruf optional, wenn keine Parameter erwartet werden. Der Geltungsbereich der Funktion entspricht dem Geltungsbereich aller Prozeduren:
Der Geltungsbereich der Funktion entspricht dem Geltungsbereich aller Prozeduren:
* <code>Private</code> kann nur innerhalb des (Klassen-)Moduls bzw. der UserForm verwendet werden
* <code>Private</code> kann nur innerhalb des (Klassen-)Moduls bzw. der UserForm verwendet werden
* <code>Public</code>
* <code>Public</code>
Zeile 61: Zeile 198:
** in einer Klasse / einer UserForm: Kann von der Instanz der Klasse / der UserForm aufgerufen und verwendet werden
** in einer Klasse / einer UserForm: Kann von der Instanz der Klasse / der UserForm aufgerufen und verwendet werden


==== Modulweite Variablen ====
=== Modulweite Variablen ===
 
Modulweite Variablen können von allen Prozeduren innerhalb eines Moduls verwendet werden, weil sie außerhalb einer speziellen Prozedur deklariert werden.
 
Sie werden im Modulkopf, also vor der Definition der ersten Prozedur, deklariert.
 
Hier wir nicht das Schlüsselwort <code>Dim</code> verwendet, sondern <code>Private</code>:
 
<span style="Color:blue">Option Explicit </span>
<span style="Color:blue">
Private </span>strVariable<span style="Color:blue"> As String </span>
<span style="Color:blue">
Sub </span>FirstSub<span style="Color:gray">()</span>
    strVariable <span style="Color:gray">=</span> <span style="Color:gray">"Hallo!"</span> <span style="Color:blue">
End Sub </span>
<span style="Color:blue">
Sub </span>SecondSub<span style="Color:gray">()</span>
    MsgBox strVariable <span style="Color:blue">
End Sub </span>
 
Modulweite Variablen können nicht von Prozeduren in anderen Modulen ausgelesen oder beschrieben werden.
 
'''Bitte beachten:''' Modulweite und projektweite Variablen sollten nur in solchen Fällen eingesetzt werden, in denen sie sinnvoll sind, und nicht, um 'Variablen zu sparen'.
 
Wenn Variablen über längere Zeiträume und aus mehreren Quellen Werte behalten bzw. beziehen, kann leicht die Übersicht darunter leiden bzw. können sich unerwartete Werte in den Variablen befinden.
 
Der sinnvolle Einsatz von modulweiten und projektweiten Variablen wäre zum Beispiel für solche Werte, die über einen längeren Zeitraum erhalten bleiben sollen.
 
=== Projektweite Variablen ===
 
Wenn Sie Werte hinterlegen möchten, die in ihrem gesamten Projekt jederzeit zur Verfügung stehen, deklarieren Sie eine öffentliche Modulvariable mit dem Schlüsselwort <code>Public</code>:
 
<span style="Color:blue">Option Explicit </span>
<span style="Color:blue">
Public </span>Variable<span style="Color:blue"> As String </span>
 
Auf diese Variable können Sie nun auch aus anderen Modulen, Klassen und Formen heraus zugreifen und von dort aus auch die Werte ändern.
 
Um Ihr Projekt übersichtlich zu gestalten, empfehlen wir, dass Sie projektweite Variablen, wenn möglich, in einem Modul sammeln.


Modulweite Variablen können von allen Prozeduren innerhalb eines Moduls verwendet werden, weil sie außerhalb einer speziellen Prozedur deklariert werden. Sie werden im Modulkopf, also vor der Definition der ersten Prozedur, deklariert. Hier wir nicht das Schlüsselwort <code>Dim</code> verwendet, sondern <code>Private</code>: Option Explicit '''Private''' strVariable As String Sub FirstSub() strVariable = "Hallo!" End Sub Sub SecondSub() MsgBox strVariable End Sub Modulweite Variablen können nicht von Prozeduren in anderen Modulen ausgelesen oder beschrieben werden. '''Bitte beachten:''' Modulweite und projektweite Variablen sollten nur in solchen Fällen eingesetzt werden, in denen sie sinnvoll sind, und nicht, um 'Variablen zu sparen'. Wenn Variablen über längere Zeiträume und aus mehreren Quellen Werte behalten bzw. beziehen, kann leicht die Übersicht darunter leiden bzw. können sich unerwartete Werte in den Variablen befinden. Der sinnvolle Einsatz von modulweiten und projektweiten Variablen wäre zum Beispiel für solche Werte, die über einen längeren Zeitraum erhalten bleiben sollen.
'''Bitte beachten:''' Modulweite und projektweite Variablen sollten nur in solchen Fällen eingesetzt werden, in denen sie sinnvoll sind, und nicht, um 'Variablen zu sparen'.  


==== Projektweite Variablen ====
Wenn Variablen über längere Zeiträume und aus mehreren Quellen Werte behalten bzw. beziehen, kann leicht die Übersicht darunter leiden bzw. können sich unerwartete Werte in den Variablen befinden.


Wenn Sie Werte hinterlegen möchten, die in ihrem gesamten Projekt jederzeit zur Verfügung stehen, deklarieren Sie eine öffentliche Modulvariable mit dem Schlüsselwort <code>Public</code>: Option Explicit '''Public''' Variable As String Auf diese Variable können Sie nun auch aus anderen Modulen, Klassen und Formen heraus zugreifen und von dort aus auch die Werte ändern. Um Ihr Projekt übersichtlich zu gestalten, empfehlen wir, dass Sie projektweite Variablen, wenn möglich, in einem Modul sammeln. '''Bitte beachten:''' Modulweite und projektweite Variablen sollten nur in solchen Fällen eingesetzt werden, in denen sie sinnvoll sind, und nicht, um 'Variablen zu sparen'. Wenn Variablen über längere Zeiträume und aus mehreren Quellen Werte behalten bzw. beziehen, kann leicht die Übersicht darunter leiden bzw. können sich unerwartete Werte in den Variablen befinden. Der sinnvolle Einsatz von modulweiten und projektweiten Variablen wäre zum Beispiel für solche Werte, die über einen längeren Zeitraum erhalten bleiben sollen.
Der sinnvolle Einsatz von modulweiten und projektweiten Variablen wäre zum Beispiel für solche Werte, die über einen längeren Zeitraum erhalten bleiben sollen.


==== Besondere Geltungsbereiche in Klassen und UserFormen ====
==== Besondere Geltungsbereiche in Klassen und UserFormen ====
Zeile 73: Zeile 248:
Da UserFormen eine besondere Form von Klassenmodulen sind und sich im Bezug auf Variablen identisch verhalten, werden wir in diesem Abschnitt nicht getrennt auf sie eingehen, sondern wie Klassen behandeln.
Da UserFormen eine besondere Form von Klassenmodulen sind und sich im Bezug auf Variablen identisch verhalten, werden wir in diesem Abschnitt nicht getrennt auf sie eingehen, sondern wie Klassen behandeln.


===== Prozedurale und private Klassen-Variablen =====
==== Prozedurale und private Klassen-Variablen ====


Prozedurale Variablen folgen den oben angegebenen Regeln; sie gelten ausschließlich innerhalb der Prozedur, in der sie definiert wurden. Mit <code>Private</code> deklarierte Klassen-Variablen gelten ebenfalls ausschließlich innerhalb der Klasse bzw. der UserForm.
Prozedurale Variablen folgen den oben angegebenen Regeln; sie gelten ausschließlich innerhalb der Prozedur, in der sie definiert wurden. Mit <code>Private</code> deklarierte Klassen-Variablen gelten ebenfalls ausschließlich innerhalb der Klasse bzw. der UserForm.


===== Öffentliche Klassenvariablen =====
==== Öffentliche Klassenvariablen ====
 
Mit <code>Public</code> deklarierte Klassen-Variablen stehen zusätzlich den Instanzen der Klasse zur Verfügung.
 
Sie können wie Eigenschaften eingesetzt werden, wenn man die Werte ungeprüft entgegennehmen kann und die Vergabe von neuen Werten nicht beeinflussen möchte.
 
'''Beispielklasse 'clsVariables':'''
 
<span style="Color:blue">Option Explicit </span>
<span style="Color:blue">
Public </span>FirstName<span style="Color:blue"> As String</span><span style="Color:gray">,</span> LastName<span style="Color:blue"> As String</span><span style="Color:gray">,</span> Phone<span style="Color:blue"> As String
Private </span>strClassVariable<span style="Color:blue"> As String </span>
<span style="Color:blue">
Public Sub </span>DoSomething<span style="Color:gray">()</span>
    <span style="Color:blue"> Dim </span>strMyValue<span style="Color:blue"> As String </span>
   
    MsgBox FirstName <span style="Color:blue">
End Sub</span><span style="Color:green">
 
'''Beispielmodul 'modTest':'''
 
<span style="Color:blue">Option Explicit </span>
<span style="Color:blue">
Sub </span>Example<span style="Color:gray">()</span>
    <span style="Color:blue"> Dim </span>myVariables<span style="Color:blue"> As </span>clsVariables
   
    <span style="Color:blue"> Set </span>myVariables <span style="Color:gray">=</span><span style="Color:blue"> New </span>clsVariables
    myVariables<span style="Color:gray">.</span>FirstName <span style="Color:gray">=</span> <span style="Color:gray">"Max"</span>
    myVariables<span style="Color:gray">.</span>LastName <span style="Color:gray">=</span> <span style="Color:gray">"Muster"</span>
    myVariables<span style="Color:gray">.</span>Phone <span style="Color:gray">=</span> <span style="Color:gray">"+49 123 4656789"</span>
    myVariables<span style="Color:gray">.</span>DoSomething <span style="Color:blue">
End Sub </span><span style="Color:green">
 
'''Darstellung im VBA-Editor:''' Ausschließlich die öffentlichen Variablen und Prozeduren stehen der Instanz <code>myVariables</code> zur Verfügung: [[Datei:ClassVariables.png]]
 
== Übergabeparameter ==
 
Wenn einer Prozedur ein Wert übergeben wird, wird dieser nach dem Prozedurnamen innerhalb der runden Klammern angegeben.
 
Mehrere Parameter werden durch Kommata getrennt.
 
<span style="Color:blue">Private Sub </span>SingleParameter<span style="Color:gray">(</span><span style="Color:blue">ByVal </span>lngValue<span style="Color:blue"> As Long</span><span style="Color:gray">)</span>
<span style="Color:blue">
End Sub
 
Private Sub </span>ListOfParameters<span style="Color:gray">(</span><span style="Color:blue">ByVal </span>lngValue<span style="Color:blue"> As Long</span><span style="Color:gray">,</span><span style="Color:blue"> ByVal </span>strValue<span style="Color:blue"> As String</span><span style="Color:gray">,</span><span style="Color:blue"> ByVal </span>dteDate<span style="Color:blue"> As Date</span><span style="Color:gray">)</span>
<span style="Color:blue">
End Sub</span><span style="Color:green">
 
=== ByVal ===
 
Der Geltungsbereich beschränkt sich mit dem Schlüsselwort <code>ByVal</code> wie bei [[#Prozedurale_Variable|prozeduralen Variablen]] auf die Prozedur, der sie übergeben wird.
 
<span style="Color:blue">Private Sub </span>ParameterByVal<span style="Color:gray">(</span><span style="Color:blue">ByVal </span>lngValue<span style="Color:blue"> As Long</span><span style="Color:gray">)</span>
    <span style="Color:green">' ... </span>
    lngValue <span style="Color:gray">=</span> lngValue <span style="Color:gray">+</span> <span style="Color:gray">1</span>
    <span style="Color:green">'.... </span>
<span style="Color:blue">End Sub </span>
 
<span style="Color:blue">
Private Sub </span>Test<span style="Color:gray">()</span>
    <span style="Color:blue"> Dim </span>lngNumber<span style="Color:blue"> As Long </span>
   
    lngNumber <span style="Color:gray">=</span> <span style="Color:gray">5</span>
    ParametersByVal lngNumber
    Debug<span style="Color:gray">.</span>Print lngNumber          <span style="Color:green">' Der Wert ist immer noch 5 </span>
<span style="Color:blue">End Sub </span><span style="Color:green">
 
Das bedeutet, dass die empfangende Prozedur eine neue Variable mit dem gewünschten Wert erhält. Wenn dieser Wert innerhalb der Prozedur geändert wird, betrifft diese Änderung '''NICHT''' die Variable in der absendenden Prozedur.
 
=== ByRef ===
 
Wird ein Parameter mit dem Schlüsselwort <code>ByRef</code> übergeben, verhält sich die Variable innerhalb der Prozedur, an der sie übergeben wurde, identisch zu <code>ByVal</code>.
 
Aber der Wert wird nicht in einer neuen Variablen übergeben, sondern über eine Referenz auf die aufrufende Variable:
 
<span style="Color:blue">Private Sub </span>ParametersByRef<span style="Color:gray">(</span><span style="Color:blue">ByRef </span>lngValue<span style="Color:blue"> As Long</span><span style="Color:gray">)</span>
    <span style="Color:green">' ... </span>
    lngValue <span style="Color:gray">=</span> lngValue <span style="Color:gray">+</span> <span style="Color:gray">1</span>
    <span style="Color:green">'.... </span>
<span style="Color:blue">End Sub </span>
 
<span style="Color:blue">
Private Sub </span>Test<span style="Color:gray">()</span>
    <span style="Color:blue"> Dim </span>lngNumber<span style="Color:blue"> As Long </span>
   
    lngNumber <span style="Color:gray">=</span> <span style="Color:gray">5</span>
    ParametersByRef lngNumber
    Debug<span style="Color:gray">.</span>Print lngNumber <span style="Color:green">    ' Der Wert ist jetzt 6!!! </span>
<span style="Color:blue">End Sub </span><span style="Color:green">
 
Über diese Referenz erhält also die aufgerufene Prozedur Zugriff auf den Original-Speicherplatz und kann dessen Wert direkt ändern. Dies kann selbstverständlich zu großer Verwirrung führen, wenn Sie nicht mit diesem Verhalten rechnen.
 
'''Bitte beachten:''' Wenn Sie bei einem Parameter keine zusätzliche Angabe machen, wird standardmäßig die Übergabe <code>ByRef</code> vorgenommen!
 
=== Optionale Parameter ===
 
==== Generelles zu optionalen Parametern ====
 
Das Schlüsselwort 'Optional' gibt an, dass der beschriebene Parameter optional ist, also nicht zwingend angegeben werden muss.
 
In der Hilfe und in der Quickinfo (STRG + i) werden optionale Parameter in eckigen Klammern dargestellt.


Mit <code>Public</code> deklarierte Klassen-Variablen stehen zusätzlich den Instanzen der Klasse zur Verfügung. Sie können wie Eigenschaften eingesetzt werden, wenn man die Werte ungeprüft entgegennehmen kann und die Vergabe von neuen Werten nicht beeinflussen möchte. '''Beispielklasse 'clsVariables':''' Option Explicit Public FirstName As String, LastName As String, Phone As String Private strClassVariable As String Public Sub DoSomething() Dim strMyValue As String MsgBox FirstName End Sub '''Beispielmodul 'modTest':''' Option Explicit Sub Example() Dim myVariables As clsVariables Set myVariables = New clsVariables myVariables.FirstName = "Max" myVariables.LastName = "Muster" myVariables.Phone = "+49 123 4656789" myVariables.DoSomething End Sub '''Darstellung im VBA-Editor:''' Ausschließlich die öffentlichen Variablen und Prozeduren stehen der Instanz <code>myVariables</code> zur Verfügung: [[Datei:ClassVariables.png]]
Bei der 'MsgBox'-Funktion wird dies zum Beispiel deutlich: Der Prompt wird zwingend erwartet, alle weiteren Parameter sind optional und können bei Bedarf weggelassen werden.  


==== Übergabeparameter ====
  MsgBox<span style="Color:gray">(</span>Prompt<span style="Color:gray">,</span> [Buttons<span style="Color:blue"> As </span>VbMsgBoxStyle <span style="Color:gray">=</span> vbOKOnly]<span style="Color:gray">,</span> [Title]<span style="Color:gray">,</span> [HelpFile]<span style="Color:gray">,</span> [Context]<span style="Color:gray">)</span><span style="Color:blue"> As </span>VbMsgBoxResult<span style="Color:blue">


Wenn einer Prozedur ein Wert übergeben wird, wird dieser nach dem Prozedurnamen innerhalb der runden Klammern angegeben. Mehrere Parameter werden durch Kommata getrennt. Private Sub SingleParameter(ByVal lngValue As Long) Private Sub ListOfParameters(ByVal lngValue As Long, ByVal strValue As String, ByVal dteDate As Date)
Bei einer eigenen Prozedur sieht das dann so aus:


===== ByVal =====
<span style="Color:blue">Private Sub </span>OptionalParameter<span style="Color:gray">(</span><span style="Color:blue">ByVal </span>strNecessary<span style="Color:blue"> As String</span><span style="Color:gray">,</span> Optional<span style="Color:blue"> ByVal </span>lngOptional<span style="Color:blue"> As Long</span><span style="Color:gray">)</span>
<span style="Color:blue">
End Sub</span>


Der Geltungsbereich beschränkt sich mit dem Schlüsselwort <code>ByVal</code> wie bei [[#Prozedurale_Variable|prozeduralen Variablen]] auf die Prozedur, der sie übergeben wird. Private Sub ParameterByVal('''ByVal''' lngValue As Long) ' ... lngValue = lngValue + 1 '.... End Sub Private Sub Test() Dim lngNumber As Long lngNumber = 5 ParametersByVal lngNumber Debug.Print lngNumber ' Der Wert ist immer noch 5 End Sub Das bedeutet, dass die empfangende Prozedur eine neue Variable mit dem gewünschten Wert erhält. Wenn dieser Wert innerhalb der Prozedur geändert wird, betrifft diese Änderung '''NICHT''' die Variable in der absendenden Prozedur.
Quickinfo:


===== ByRef =====
OptionalParameter<span style="Color:gray">(</span><span style="Color:blue">ByVal </span>strNecessary<span style="Color:blue"> As String</span><span style="Color:gray">,</span> [ByVal lngOptional<span style="Color:blue"> As </span>Long]<span style="Color:gray">)</span>


Wird ein Parameter mit dem Schlüsselwort <code>ByRef</code> übergeben, verhält sich die Variable innerhalb der Prozedur, an der sie übergeben wurde, identisch zu <code>ByVal</code>. Aber der Wert wird nicht in einer neuen Variablen übergeben, sondern über eine Referenz auf die aufrufende Variable: Private Sub ParametersByRef('''ByRef''' lngValue As Long) ' ... lngValue = lngValue + 1 '.... End Sub Private Sub Test() Dim lngNumber As Long lngNumber = 5 ParametersByRef lngNumber Debug.Print lngNumber ' Der Wert ist jetzt 6!!! End Sub Über diese Referenz erhält also die aufgerufene Prozedur Zugriff auf den Original-Speicherplatz und kann dessen Wert direkt ändern. Dies kann selbstverständlich zu großer Verwirrung führen, wenn Sie nicht mit diesem Verhalten rechnen. '''Bitte beachten:''' Wenn Sie bei einem Parameter keine zusätzliche Angabe machen, wird standardmäßig die Übergabe <code>ByRef</code> vorgenommen!
Sie können für einen optionalen Parameter einen Standardwert vergeben:  


==== Optionale Parameter ====
<span style="Color:blue">Private Sub </span>OptionalParameter<span style="Color:gray">(</span><span style="Color:blue">ByVal </span>strNecessary<span style="Color:blue"> As String</span><span style="Color:gray">,</span> Optional<span style="Color:blue"> ByVal </span>lngOptional<span style="Color:blue"> As Long </span><span style="Color:gray">=</span> <span style="Color:gray">3)</span>
<span style="Color:blue">
End Sub</span>


===== Generelles zu optionalen Parametern =====
Der Aufruf kann nun wie folgt durchgeführt werden:


Das Schlüsselwort 'Optional' gibt an, dass der beschriebene Parameter optional ist, also nicht zwingend angegeben werden muss. Bei der 'MsgBox'-Funktion wird dies zum Beispiel deutlich: Der Prompt wird zwingend erwartet, alle weiteren Parameter sind optional und können bei Bedarf weggelassen werden. Private Sub OptionalParameter(ByVal strNecessary As String, '''Optional''' ByVal lngOptional As Long) Sie können für einen optionalen Parameter einen Standardwert vergeben: Private Sub OptionalParameter(ByVal strNecessary As String, Optional ByVal lngOptional As Long '''= 3''') Der Aufruf kann nun wie folgt durchgeführt werden: OptionalParameter "Hallo" oder mit zweitem Parameter OptionalParameter "Hallo", 7 ;Regeln
OptionalParameter <span style="Color:gray">"Hallo"</span>
 
oder mit zweitem Parameter  
 
OptionalParameter <span style="Color:gray">"Hallo",</span> <span style="Color:gray">7</span>
 
aber niemals
 
OptionalParameter         <span style="Color:green">' Ganz ohne Parameter</span>
OptionalParameter <span style="Color:gray">,</span> <span style="Color:gray">7</span>    <span style="Color:green">' Nur mit Angabe des zweiten Parameters</span>
 
;Regeln
* Bitte die hier gezeigte Reihenfolge einhalten ('Optional' erscheint vor 'ByVal', 'ByRef' bzw. dem Namen des Parameters).
* Bitte die hier gezeigte Reihenfolge einhalten ('Optional' erscheint vor 'ByVal', 'ByRef' bzw. dem Namen des Parameters).
* Der Standardwert wird nach der Angabe des Datentyps platziert.
* Der Standardwert wird nach der Angabe des Datentyps platziert.
* '''Wichtig:''' Nach einem optionalen Parameter können ausschließlich weitere optionale Parameter erscheinen!!! Alle benötigten Parameter stehen damit am Anfang der Parameter-Liste, optionale am Ende. '''Bitte beachten:''' Die 'IsMissing'-Funktion soll prüfen, ob einem optionalen Parameter ein Wert übergeben wurde. Dies klappt allerdings nur für Variant! '''Tipp:''' Wenn Sie prüfen möchten, ob ein optionaler Parameter angegeben wurde, belegen Sie ihn mit einem unwahrscheinlichen oder unmöglichen Wert: Public Function RandomDouble(ByVal dblBottom As Double, ByVal dblTop As Double, Optional ByVal lngRoundToDigits As Long = -1) As Double Hier wird der Standardwert für 'lngRoundToDigits' mit '-1' vorbelegt, denn ohne diese Angabe wäre dieser mit 0 belegt und das Ergebnis würde somit immer auf 0 Nachkommastellen gerundet. Wenn die Funktion ohne Angabe der Anzahl der Nachkommastellen aufgerufen wird, beträgt der Wert weiterhin -1, welches nicht möglich ist, denn es gibt keine negativen Nachkommastellen. Statt nun also das Ergebnis auf eine Ganzzahl zu runden (welches bei 0 der Fall wäre), kann nun mit einer If-Abfrage das Runden komplett verhindert werden: If lngRoundToDigits >= 0 Then RandomDouble = Round(RandomDouble, lngRoundToDigits) End If
* '''Wichtig:''' Nach einem optionalen Parameter können ausschließlich weitere optionale Parameter erscheinen!!! Alle benötigten Parameter stehen damit am Anfang der Parameter-Liste, optionale am Ende.
 
'''Bitte beachten:''' Die 'IsMissing'-Funktion soll prüfen, ob einem optionalen Parameter ein Wert übergeben wurde. Dies klappt allerdings nur für Variant-Werte!  
 
'''Tipp:''' Wenn Sie prüfen möchten, ob ein optionaler Parameter angegeben wurde, belegen Sie ihn mit einem unwahrscheinlichen oder unmöglichen Wert:  
 
Beispiel: Hier wird der Standardwert für 'lngRoundToDigits' mit einem nicht möglichen Wert '-1' vorbelegt:
 
<span style="Color:blue">Public Function </span>RandomDouble<span style="Color:gray">(</span><span style="Color:blue">ByVal </span>dblBottom<span style="Color:blue"> As Double</span><span style="Color:gray">,</span><span style="Color:blue"> ByVal </span>dblTop<span style="Color:blue"> As Double</span><span style="Color:gray">,</span> Optional<span style="Color:blue"> ByVal </span>lngRoundToDigits<span style="Color:blue"> As Long </span><span style="Color:gray">=</span> <span style="Color:gray">-1)</span><span style="Color:blue"> As Double</span>
    Randomize
    RandomDouble <span style="Color:gray">=</span> dblBottom <span style="Color:gray">+</span> Rnd<span style="Color:gray">()</span> <span style="Color:gray">*</span> <span style="Color:gray">(</span>dblTop <span style="Color:gray">-</span> dblBottom<span style="Color:gray">)</span>
   
    <span style="Color:green">' Wenn die Funktion ohne Angabe der Anzahl der Nachkommastellen aufgerufen wird, beträgt der Wert weiterhin -1,</span>
    <span style="Color:green">' welches nicht möglich ist, denn es gibt keine negativen Nachkommastellen.</span>
    <span style="Color:green">' Statt nun also das Ergebnis auf eine Ganzzahl zu runden (welches bei 0 der Fall wäre), kann nun mit einer If-Abfrage das Runden komplett verhindert werden:</span>
   
    <span style="Color:blue"> If </span>lngRoundToDigits <span style="Color:gray">>=</span> <span style="Color:gray">0</span><span style="Color:blue"> Then</span>
        RandomDouble <span style="Color:gray">=</span> Round<span style="Color:gray">(</span>RandomDouble<span style="Color:gray">,</span> lngRoundToDigits<span style="Color:gray">)</span>
    <span style="Color:blue"> End If
End Function</span>
 
<span style="Color:blue">
Private Sub </span>Test<span style="Color:gray">()</span>
   
    Debug<span style="Color:gray">.</span>Print RandomDouble<span style="Color:gray">(0,</span> <span style="Color:gray">5)</span>          <span style="Color:green">' 3,75971466302872  (ungerundeter Wert)</span>
    Debug<span style="Color:gray">.</span>Print RandomDouble<span style="Color:gray">(0,</span> <span style="Color:gray">5,</span> <span style="Color:gray">0)</span>      <span style="Color:green">' 4                (auf ganze Zahl gerundet)</span>
    Debug<span style="Color:gray">.</span>Print RandomDouble<span style="Color:gray">(0,</span> <span style="Color:gray">5,</span> <span style="Color:gray">5)</span>      <span style="Color:green">' 3,75971          (auf 5 Nachkommastellen gerundet)</span>
<span style="Color:blue">End Sub</span>
 
==== Arbeiten mit Optionalen Parametern ====
 
Bei Variant-Parametern können Sie mit der IsMissing-Funktion prüfen, ob der optionale Parameter übergeben wurde:
 
<span style="Color:blue">Public Sub </span>DoSomething<span style="Color:gray">(</span>Optional<span style="Color:blue"> ByVal </span>varWithThis<span style="Color:blue"> As Variant</span><span style="Color:gray">)</span>
   
    <span style="Color:blue"> If </span>IsMissing<span style="Color:gray">(</span>varWithThis<span style="Color:gray">)</span> <span style="Color:gray">=</span><span style="Color:blue"> False Then</span>
        MsgBox <span style="Color:gray">"Der Parameter wurde übergeben!"</span>
        <span style="Color:blue"> End If</span>
    <span style="Color:blue"> End Sub


===== Arbeiten mit Optionalen Parametern =====
Private Sub </span>TestDoSomething<span style="Color:gray">()</span>
    DoSomething <span style="Color:green">' Kein Parameter ...</span>
    DoSomething <span style="Color:gray">"Irgendwas"</span><span style="Color:blue">
End Sub</span>


Bei Variant-Parametern können Sie mit der IsMissing-Funktion prüfen, ob der optionale Parameter übergeben wurde: Public Sub DoSomething(Optional ByVal varWithThis As Variant) If IsMissing(varWithThis) = False Then MsgBox "Der Parameter wurde übergeben!" End If End Sub Private Sub TestDoSomething() DoSomething ' Kein Parameter ... DoSomething "Irgendwas" End Sub Empfohlen wird jedoch, stattdessen mit dem Leerwert des Parameters oder einem unwahrscheinlichen Vorgabewert zu arbeiten: Public Sub DoSomething(Optional ByVal strWithThis As String) If strWithThis <> "" Then MsgBox "Der Parameter wurde übergeben!" End If End Sub Public Sub DoSomething(Optional ByVal lngWithThis As Long = -43423442) If lngWithThis <> -43423442 Then MsgBox "Der Parameter wurde übergeben!" End If End Sub Der Vorteil dieser Beispiele ist, dass Sie nicht ausschließlich mit Variant-Parametern arbeiten müssen, um dann mit 'IsMissing' festzustellen, ob der Parameter verwendet wurde.
Empfohlen wird jedoch, stattdessen mit dem Leerwert des Parameters oder einem unwahrscheinlichen Vorgabewert zu arbeiten:  
 
<span style="Color:blue">Public Sub </span>DoSomething<span style="Color:gray">(</span>Optional<span style="Color:blue"> ByVal </span>strWithThis<span style="Color:blue"> As String</span><span style="Color:gray">)</span>
   
    <span style="Color:blue"> If </span>strWithThis <span style="Color:gray"><></span> <span style="Color:gray">""</span><span style="Color:blue"> Then</span>
        MsgBox <span style="Color:gray">"Der Parameter wurde übergeben!"</span>
    <span style="Color:blue"> End If
End Sub
 
Public Sub </span>DoSomething<span style="Color:gray">(</span>Optional<span style="Color:blue"> ByVal </span>lngWithThis<span style="Color:blue"> As Long </span><span style="Color:gray">=</span>  <span style="Color:gray">-</span> <span style="Color:gray">43423442)</span>
    <span style="Color:blue"> If </span>lngWithThis <span style="Color:gray"><></span> <span style="Color:gray">-</span> <span style="Color:gray">43423442</span><span style="Color:blue"> Then</span>
        MsgBox <span style="Color:gray">"Der Parameter wurde übergeben!"</span>
    <span style="Color:blue"> End If
End Sub</span>
 
Der Vorteil dieser letzten Beispiele ist, dass Sie nicht ausschließlich mit Variant-Parametern arbeiten müssen, um dann mit 'IsMissing' festzustellen, ob der Parameter verwendet wurde.


== Konstanten ==
== Konstanten ==
Zeile 112: Zeile 464:
=== Deklaration und Wertzuweisung ===
=== Deklaration und Wertzuweisung ===


Eine Konstante wird mit dem Schlüsselwort <code>Const</code> deklariert, der Wert wird anschließend mit '=' zugewiesen: '''Prozedurale Konstante:''' Const strConstant As String = "Konstanter Wert" '''Alle weiteren Konstanten:''' Private Const strConstant As String = "Konstanter Wert" Public Const Constant As String = "Konstanter Wert" '''Bitte beachten:''' Bei konstanten Datumsangaben muss der Datumswert entweder als Zahl oder eindeutiger Datums-String angegeben werden. Eine Umwandlung mit der Funktion CDate() ist nicht möglich! Const dteEstablished As Date = "1984-03-01" Const dteEstablished As Date = 30742
Eine Konstante wird mit dem Schlüsselwort <code>Const</code> deklariert, der Wert wird anschließend mit '=' zugewiesen:  
 
'''Prozedurale Konstante:'''  
 
<span style="Color:blue">Const </span>strConstant<span style="Color:blue"> As String </span><span style="Color:gray">=</span> <span style="Color:gray">"Konstanter Wert"</span>    <span style="Color:green">' NICHT: Dim Const strConstant As String = "Konstanter Wert"</span>
 
'''Alle weiteren Konstanten:'''  
 
<span style="Color:blue">Private Const </span>strConstant<span style="Color:blue"> As String </span><span style="Color:gray">=</span> <span style="Color:gray">"Konstanter Wert"</span> <span style="Color:blue">
Public Const </span>Constant<span style="Color:blue"> As String </span><span style="Color:gray">=</span> <span style="Color:gray">"Konstanter Wert"</span>
 
'''Bitte beachten:''' Bei konstanten Datumsangaben muss der Datumswert entweder als Zahl oder eindeutiger Datums-String angegeben werden. Eine Umwandlung mit der Funktion CDate() ist nicht möglich!  
 
<span style="Color:blue">Const </span>dteEstablished<span style="Color:blue"> As Date </span><span style="Color:gray">=</span> <span style="Color:gray">"1984-03-01"</span> <span style="Color:blue">
Const </span>dteIncorporated<span style="Color:blue"> As Date </span><span style="Color:gray">=</span> <span style="Color:gray">36742</span>


=== Datentypen ===
=== Datentypen ===


Da Konstanten ausschließlich bei der Deklaration den gewünschten Wert erhalten können, können sie ausschließlich natürliche Datentypen enthalten, also keine (Klassen-)Objekte, Types, Collections oder Arrays. Eine vollständige Liste der in VBA verwendeten Datentypen finden Sie hier: [[Datentypen|Datentypen]]
Da Konstanten ausschließlich bei der Deklaration den gewünschten Wert erhalten können, können sie ausschließlich natürliche Datentypen enthalten, also keine (Klassen-)Objekte, Types, Collections oder Arrays.  
 
Eine vollständige Liste der in VBA verwendeten Datentypen finden Sie hier: [[Datentypen|Datentypen]]


=== Geltungsbereich und Lebensdauer ===
=== Geltungsbereich und Lebensdauer ===


Geltungsbereich und Lebensdauer sind identisch zu den bei Variablen beschriebenen Geltungsbereichen und Lebensdauern. Das Schlüsselwort <code>Static</code> ist jedoch nicht zulässig.
Geltungsbereich und Lebensdauer sind identisch zu den bei Variablen beschriebenen Geltungsbereichen und Lebensdauern. Das Schlüsselwort <code>Static</code> ist jedoch nicht zulässig.

Aktuelle Version vom 28. Januar 2023, 00:36 Uhr

Eine Variable ist ein Speicherort, an dem ein Wert abgelegt werden kann, der später in der Programmierung abgerufen oder verändert werden soll.

Variablen anlegen

Deklaration

Um eine Variable verwenden zu können, muss sie deklariert werden. Damit wird der Speicherort reserviert und der Name der Variable dient als Kennung, damit später auf genau diesen Wert zugegriffen werden kann.

Der reservierte Platz und die Art des Speicherplatzes wird mit dem angegebenen Datentyp bestimmt. So wird bei der Deklaration festgelegt, ob z. B. eine Zahl oder ein Text oder ein Datum gespeichert wird.

Den Datentyp kann man nur bei der Deklaration angeben und später nicht ändern.

Bei der Deklaration können mehrere Variablen in einer Zeile gemeinsam angegeben werden und werden dann durch Kommata voneinander getrennt:

Dim strName As String, strAddress As String
Public FirstName As String, LastName As String, Phone as String 

Bitte beachten:

  • Sie können zwar mehrere Variablen von verschiedenen Datentypen in einer Zeile deklarieren, sollten dies jedoch vermeiden, um Ihres Programmcode nicht unnötig kompliziert zu gestalten!
  • Wenn Sie mehrere Variablen in einer Zeile deklarieren, müssen Sie jedes Mal mit 'As' den Datentyp angeben, sonst wird die Variable als 'Variant' deklariert.

Datentyp

Der Datentyp wird bei allen Variablen mit dem Schüsselwort As und dem Bezeichner des Datentyps angegeben.

Eine vollständige Liste der in VBA möglichen Datentypen finden Sie hier: Datentypen

Benennung

Um den Zweck der Variablen klar zu kennzeichnen, sollten Sie eindeutige, sprechende Namen wählen, welche jederzeit und für jedermann und innerhalb des Kontextes eine klare Bedeutung haben.

Beispiele:

Dim strFirstName As String, strLastName As String

Die Bezeichnung und der Datentyp, welcher Teil des Namens ist (im Beispiel das vorangestellte 'str') lassen keinen Zweifel zu, welche Daten diese Variablen enthalten.

Der Grund für die ausdrückliche Angabe des Datentyps auch im Variablennamen wird mit diesem Beispiel verdeutlicht:

Dim strItem As String
Dim lngItem As Long
Dim colCollection As New Collection

colCollection.Add "One"
colCollection.Add "Two"
For lngItem = 1 To colCollection.Count
    strItem = colCollection.Item(lngItem)
Next lngItem

Der Name 'Item' wird zweimal unabhängig voneinander belegt, einmal als Zeichenkette, die einen Wert entgegennimmt, und dann als Zählvariable für die For-Schleife. In beiden Fällen ist der Name 'Item' gerechtfertigt, durch das vorangestellte 'str' bzw. 'lng' können beide trotzdem klar voneinander unterschieden werden.

Weitere Angaben zur Bezeichnung des Datentyps im Variablennamen finden Sie im Anhang.

Reihenfolge

Die Reihenfolge, in der Datentypen deklariert werden, hat keine Auswirkung auf die Ausführung des Programmcodes, durchaus jedoch auf die Lesbarkeit für uns Programmierer!

Gewöhnen Sie es sich daher gerne an, Ihre Deklarationen immer in der gleichen Reihenfolge anzulegen, um später schnell ermitteln zu können, welche Variablen schon angelegt wurden und welche Rolle diese in dieser Prozedur spielen.

Die von mir persönlich verwendete Reihenfolge gestaltet sich folgendermaßen:

  • Zeichenketten
  • Zahlenwerte nach Größe sortiert (Integer, Long, Single, Double)
  • Collections
  • Eigene Objekte (zum Beispiel Klassen), Enums und benutzerdefinierte Datentypen
  • Anwendungsobjekte wenn möglich nach Größe sortiert (zum Beispiel Bereich, Dokument, Anwendung in Word oder Zelle, Arbeitsblatt, Arbeitsmappe in Excel)

Der gespeicherte Wert

Abhängig von seinem Datentyp enthält der Speicherplatz einer Variablen bei der Deklaration einen leeren Wert:

Ursprünglicher Leerwert

  • String: "" (Leerstring)
  • Integer und Long: 0
  • Single, Double, Currency etc.: 0.0
  • Date: 00:00:00 (Uhrzeit!)
  • Boolean: False (0)
  • Array: abhängig vom Datentyp
  • Collections, Objekte, Klassen: Nothing

Werte ändern

Bitte beachten: Anders als in vielen anderen Programmiersprachen können Sie in VBA nicht bei der Deklaration der Variablen einen Wert zuweisen. Folgendes ist also nicht möglich:

Dim strValue As String = "Hallo!"     ' Verursacht einen Syntaxfehler!!!!!

Natürliche Datentypen

Um den Speicherplatz einer Variablen sinnvoll nutzen zu können, kann man ihm mit dem Ist Gleich-Operator (=) einen Wert zuweisen.

strValue = "Hallo!"

Objektvariablen

Objektvariablen bekommen mit dem zusätzlichen Schlüsselwort Set eine Instanz des Objektes zugewiesen:

 Dim objApplication As Application
 
 Set objApplication = Application 

Klassenobjekte, UserFormen und Collections müssen erst mit dem Schlüsselwort New neu erzeugt werden, bevor sie verwendet werden können:

Dim myVariables As clsVariables

Set myVariables = New clsVariables
myVariables.FirstName = "Max"
Dim myDialog As frmDialog

Set myDialog = New frmDialog
myDialog.Show
Dim colList As Collection

Set colList = New Collection
colList.Add "Value"

Wichtig: Anwendungsobjekte (Document, Workbook, Range, Font, ...) können nicht mit New neu erzeugt werden, denn sie existieren schon, sobald die Anwendung gestartet wurde. Wenn Sie ein neues Dokument erzeugen möchten, verwenden Sie stattdessen folgende Vorgehensweise:

Dim doc As Document

Set doc = Application.Documents.Add     ' erzeugt ein neues Blanko-Dokument und übergibt es an die Variable 'doc'

Zusätzlich ist eine Kurzschreibweise möglich, welche eine Objektvariable bei der Deklaration Initialisiert.

Dim myVariables As New clsVariables

myVariables.FirstName = "Max"
Dim myDialog As New frmDialog

myDialog.Show
Dim colList As New Collection

colList.Add "Value"

Diese Kurzschreibweise sollte jedoch nur dann verwendet werden, wenn absolut sicher ist, dass Sie das (Klassen-)Objekt, den Dialog oder die Collection auf jeden Fall verwenden werden.

Wenn Sie z. B. vor dem Anzeigen eines Dialoges sicher stellen müssen, dass der Dialog angezeigt werden kann, sollten Sie den Dialog erst dann Instanziieren, wenn Sie ihn auch anzeigen werden.

Dim dlg as frmDialog

If DialogMustBeShown = True Then
    Set dlg = New frmDialog
    dlg.Show
    ' ...
End If

Geltungsbereich, Lebensdauer und Formen der Deklaration

Jede Variable hat einen klar definierten Geltungsbereich, der sich aus dem Ort, an dem sie definiert wurde und den Schlüsselwörtern Private / Public ergibt:

Prozedurale Variable

Diese befindet sich innerhalb einer Prozedur (einer Funktion, einer Eigenschaft) und wird wie folgt mit dem Schlüsselwort Dim deklariert:

Sub TemporaryProceduralVariable()
    Dim strVariable As String
End Sub

Eine prozedurale Variable gilt ausschließlich innerhalb der Prozedur, in der sie definiert wurde. Die Werte sind nicht von anderen Prozeduren aus sichtbar oder veränderbar. Sobald die Prozedur verlassen wird, wird der Speicherplatz freigegeben, die Variable ist somit inklusive ihrem Wert gelöscht.

Statische prozedurale Variable

Eine mit dem Schlüsselwort Static deklarierte prozedurale Variable hat den gleichen Geltungsbereich wie die mit Dim deklarierte Variable, wird jedoch nach Verlassen der Prozedur nicht gelöscht, sondern bleibt solange erhalten, wie das Modul, in dem sich die Prozedur befindet, besteht (bei Modulen so lange das Projekt geladen ist, bei Klassen und UserForms so lange eine Instanz deren besteht).

Sub PermanentProceduralVariable() 
    Static strVariable As String 
End Sub 

So bleibt der Wert der Variable erhalten und kann bei nachfolgenden Aufrufen der Prozedur weiter verwendet werden.

Bitte beachten: Das Schlüsselwort Static darf nicht außerhalb von Prozeduren verwendet werden.

Funktionsname

Der Name einer Funktion kann innerhalb der Funktion wie eine Variable (vom Datentyp der Funktion) verwendet werden und erfüllt zusätzlich den Zweck, den Rückgabewert der Funktion entgegenzunehmen.

Private Function ApplicationName() As String 
    ApplicationName = Application.Name 
End Function 

Der Wert der Variablen, die den Funktionsnamen trägt, kann ausschließlich innerhalb der Funktion geändert werden. Der Wert der Funktion kann wie folgt abgefragt werden:

Sub Example() 
    Dim strAppName As String 
 
    strAppName = ApplicationName() 
    strAppName = ApplicationName 
End Sub 

Die leeren runden Klammern hinter dem Funktionsnamen sind beim Aufruf optional, wenn keine Parameter erwartet werden.

Der Geltungsbereich der Funktion entspricht dem Geltungsbereich aller Prozeduren:

  • Private kann nur innerhalb des (Klassen-)Moduls bzw. der UserForm verwendet werden
  • Public
    • in einem Modul: Kann jederzeit im gesamten Projekt verwendet werden
    • in einer Klasse / einer UserForm: Kann von der Instanz der Klasse / der UserForm aufgerufen und verwendet werden

Modulweite Variablen

Modulweite Variablen können von allen Prozeduren innerhalb eines Moduls verwendet werden, weil sie außerhalb einer speziellen Prozedur deklariert werden.

Sie werden im Modulkopf, also vor der Definition der ersten Prozedur, deklariert.

Hier wir nicht das Schlüsselwort Dim verwendet, sondern Private:

Option Explicit 

Private strVariable As String 

Sub FirstSub() 
    strVariable = "Hallo!" 
End Sub 

Sub SecondSub() 
    MsgBox strVariable 
End Sub 

Modulweite Variablen können nicht von Prozeduren in anderen Modulen ausgelesen oder beschrieben werden.

Bitte beachten: Modulweite und projektweite Variablen sollten nur in solchen Fällen eingesetzt werden, in denen sie sinnvoll sind, und nicht, um 'Variablen zu sparen'.

Wenn Variablen über längere Zeiträume und aus mehreren Quellen Werte behalten bzw. beziehen, kann leicht die Übersicht darunter leiden bzw. können sich unerwartete Werte in den Variablen befinden.

Der sinnvolle Einsatz von modulweiten und projektweiten Variablen wäre zum Beispiel für solche Werte, die über einen längeren Zeitraum erhalten bleiben sollen.

Projektweite Variablen

Wenn Sie Werte hinterlegen möchten, die in ihrem gesamten Projekt jederzeit zur Verfügung stehen, deklarieren Sie eine öffentliche Modulvariable mit dem Schlüsselwort Public:

Option Explicit 

Public Variable As String 

Auf diese Variable können Sie nun auch aus anderen Modulen, Klassen und Formen heraus zugreifen und von dort aus auch die Werte ändern.

Um Ihr Projekt übersichtlich zu gestalten, empfehlen wir, dass Sie projektweite Variablen, wenn möglich, in einem Modul sammeln.

Bitte beachten: Modulweite und projektweite Variablen sollten nur in solchen Fällen eingesetzt werden, in denen sie sinnvoll sind, und nicht, um 'Variablen zu sparen'.

Wenn Variablen über längere Zeiträume und aus mehreren Quellen Werte behalten bzw. beziehen, kann leicht die Übersicht darunter leiden bzw. können sich unerwartete Werte in den Variablen befinden.

Der sinnvolle Einsatz von modulweiten und projektweiten Variablen wäre zum Beispiel für solche Werte, die über einen längeren Zeitraum erhalten bleiben sollen.

Besondere Geltungsbereiche in Klassen und UserFormen

Da UserFormen eine besondere Form von Klassenmodulen sind und sich im Bezug auf Variablen identisch verhalten, werden wir in diesem Abschnitt nicht getrennt auf sie eingehen, sondern wie Klassen behandeln.

Prozedurale und private Klassen-Variablen

Prozedurale Variablen folgen den oben angegebenen Regeln; sie gelten ausschließlich innerhalb der Prozedur, in der sie definiert wurden. Mit Private deklarierte Klassen-Variablen gelten ebenfalls ausschließlich innerhalb der Klasse bzw. der UserForm.

Öffentliche Klassenvariablen

Mit Public deklarierte Klassen-Variablen stehen zusätzlich den Instanzen der Klasse zur Verfügung.

Sie können wie Eigenschaften eingesetzt werden, wenn man die Werte ungeprüft entgegennehmen kann und die Vergabe von neuen Werten nicht beeinflussen möchte.

Beispielklasse 'clsVariables':

Option Explicit 

Public FirstName As String, LastName As String, Phone As String 
Private strClassVariable As String 

Public Sub DoSomething() 
    Dim strMyValue As String 
    
    MsgBox FirstName 
End Sub

Beispielmodul 'modTest':

Option Explicit 

Sub Example() 
    Dim myVariables As clsVariables 
    
    Set myVariables = New clsVariables 
    myVariables.FirstName = "Max" 
    myVariables.LastName = "Muster" 
    myVariables.Phone = "+49 123 4656789" 
    myVariables.DoSomething 
End Sub 

Darstellung im VBA-Editor: Ausschließlich die öffentlichen Variablen und Prozeduren stehen der Instanz myVariables zur Verfügung: ClassVariables.png

Übergabeparameter

Wenn einer Prozedur ein Wert übergeben wird, wird dieser nach dem Prozedurnamen innerhalb der runden Klammern angegeben.

Mehrere Parameter werden durch Kommata getrennt.

Private Sub SingleParameter(ByVal lngValue As Long) 

End Sub
Private Sub ListOfParameters(ByVal lngValue As Long, ByVal strValue As String, ByVal dteDate As Date)

End Sub

ByVal

Der Geltungsbereich beschränkt sich mit dem Schlüsselwort ByVal wie bei prozeduralen Variablen auf die Prozedur, der sie übergeben wird.

Private Sub ParameterByVal(ByVal lngValue As Long) 

    ' ... 
    lngValue = lngValue + 1 
    '.... 
End Sub 

Private Sub Test() 
    Dim lngNumber As Long 
    
    lngNumber = 5 
    ParametersByVal lngNumber 
    Debug.Print lngNumber           ' Der Wert ist immer noch 5 
End Sub 

Das bedeutet, dass die empfangende Prozedur eine neue Variable mit dem gewünschten Wert erhält. Wenn dieser Wert innerhalb der Prozedur geändert wird, betrifft diese Änderung NICHT die Variable in der absendenden Prozedur.

ByRef

Wird ein Parameter mit dem Schlüsselwort ByRef übergeben, verhält sich die Variable innerhalb der Prozedur, an der sie übergeben wurde, identisch zu ByVal.

Aber der Wert wird nicht in einer neuen Variablen übergeben, sondern über eine Referenz auf die aufrufende Variable:

Private Sub ParametersByRef(ByRef lngValue As Long)

    ' ... 
    lngValue = lngValue + 1 
    '.... 
End Sub 

Private Sub Test() 
    Dim lngNumber As Long 
    
    lngNumber = 5 
    ParametersByRef lngNumber 
    Debug.Print lngNumber      ' Der Wert ist jetzt 6!!! 
End Sub 

Über diese Referenz erhält also die aufgerufene Prozedur Zugriff auf den Original-Speicherplatz und kann dessen Wert direkt ändern. Dies kann selbstverständlich zu großer Verwirrung führen, wenn Sie nicht mit diesem Verhalten rechnen.

Bitte beachten: Wenn Sie bei einem Parameter keine zusätzliche Angabe machen, wird standardmäßig die Übergabe ByRef vorgenommen!

Optionale Parameter

Generelles zu optionalen Parametern

Das Schlüsselwort 'Optional' gibt an, dass der beschriebene Parameter optional ist, also nicht zwingend angegeben werden muss.

In der Hilfe und in der Quickinfo (STRG + i) werden optionale Parameter in eckigen Klammern dargestellt.

Bei der 'MsgBox'-Funktion wird dies zum Beispiel deutlich: Der Prompt wird zwingend erwartet, alle weiteren Parameter sind optional und können bei Bedarf weggelassen werden.

 MsgBox(Prompt, [Buttons As VbMsgBoxStyle = vbOKOnly], [Title], [HelpFile], [Context]) As VbMsgBoxResult

Bei einer eigenen Prozedur sieht das dann so aus:

Private Sub OptionalParameter(ByVal strNecessary As String, Optional ByVal lngOptional As Long) 

End Sub

Quickinfo:

OptionalParameter(ByVal strNecessary As String, [ByVal lngOptional As Long])

Sie können für einen optionalen Parameter einen Standardwert vergeben:

Private Sub OptionalParameter(ByVal strNecessary As String, Optional ByVal lngOptional As Long = 3) 

End Sub

Der Aufruf kann nun wie folgt durchgeführt werden:

OptionalParameter "Hallo" 

oder mit zweitem Parameter

OptionalParameter "Hallo", 7 

aber niemals

OptionalParameter         ' Ganz ohne Parameter
OptionalParameter , 7     ' Nur mit Angabe des zweiten Parameters
Regeln
  • Bitte die hier gezeigte Reihenfolge einhalten ('Optional' erscheint vor 'ByVal', 'ByRef' bzw. dem Namen des Parameters).
  • Der Standardwert wird nach der Angabe des Datentyps platziert.
  • Wichtig: Nach einem optionalen Parameter können ausschließlich weitere optionale Parameter erscheinen!!! Alle benötigten Parameter stehen damit am Anfang der Parameter-Liste, optionale am Ende.

Bitte beachten: Die 'IsMissing'-Funktion soll prüfen, ob einem optionalen Parameter ein Wert übergeben wurde. Dies klappt allerdings nur für Variant-Werte!

Tipp: Wenn Sie prüfen möchten, ob ein optionaler Parameter angegeben wurde, belegen Sie ihn mit einem unwahrscheinlichen oder unmöglichen Wert:

Beispiel: Hier wird der Standardwert für 'lngRoundToDigits' mit einem nicht möglichen Wert '-1' vorbelegt:

Public Function RandomDouble(ByVal dblBottom As Double, ByVal dblTop As Double, Optional ByVal lngRoundToDigits As Long = -1) As Double

    Randomize
    RandomDouble = dblBottom + Rnd() * (dblTop - dblBottom)
    
    ' Wenn die Funktion ohne Angabe der Anzahl der Nachkommastellen aufgerufen wird, beträgt der Wert weiterhin -1,
    ' welches nicht möglich ist, denn es gibt keine negativen Nachkommastellen.
    ' Statt nun also das Ergebnis auf eine Ganzzahl zu runden (welches bei 0 der Fall wäre), kann nun mit einer If-Abfrage das Runden komplett verhindert werden:
    
    If lngRoundToDigits >= 0 Then
        RandomDouble = Round(RandomDouble, lngRoundToDigits)
    End If
End Function

Private Sub Test()
    
    Debug.Print RandomDouble(0, 5)          ' 3,75971466302872  (ungerundeter Wert)
    Debug.Print RandomDouble(0, 5, 0)       ' 4                 (auf ganze Zahl gerundet)
    Debug.Print RandomDouble(0, 5, 5)       ' 3,75971           (auf 5 Nachkommastellen gerundet)
End Sub

Arbeiten mit Optionalen Parametern

Bei Variant-Parametern können Sie mit der IsMissing-Funktion prüfen, ob der optionale Parameter übergeben wurde:

Public Sub DoSomething(Optional ByVal varWithThis As Variant)
    
    If IsMissing(varWithThis) = False Then
        MsgBox "Der Parameter wurde übergeben!"
        End If
    End Sub
Private Sub TestDoSomething()
    DoSomething ' Kein Parameter ...
    DoSomething "Irgendwas"
End Sub

Empfohlen wird jedoch, stattdessen mit dem Leerwert des Parameters oder einem unwahrscheinlichen Vorgabewert zu arbeiten:

Public Sub DoSomething(Optional ByVal strWithThis As String)
    
    If strWithThis <> "" Then
        MsgBox "Der Parameter wurde übergeben!"
    End If
End Sub
Public Sub DoSomething(Optional ByVal lngWithThis As Long =  - 43423442)

    If lngWithThis <> - 43423442 Then
        MsgBox "Der Parameter wurde übergeben!"
    End If
End Sub

Der Vorteil dieser letzten Beispiele ist, dass Sie nicht ausschließlich mit Variant-Parametern arbeiten müssen, um dann mit 'IsMissing' festzustellen, ob der Parameter verwendet wurde.

Konstanten

Eine Konstante ist ein Speicherort, an dem ein fester Wert hinterlegt werden kann. Der Wert wird bei der Deklaration angegeben und kann danach nicht wieder geändert werden.

Deklaration und Wertzuweisung

Eine Konstante wird mit dem Schlüsselwort Const deklariert, der Wert wird anschließend mit '=' zugewiesen:

Prozedurale Konstante:

Const strConstant As String = "Konstanter Wert"     ' NICHT: Dim Const strConstant As String = "Konstanter Wert"

Alle weiteren Konstanten:

Private Const strConstant As String = "Konstanter Wert" 
Public Const Constant As String = "Konstanter Wert" 

Bitte beachten: Bei konstanten Datumsangaben muss der Datumswert entweder als Zahl oder eindeutiger Datums-String angegeben werden. Eine Umwandlung mit der Funktion CDate() ist nicht möglich!

Const dteEstablished As Date = "1984-03-01" 
Const dteIncorporated As Date = 36742

Datentypen

Da Konstanten ausschließlich bei der Deklaration den gewünschten Wert erhalten können, können sie ausschließlich natürliche Datentypen enthalten, also keine (Klassen-)Objekte, Types, Collections oder Arrays.

Eine vollständige Liste der in VBA verwendeten Datentypen finden Sie hier: Datentypen

Geltungsbereich und Lebensdauer

Geltungsbereich und Lebensdauer sind identisch zu den bei Variablen beschriebenen Geltungsbereichen und Lebensdauern. Das Schlüsselwort Static ist jedoch nicht zulässig.