HERBERS Excel-Forum - VBA-Basics

Thema: Variablen und Arrays

Inhaltsverzeichnis
  • 1 Grundlegendes
  • 2 Konstanten
  • 3 Variablentypen
  • 4 Variablendeklaration
  • 5 Einsatz von String-Variablen
  • 6 Einsatz von Variant-Variablen
  • 7 Einsatz von Public-Variablen
  • 8 Übergabe von String-Variablen
  • 9 Variablen in Funktionen
  • 10 Hierarchische Anordnung der Objekttyp-Variablen
  • 11 Collections von Objekttyp-Variablen
  • 12 Arrays und Feldvariablen
  • Grundlegendes

    Was sind Variablen?

    Variablen sind eine Art von Platzhalter für Zeichenfolgen, Werte und Objekte. So können beispielsweise mehrfach anzuzeigende Meldungen, bei Berechnungen mehrfach einzusetzende Werte oder in einer Schleife anzusprechende Objekte in Variablen gespeichert werden.

    Wann sind Variablen einzusetzen?

    Der Einsatz von Variablen ist immer dann sinnvoll, wenn das Element mehrfach angesprochen wird. Sinnvoll eingesetzt, beschleunigen Variablen die Ausführung eines VBA-Programms erheblich. Wird das Element im Code nur einmal angesprochen - wie z.B. eine Msg-Meldung - ist das Speichern dieser Zeichenfolge in eine String-Variable überflüssig und verwirrend. Ausnahmen bilden Fälle, in denen auch bei einmaligem Vorkommen die Übersichtlichkeit des Codes verbessert wird. Dies kann beispielsweise bei langen Objektnamen der Fall sein.

    Sind Variablen zu deklarieren?

    Eine Deklaration der Variablen sollte immer erfolgen. Um sich dazu zu zwingen, sollte man in der Entwicklungsumgebung im Menü Extras / Optionen die CheckBox Variablendeklaration erforderlich aktivieren.

    Wo sind Variablen zu deklarieren?

    Variablen, die nur für die Prozedur gelten sollen, sind innerhalb der Prozedur, in der Regel am Prozuduranfang zu deklarieren. Variablen, die außerhalb einer Prozedur deklariert werden, gelten für das ganze Modul, werden sie als Public dekariert, für das gesamte Projekt. Zu einem sauberen Programmierstil gehört es, Variablen soweit irgend möglich nur auf Prozedurebene zu deklarieren und an Unterprogramme als Parameter zu übergeben.

    Sind Variablen zu dimensionieren?

    Variablen sind immer zu dimensionieren. Hiervon gibt es keine Ausnahmen.

    Sind Objekttyp-Variablen bestimmten Objekten zuzuweisen?

    Jeder Objekttyp-Variablen ist das Objekt korrekt zuzuweisen. Diese Vorgehensweise beschleunigt den Programmablauf, ausserdem werden in der Entwicklungsumgebung während der Programmierphase - wenn im obigen Dialog die CheckBox Elemente automatisch auflisten aktiviert ist - beim Ansprechen des Objekts alle Objektelemente automatisch aufgelistet, was Fehler vermeidet und Schreibarbeit erspart.

    Konstanten

    Konstanten werden hier der Vollständigkeit halber erwähnt. Weisen Sie immer dann, wenn ein Wert vom Programmstart bis zum Programmende unverändert bleibt, diesen einer Konstanten, keiner Variablen zu. Konstanten werden in VBA-Programmen schneller berechnet als Variablen. Konstanten werden generell im Allgemein-Abschnitt von Modulen deklariert, Private-Konstanten in Klassen- und Standard-, Public-Konstanten nur in Standardmodulen. Beispiel für eine Konstanten-Deklaration:

    
    Private Const cintStart As Integer = 5
    


    Variablentypen

    Die gebräuchlichen Variablentypen:

    VariablentypNamenskonventionRes.SpeicherplatzKurzbezeichnungBeschreibung
    Boolean bln16 Bit, 2 Bytes WAHR (1) oder FALSCH (0)
    Integerint16 Bit, 2 Bytes %-32.768 bis 32.767
    Long lng32 Bit, 4 Bytes&-2.147.483.648 bis 2.147.483.647
    Currencycur @-922.337.203.685.477,5808 bis 922.337.203.685.477,5807
    Singlesng32 Bit, 4 Bytes !-3,402823E38 bis -1,401298E-45 für negative Werte und von 1,401298E-45 bis 3,402823E38 für positive Werte
    Doubledbl64 Bit, 8 Bytes#-1.79769313486231E308 bis -4,94065645841247E-324 für negative Werte und von 4,94065645841247E-324 bis 1,79769313486232E308 für positive Werte
    Datedat64 Bit, 8 Bytes Datum und Zeit
    Stringstr $Zeichenfolgen
    Objectobj32 Bit, 4 Bytes Objekte
    Variantvar128 Bit, 16 Bytes Alle Typen, Voreinstellung
    benutzerdefinierter Typtyp ein oder mehrere Elemente jeden Datentyps
    Objekttyp Objekte wie Workbook, Range

    Variablendeklaration

    Wie schon erwähnt, sind Variablen generell zu deklarieren und zu dimensionieren. Werden sie nicht deklariert oder nicht dimensioniert, handelt es sich beim Programmstart in jedem Fall um den Variablentyp Variant, der zum einen mit 16 Bytes den größten Speicherplatz für sich beansprucht, zum anderen während des Programmablaufes seinen Typ mehrmals wechseln kann, was möglicherweise die Programmausführung erschwert. Außerdem benötigen Variant-Variablen erheblich längere Berechnungszeiten als andere.

    Einsatz von String-Variablen

    Im nachfolgenden Beispiel wird eine String-Variable deklariert und zum Finden und Ersetzen einer Zeichenfolge eingesetzt:

    
    Sub Ersetzen()
       Dim rngCell As Range
       Dim strText As String
       strText = "Kasse "
       strYear = CStr(Year(Date))
       For Each rngCell In Range("A1:F15")
          If rngCell.Value = strText & Year(Date) - 1 Then
             rngCell.Value = strText & Year(Date)
          End If
       Next rngCell
    End Sub
    

    Im vorgegebenen Bereich werden alle Zellen darauf überprüft, ob ihr Text aus der Zeichenfolge Kasse und der Jahreszahl des Vorjahres besteht. Wenn ja, wird die Vorjahreszahl durch die aktuelle Jahreszahl ersetzt. String-Variablen werden mit dem &-, nicht dem +-Zeichen verknüpft. Der Einsatz des Pluszeichens kann zu überraschenden, ungewollten Ergebnissen führen.

    Einsatz von Variant-Variablen

    Es gibt Fälle, in denen es wünschenswert ist, dass eine Variable ihren Typ ändert. In diesem Fall können Variant-Variablen eingesetzt werden. Ein typisches Beispiel:

    
    Sub Oeffnen()
       Dim varFile As Variant
       varFile = Application.GetOpenFilename("Excel-Dateien (*.xls), *.xls")
       If varFile = False Then Exit Sub
       Workbooks.Open varFile
    End Sub
    

    Es wir ein Dialog zur Auswahl einer Datei aufgerufen. Wird dieser über die Schaltfläche Abbrechen beendet, nimmt die Variable varFile den Typ Boolean und den Wert False an. Wird der Dialog nicht abgebrochen, sondern normal beendet, wird varFile zu einer String-Variablen mit dem Dateinamen als Wert.

    Einsatz von Public-Variablen

    Im nachfolgenden Beispiel wird in einem Standardmodul eine Public-String-Variable deklariert. Diese wird in der Prozedur AufrufenMeldung mit einem Wert belegt; danach wird das Unterprogramm Meldung aufgerufen. Da die Variable außerhalb der Prozeduren deklariert wurde, ist der Wert nicht verlorengegangen und kann weiterverwertet werden.

    
    
    Public strMsg As String
    
    Sub AufrufenMeldung()
        strMsg = "Hallo!"
        Call Meldung
    End Sub
    
    Sub Meldung()
        MsgBox strMsg
    End Sub
    

    Auch wenn sich die Prozedur Meldung in einem anderen Modul befindet, funktioniert der Aufruf. Erfolgt jedoch die Deklaration mit Dim oder als Private, gilt sie nur für das jeweilige Modul.

    Übergabe von String-Variablen

    Eine Vorgehensweise wie im vorhergehenden Beispiel ist zu meiden und eine Übergabe der Variablen als Parameter ist vorzuziehen:

    
    Sub AufrufenMeldung()
       Dim strMsg As String
       strMsg = "Hallo!"
       Call Meldung(strMsg)
    End Sub
    
    Sub Meldung(strMsg As String)
       MsgBox strMsg
    End Sub
    

    Variablen in Funktionen

    Funktionen werden eingesetzt, wenn Werte zurückgeliefert werden müssen. Eine Alternative wäre (neben einer ByRef-Variablenübergabe) der Einsatz von Public-Variablen, die wir ja meiden wollen. Bei den Parametern einer Funktion handelt es sich ebenfalls um Variablen. Der Deklarationsbereich liegt innerhalb der Klammern der Funktion. Diese Parameter müssen beim Aufruf der Funktion - aus einem Tabellenblatt oder aus einer anderen Prozedur - übergeben werden. In der nachfolgenden Funkion wird die Kubatur errechnet:

    
    Function Kubatur( _
       dblLaenge As Double, _
       dblBreite As Double, _
       dblHoehe As Double) As Double
       Kubatur = dblLaenge * dblBreite * dblHoehe
    End Function
    

    Die Eingabesyntax einer solchen Prozedur in einem Tabellenblatt ist, wenn die Werte in den Zellen A1:C1 stehen:

    
    =kubatur(A1;B1;C1)
    

    Wird die Funktion aus einer anderen Prozedur zur Weiterverarbeitung aufgerufen, sieht das wie folgt aus:

    
    Sub ErrechneGewicht()
       Dim dblSpezGewicht As Double, dblKubatur As Double
       dblSpezGewicht = 0.48832
       dblKubatur = Kubatur(Range("A1"), Range("B1"), Range("C1"))
       Range("E1").Value = dblKubatur * dblSpezGewicht
    End Sub
    

    Hierarchische Anordnung der Objekttyp-Variablen

    Über die Objekttypvariablen kann ein Typengerüst aufgebaut werden, indem die jeweils aktuelle Ebene referenziert wird:

    
    Sub NeueSymbolleiste()
       Dim objCmdBar As CommandBar
       Dim objPopUp As CommandBarPopup
       Dim objButton As CommandBarButton
       Dim intMonth As Integer, intDay As Integer
       On Error Resume Next
       Application.CommandBars("Jahr " & Year(Date)).Delete
       On Error GoTo 0
       Set objCmdBar = Application.CommandBars.Add("Jahr " & Year(Date), msoBarTop)
       For intMonth = 1 To 12
          Set objPopUp = objCmdBar.Controls.Add(msoControlPopup)
          objPopUp.Caption = Format(DateSerial(1, intMonth, 1), "mmmm")
          For intDay = 1 To Day(DateSerial(Year(Date), intMonth + 1, 0))
             Set objButton = objPopUp.Controls.Add
             With objButton
                .Caption = Format(DateSerial(Year(Date), intMonth, intDay), _
                   "dd.mm.yy - dddd")
                .OnAction = "MeldenTag"
                .Style = msoButtonCaption
             End With
          Next intDay
       Next intMonth
       objCmdBar.Visible = True
    End Sub
    

    Mit vorstehendem Code wird eine neue Symbolleiste mit dem Namen des aktuellen Jahres angelegt und im Symbolleistenbereich als nächstuntere platziert. Der Leiste wird für jeden Monat ein Menü und diesem Menü wird für jeden Tag eine Schaltfläche hinzugefügt.

    Das Auslesen der betätigten Schaltfläche und die Datumsberechnungen erfolgen anhand einer Datumsvariablen:

    
    Private Sub MeldenTag()
        Dim datAC As Date
        datAC = DateSerial(Year(Date), Application.Caller(2), Application.Caller(1))
        Select Case datAC
            Case Is < Date
                MsgBox Date - datAC & " Tage vergangen"
            Case Is = Date
                MsgBox "Heute"
            Case Is > Date
                MsgBox "Noch " & datAC - Date & " Tage"
        End Select
    End Sub
    
    

    Collections von Objekttyp-Variablen

    Das Objekt UserForm1.Controls stellt alle Steuerelemente dar, die in der UserForm1 enthalten sind. Nicht ganz so einfach ist es, auf alle CheckBoxes dieser UserForm zuzugreifen, um sie über eine Schleife zu bearbeiten, denn die CheckBox ist kein gültiges Objekt, das heißt Controls. Liest man die CheckBoxes in ein Collection-Objekt ein, lassen Sie sich später problemlos ansprechen und in Schleifen einbinden:

    
    Public colChBox As New Collection
    
    Private Sub UserForm_Initialize()
       Dim cnt As Control, intMonth As Integer
       For Each cnt In Controls
          If TypeName(cnt) = "CheckBox" Then
             intMonth = intMonth + 1
             colChBox.Add cnt
             cnt.Caption = Format(DateSerial(1, intMonth, 1), "mmmm")
          End If
       Next cnt
    End Sub
    

    Das Collection-Objekt wird - damit es seinen Wert nicht verliert - als Public außerhalb einer Prozedur deklariert und im Initialisierungscode der UserForm mit den Einzelobjekten - den 12 CheckBoxes der UserForm - belegt. Beim Klick auf die Schaltfläche Meldung werden alle aktivieren CheckBoxes in einer MsgBox ausgegeben:

    
    Private Sub cmdMeldung_Click()
       Dim intCounter As Integer
       Dim strMsg As String
       strMsg = "Aktiviert:" & vbLf
       For intCounter = 1 To 12
          If colChBox(intCounter).Value Then
             strMsg = strMsg & colChBox(intCounter).Caption & vbLf
          End If
       Next intCounter
       MsgBox strMsg
    End Sub
    
    

    Arrays und Feldvariablen

    Es gibt grundsätzlich zwei Möglichkeiten, Variablen für Matrizen zu schaffen. Entweder man deklariert die Variable als Variant und weist ihr ein Array zu oder man deklariert sie als Datenfeld. Variant-Variablen können Datenfeldvariablen aufnehmen.