Variablen: Unterschied zwischen den Versionen

Aus VBA-wiki
Zur Navigation springen Zur Suche springen
Keine Bearbeitungszusammenfassung
 
(16 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 83: Zeile 84:


'''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:
'''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!!!!!
  <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.
Um den Speicherplatz einer Variablen sinnvoll nutzen zu können, kann man ihm mit dem Ist Gleich-Operator (=) einen Wert zuweisen.
  strValue = "Hallo!"
  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:
Objektvariablen bekommen mit dem zusätzlichen Schlüsselwort <code>Set</code> eine Instanz des Objektes zugewiesen:
  Dim objApplication As Application
  <span style="Color:blue"> Dim </span>objApplication<span style="Color:blue"> As </span>Application
 
  Set objApplication = 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:
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
  <span style="Color:blue">Dim </span>myVariables<span style="Color:blue"> As </span>clsVariables
   
  <span style="Color:blue">
  Set myVariables = New clsVariables
  Set </span>myVariables <span style="Color:gray">=</span><span style="Color:blue"> New </span>clsVariables
  myVariables.FirstName = "Max"
  myVariables<span style="Color:gray">.</span>FirstName <span style="Color:gray">=</span> <span style="Color:gray">"Max"</span>


  Dim myDialog As frmDialog
  <span style="Color:blue">Dim </span>myDialog<span style="Color:blue"> As </span>frmDialog
   
  <span style="Color:blue">
  Set myDialog = New frmDialog
  Set </span>myDialog <span style="Color:gray">=</span><span style="Color:blue"> New </span>frmDialog
  myDialog.Show
  myDialog<span style="Color:gray">.</span>Show


  Dim colList As Collection
  <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>
   
   
Set colList = New Collection
colList.Add "Value"


'''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:
'''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:


  Dim doc As Document
  <span style="Color:blue">Dim </span>doc<span style="Color:blue"> As </span>Document
   
  <span style="Color:blue">
  Set doc = Application.Documents.Add         ' erzeugt ein neues Blanko-Dokument und übergibt es an die Variable 'doc'
  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. 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.  
Zusätzlich ist eine Kurzschreibweise möglich, welche eine Objektvariable bei der Deklaration Initialisiert.  


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>myVariables<span style="Color:blue"> As New </span>clsVariables
  Dim myVariables As New clsVariables
   
   
  myVariables.FirstName = "Max"
  myVariables<span style="Color:gray">.</span>FirstName <span style="Color:gray">=</span> <span style="Color:gray">"Max"</span>


  Dim myDialog As New frmDialog
  <span style="Color:blue">Dim </span>myDialog<span style="Color:blue"> As New </span>frmDialog
   
   
  myDialog.Show
  myDialog<span style="Color:gray">.</span>Show


  Dim colList As New Collection
  <span style="Color:blue">Dim </span>colList<span style="Color:blue"> As New </span>Collection
   
   
  colList.Add "Value"
  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 139: 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.


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.
'''Bitte beachten:''' Das Schlüsselwort <code>Static</code> darf nicht außerhalb von Prozeduren verwendet werden.


==== Statische prozedurale Variable ====
=== Funktionsname ===


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.
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.  


==== Funktionsname ====
<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>


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 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:  
 
<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>
 
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:
* <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 155: 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.


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.
=== Projektweite Variablen ===


==== 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>:


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.
<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.  
 
'''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 ====
==== Besondere Geltungsbereiche in Klassen und UserFormen ====
Zeile 167: 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">


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]]
'''Darstellung im VBA-Editor:''' Ausschließlich die öffentlichen Variablen und Prozeduren stehen der Instanz <code>myVariables</code> zur Verfügung: [[Datei:ClassVariables.png]]


==== Übergabeparameter ====
== Ü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) Private Sub ListOfParameters(ByVal lngValue As Long, ByVal strValue As String, ByVal dteDate As Date)
Wenn einer Prozedur ein Wert übergeben wird, wird dieser nach dem Prozedurnamen innerhalb der runden Klammern angegeben.  


===== ByVal =====
Mehrere Parameter werden durch Kommata getrennt.


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.
<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


===== ByRef =====
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">


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!
=== ByVal ===


==== Optionale Parameter ====
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.


===== Generelles zu optionalen Parametern =====
<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>


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
<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.
 
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<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">
 
Bei einer eigenen Prozedur sieht das dann so aus:
 
<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>
 
Quickinfo:
 
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>
 
Sie können für einen optionalen Parameter einen Standardwert vergeben:  
 
<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>
 
Der Aufruf kann nun wie folgt durchgeführt werden:  
 
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.


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


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.
'''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
 
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>
 
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 206: 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.