Abfragen

Aus VBA-wiki
Wechseln zu: Navigation, Suche

If-Abfrage

Eine If-Abfrage prüft, ob der in der Abfrage eingeschlossene Anweisungsblock ausgeführt werden soll. Der Anweisungsblock beginnt nach dem 'Then' (bzw. nach dem 'Else') und endet bei 'End If' (bzw. vor dem 'Else' oder einem 'ElseIf'). In der Regel wird der Anweisungsblock durch Einzüge verdeutlicht.

Einfache If-Abfrage

Eine If-Abfrage können wir uns wie eine Weiche vorstellen, welche die Ausführung des Codes nach Prüfung der Bedingung auf einen Umweg schickt: /[ja]: Führe dies durch \ ... Anweisungen <Ist Bedingung erfüllt?>| > Weitere Anweisungen ... \[nein]-----------------/ Sie wird in VBA wie folgt formuliert: ' Programmschritte If Bedingung = Erfüllt Then ' Anweisungsblock: Wenn erfüllt, wird dies ausgeführt End If ' Weitere Programmschritte Beispiel: Private Function EnterNumber() Dim lngNumber As Long lngNumber = InputBox("Bitte geben Sie eine Zahl ein:") If lngNumber = 3 Then MsgBox "Eingegebene Zahl ist 3" End If EnterNumber = lngNumber ' Anweisungen nach dem If-Block werden unabhängig von der If-Abfrage ausgeführt End Function

Else-Zweig

Der Else-Zweig einer If-Abfrage dient dazu, die Fälle zu behandeln, welche die ursprüngliche(n) Bedingung(en) nicht erfüllen. Wenn wir uns die einfache If-Abfrage wie eine Weiche vorstellen, dann lässt der Else-Zweig die Ausführung auf beiden getrennten Gleisen zu: /[ja]: Führe dies durch \ ... Anweisungen <Ist Bedingung erfüllt?>| > Weitere Anweisungen ... \[nein]: Führe das durch / Bitte beachten: Der Else-Zweig erscheint immer an letzter Stelle, also vor dem 'End If'. Sie können also nicht nach dem 'Else'-Zweig einen weiteren 'ElseIf' angeben. Siehe auch verschachtelte If-Abfragen. ' Anweisungen If Bedingung = Erfüllt Then ' Anweisungsblock: Wenn erfüllt, wird dies ausgeführt Else ' Anweisungsblock: Wenn nicht erfüllt, wird dies ausgeführt End If ' Weitere Anweisungen Beispiel: Private Function EnterNumber() Dim lngNumber As Long lngNumber = InputBox("Bitte geben Sie eine Zahl ein:") If lngNumber = 3 Then MsgBox "Zahl ist 3" Else MsgBox "Zahl ist ungleich 3" End If EnterNumber = lngNumber End Function Langschreibweise: If intVariable < 5 Then ' Übergeordnete Abfrage End If If intVariable >= 5 Then ' Frage nach dem Gegenteil End If

ElseIf-Zweig

Die in der übergeordneten Abfrage nicht erfüllten Fälle können wir mit 'ElseIf' weiter eingrenzen: Private Sub ElseIf() Dim intAge As Integer intAge = 100 Debug.Print "Age: " & intAge If intAge < 1 Then Debug.Print "Newborn" ElseIf intAge <= 3 Then Debug.Print "Toddler" ElseIf intAge <= 12 Then Debug.Print "Child" ElseIf intAge < 20 Then Debug.Print "Teenager" ElseIf intAge < 30 Then Debug.Print "Twen" ElseIf intAge < 50 Then Debug.Print "Adult" ElseIf intAge < 70 Then Debug.Print "Youngtimer" ElseIf intAge < 100 Then Debug.Print "Oldtimer" Else Debug.Print "Centennial" End If End Sub

Verschachtelte If-Abfragen

Sie können If-Abfragen, wenn es die Logik erfordert oder wenn es der Lesbarkeit dient, ineinander verschachteln: If True Then If MoreTrue Then ' ... ElseIf EvenMoreTrue Then ' ... Else ' ... End If ' ... Else ' ... If OtherTrue Then ' ... End If ' ... End If

'And' und 'Or'

Sub IfAndOr() Dim intVariable As Integer intVariable = 7 ' Oder-Verknüpfung: Mindestens ein Fall tritt ein Debug.Print "Zahl: " & intVariable If intVariable < 5 Then Debug.Print "Zahl ist kleiner 5 oder größer als 10" ElseIf intVariable > 10 Then Debug.Print "Zahl ist kleiner 5 oder größer als 10" End If If intVariable < 5 Or intVariable > 10 Then ' Bei Or muss mindestens ein Fall eintreten Debug.Print "Zahl ist kleiner 5 oder größer als 10" End If ' Und-Verknüpfung: Beide Bedingungen müssen erfüllt sein If intVariable >= 5 Then If intVariable <= 10 Then Debug.Print "Zahl ist zwischen 5 und 10" End If End If If intVariable >= 5 And intVariable <= 10 Then ' Bei And müssen beide Fälle eintreten Debug.Print "Zahl ist zwischen 5 und 10" End If End Sub

Klammersetzung in If-Abfragen

Bei If-Abfragen können mit 'And' bzw. 'Or' zusammengefasste Auswertungen mithilfe von Klammern logisch zusammengefasst werden. In diesem Beispiel besteht die zweite Bedingung (in Klammern) aus zwei optionalen Werten (durch 'Or' verknüpft), insgesamt muss jedoch auch die erste Bedingung erfüllt sein. Ohne Klammern setzt die letzte Bedingung nicht voraus, dass auch die erste erfüllt ist. If strInput01 = "Begrüßung" And (strInput02 = "Hallo" Or strInput02 = "Huhu") Then ' ... End If

Kurzschreibweise

Der Anweisungsblock einer If-Abfrage kann, sofern dieser nur aus einer einzigen Befehlszeile besteht, direkt hinter dem 'Then' angegeben werden. Das 'End If' entfällt dann: If True Then Exit Sub Bei einem ElseIf-Zweig kann dies ebenso eingesetzt werden. Beachten Sie dann jedoch, dass hier das 'End If' erforderlich ist! If True Then Exit Sub ElseIf MoreTrue Then Exit Sub End If Bei einem Else-Zweig fügt der VBA-Editor automatisch einen Doppelpunkt ein. Auch in diesem Fall wird wieder das 'End If' erfordert: If True Then Exit Sub Else: Exit Sub End If Bitte beachten: Diese Schreibweise wird nur dann akzeptiert, wenn die erste Zeile nicht die Kurzschreibweise verwendet! Bitte beachten: Wenn Sie sich für die Kurzschreibweise entschieden haben, dürfen Sie keine weitere Anweisungen im Anweisungsblock angeben! Fazit: Die einfache Kurzschreibweise (erstes Beispiel) kann gerne eingesetzt werden, um den Code kurz, knapp und übersichtlich zu gestalten. Je weiter wir diese ausbauen und mit weiteren Elementen (ElseIf, Else) verknüpfen, desto mehr verliert die Kurzschreibweise jedoch diese Vorteile und wirkt im Gegendsatz eher verwirrend.

Select Case

Am Beispiel des Else-If Zweiges erkennen wir, dass diese Form der Verzweigung sehr unübersichtlich erscheinen kann. Hier kann eine 'Select Case'-Verzweigung deutlich aufgeräumter und übersichtlicher erscheinen: Private Sub SelectCase() Dim intAge As Integer intAge = 100 Debug.Print "Age: " & intAge Select Case intAge Case 0 Debug.Print "Unborn" Case Is < 1 Debug.Print "Newborn" Case Is <= 3 Debug.Print "Toddler" Case Is <= 12 Debug.Print "Child" Case Is < 20 Debug.Print "Teenager" Case Is < 30 Debug.Print "Twen" Case Is < 50 Debug.Print "Adult" Case Is < 70 Debug.Print "Youngtimer" Case Is < 100 Debug.Print "Oldtimer" Case Else Debug.Print "Centennial" End Select End Sub Wie Sie sehen, stehen nun die abgefragten Werte in einer erkennbaren Spalte untereinander, das Auge findet sich gleich in der Struktur zurecht.

Regeln

Die 'Select Case'-Verzweigung hat einen eigenen Satz Regeln, welche Sie beachten müssen:

  • Sie können immer nur eine Variable (einen Rückgabewert einer Funktion, einen vorgegebenen Wert) prüfen
  • Die Vergleichswerte geben Sie in einer neuen Zeile hinter 'Case' an
  • Zusätzliche Einschränkungen ('<', '<=', '<>') werden automatisch um ein 'Is' ergänzt ('Case Is < 70')
  • Der Else-Zweig lautet 'Case Else' Sie können mehrere Werte in einem Zweig abfragen, indem Sie die Werte durch Kommata voneinander trennen: Case 0, 2, 5, Is > 10

Einschränkungen

Im folgenden Fall können die If-Abfragen NICHT durch ein Select ersetzt werden, denn jede If-Abfrage fragt einen anderen Wert ab: Sub SelectCaseLimitations() Dim dteDate As Date If Year(Now()) = 2015 Then ElseIf Year(dteDate) < 2017 Then ElseIf Month(dteDate) > 3 Then End If End Sub

Beispiele

Sub MessageBoxResult() ' Beispiel: Auswertung des Rückgabewertes einer Messsagebox Select Case MsgBox("Select this", vbYesNoCancel) Case 6 MsgBox "Ja!" Case 7 MsgBox "Nö..." Case 2 MsgBox "Abbruch!!!" Case Else MsgBox "Nicht definiert?!?" End Select End Sub Sub SelectString() Select Case InputBox("Bitte geben Sie Ihren Namen an") Case "Patrick Wania" MsgBox "Hallo" Case "Erich Stroheim" MsgBox "Huhu" Case Else MsgBox "Wer sind Sie?!?" End Select End Sub

Vergleichsoperatoren

Um prüfen zu können, ob eine Bedingung erfüllt ist, können folgende Möglichkeiten genutzt werden:

Entspricht genau (=)

Dieser Operator vergleicht zwei Werte miteinander und wird nur genau in dem einen Fall den Vergleich positiv bewerten, wenn beide Werte sich 100 % entsprechen. Eine Umwandlung der Datentypen, falls diese nicht gleich sind, erfolgt dabei automatisch. Debug.Print 1 = 1 ' Wahr Debug.Print 1 = "1" ' Wahr Debug.Print 1 = 1.0 ' Wahr Debug.Print 1.1 = 1 ' Falsch Debug.Print "a" = "A" ' Falsch Da der Vergleich von Zeichenketten die Groß- und Kleinschreibung berücksichtigt, können wir mit den Funktionen UCase() bzw. LCase() diesen Unterschied ausgleichen: Debug.Print "a" = LCase("A") ' Wahr Beim Vergleich von zwei Textvariablen sollten Sie beide Werte gleich umwandeln: Dim strValue01 As String, strValue02 As String strValue01 = "max" strValue02 = "Max" Debug.Print strValue01 = strValue02 ' Falsch Debug.Print LCase(strValue01) = LCase(strValue02) ' Wahr

Ungleich (<>)

Mit dem Ungleich-Operator wird geprüft, ob sich zwei Werte unterscheiden. Hierbei wird nicht berücksichtigt, auf welche Art sich die Werte unterscheiden. Debug.Print 1 <> 1 ' Falsch Debug.Print 1 <> "1" ' Falsch Debug.Print 1 <> 1.0 ' Falsch Debug.Print 1.1 <> 1 ' Wahr Debug.Print "a" <> "A" ' Wahr Beim Vergleich von Zeichenketten beachten Sie bitte die oben beschriebenen Anmerkungen zur Umwandlung für einen Vergleich, welcher die Groß- und Kleinschreibung nicht berücksichtigt: Debug.Print "a" <> LCase("A") ' Falsch Dim strValue01 As String, strValue02 As String strValue01 = "max" strValue02 = "Max" Debug.Print strValue01 = strValue02 ' Wahr Debug.Print LCase(strValue01) = LCase(strValue02) ' Falsch === Größenvergleiche (<, <=, >, >=) === Der Größenvergleich von Zahlen sollte keiner Erklärung bedürfen: Debug.Print 1 < 2 ' Wahr Debug.Print 1 <= 2 ' Wahr Debug.Print 1 < 1 ' Falsch Debug.Print 1 <= 1 ' Wahr usw. Der Größenvergleich von Zeichenketten bewirkt, dass die Zeichenpositionen der einzelnen Buchstaben in der Zeichentabelle betrachtet werden. In der Zeichentabelle beginnen die Großbuchstaben mit dem 'A' an der Position 65, die Kleinbuchstaben mit dem 'a' bei 97. Umlaute und weitere Sonderzeichen erscheinen weiter hinten in der Zeichentabelle. Debug.Print "Max" < "max" ' Wahr Debug.Print "berta" <= "Emil" ' Falsch Debug.Print "Max" < "Max" ' Falsch Debug.Print "Max" <= "Max" ' Wahr usw. Auch bei diesen Vergleichen bietet es sich in bestimmten Fällen an, mit der oben beschriebenen Umwandlungen zu arbeiten, wenn Sie den Vergleich von Texten ohne Berücksichtigung der Groß- und Kleinschreibung durchführen möchten: Debug.Print LCase("Max") < LCase("max") ' entspricht "max" < "max" (Falsch) Debug.Print LCase("berta") <= LCase("Emil") ' entspricht "berta" <= "emil" (Wahr) Debug.Print LCase("Max") <= LCase("max") ' entspricht "max" <= "max" (Wahr) usw.

Mustervergleich (Like)

Der Like-Operator ermöglicht die Überprüfung, ob eine Zeichenkette einem erwarteten Muster entspricht. Hierbei gelten folgende Regeln:

Gruppe Zeichen Regel Beispiel
Generell Texte können direkt verglichen werden, 'Like' verhält sich dann wie '=' strText = "Test" If strText Like "Test" Then MsgBox "Juhuu!" End If ' oder: If strText = "Test" Then MsgBox "Juhuu!" End If
" Wenn Sie ein Anführungszeichen in einen Mustervergleich mit einbeziehen möchten, muss dieses verdoppelt werden ( "" ). "Dann ertönte ""Bitte wenden!""" Like "*""*" ' Enthält der Text ein Anführungszeichen?
Unspezifische Platzhalter  ? Das Fragezeichen ersetzt ein einzelnes beliebiges Zeichen (a, 4, §, ~, Ü, ...) "Test" Like "T???"
Der Stern ersetzt kein oder eine beliebige Anzahl beliebiger Zeichen. "Beispiel" Like "*spiel*"
# Das Doppelkreuz ersetzt eine einzelne Ziffer (0-9) "+49 123 456789" Like "+49 ##*"
Spezifische Platzhalter [ ] In eckigen Klammern kann ein Zeichenbereich oder eine Zeichengruppen angegeben werden, mit der verglichen werden soll. "Übung" Like "[A-ZÄÖÜ]*"
- Mit dem Minus kann in eckigen Klammern ein Zeichenbereich angegeben werden, wie 'A-Z', '0-9' etc. "Übung" Like "[A-ZÄÖÜ]*"
Wenn Sie dem / den gesuchten Zeichen in eckigen Klammern ein Ausrufezeichen voranstellen, wird nach allen Zeichen außer den angegebenen gesucht. "Übung" Like "*[!&]*"
[ Wenn Sie eine geöffnete eckige Klammer in Ihrem Muster verwenden, können Sie diese wie jedes andere Zeichen angeben: "[Muster]" Like "[*" ' Beginnt der Text mit '['? "[Muster]" Like "[M[]*" ' Beginnt der Text mit 'M' oder '['? "[Muster]" Like "[[M]*" ' Beginnt der Text mit '[' oder 'M'? Die zweite '[' wird als Bestandteil des Zeichenbereichs innerhalb der eckigen Klammern betrachtet.
] Die geschlossene eckige Klammer kann gar nicht in einem spezifischen Platzhalter eingesetzt werden, denn sie würde die eckige Klammer vorzeitig schließen. Daher muss sie immer getrennt (als einzelner Buchstabe) gesucht werden. -
- Wenn Sie das Minuszeichen in einem spezifischen Platzhalter einbeziehen möchten, muss es an letzter Stelle angegeben werden, damit kein Paar um das Minus herum gebildet werden kann ('[§-/]' würde bedeuten: die Zeichen zwischen '§' und '/'). "+49 132 4658" Like "*[0-9 /()+-]*"
 ! Wenn Sie ein Ausrufezeichen in einem spezifischen Platzhalter einbeziehen möchten, darf es nicht an erster Stelle angegeben werden (es sei denn, Sie möchten sicher stellen, dass kein '!' enthalten ist, wie im zweiten Beispiel). "Hallo!" Like "*[.,;:!?-]" ' Endet der Text auf ein Satzzeichen? "Ja?" Like "*[!.,;:!?-]*" ' Enthält der Text mindestens ein Zeichen, das kein Satzzechen ist?
Beispiel Ergebnis Beschreibung
"Test" Like "Test" Wahr Beide Texte stimmen genau überein.
"Test" Like "test" Falsch Groß- und Kleinschreibung muss übereinstimmen.
"Test" Like "[Tt]est" Wahr Das erste Zeichen (eingefasst in '[]') ist ein großes 'T' oder ein kleines 't' und wird von der Zeichenkette 'est' gefolgt.
"Beispiel" Like "*?*" Wahr Die Zeichenkette enthält mindestens ein beliebiges Zeichen. Das '?' ist der Platzhalter für genau ein beliebiges Zeichen (Ziffer, Buchstabe, Satzzeichen, Sonderzeichen, ...).
"Test" Like "T???" Wahr Ein großes 'T' wird von genau drei beliebigen einzelnen Zeichen gefolgt.
"Test" Like "T*" "T" Like "T*" Wahr Ein großes 'T' wird von einer beliebigen Anzahl (inklusive keinen) Zeichen gefolgt.
"Beispiel" Like "*spiel" Wahr Die Zeichenkette endet auf 'spiel'.
"Beispiel" Like "*spiel*" Wahr Die Zeichenkette enthält 'spiel'.
"Beispiel" Like "*[Ss]piel*" Wahr Die Zeichenkette enthält 'Spiel' oder 'spiel'.
"Beispiel" Like "[A-G]*" Wahr Der erste Buchstabe stammt aus der Liste von Großbuchstaben zwischen A und G.
"Übung" Like "[A-Z]*" Falsch Der erste Buchstabe ist ein Sonderzeichen und stammt somit nicht aus der Liste von Großbuchstaben zwischen A und Z.
"Rastatt" Like "*[Ss]ta[dt]t" Wahr Die Zeichenkette lautet oder endet auf 'Stadt', 'stadt', 'Statt' oder 'statt'.
"m.muster@muster.de" Like "*??@??*.??*" Wahr Zeichenkette enthält mindestens zwei beliebige Zeichen vor sowie mindestens zwei beliebige Zeichen nach dem '@', woraufhin ein Punkt mit wiederum mindestens zwei beliebigen Zeichen folgt.
"Maier & Söhne" Like "*[&]*" Wahr Zeichenkette enthält mindestens ein '&'.
"Maier & Söhne" Like "*[!&]*" Wahr Zeichenkette enthält mindestens ein Zeichen, das kein '&' ist.
"+49 123 456789" Like "+49 ###*" Wahr Telefonnummer beginnt mit '+49', einem Leerzeichen und mindestens drei Ziffern. Hierbei wird jedoch nicht geprüft, ob die weiteren Zeichen ebenfalls Ziffern sind.
"+49 132 4658" Like "*[0-9 /()+-]*" True Prüft, ob eines dieser Zeichen enthalten ist. In diesem Falle jedoch nicht aussagekräftig, denn hier wäre wichtig zu wissen, ob ein fremdes Zeichen enthalten ist ...
"+49 132 4658" Like "*[!0-9 /()+-]*" False Enthält die Zeichenkette mindestens ein Zeichen, das nicht aus der angegebenen Gruppe stammt?
"+49 a123 456" Like "*[!0-9 /()+-]*" True Enthält die Zeichenkette mindestens ein Zeichen, das nicht aus der angegebenen Gruppe stammt? (Beachten Sie das 'a' vor '123')
"üä" Like "[!&]*" False Beginnt der Text nicht mit einem '&'?


Objektreferenzvergleich (Is)

Mit dem Is-Operator können Sie prüfen, ob zwei Objektreferenzen auf das gleiche Objekt verweisen. Hierbei wird nicht geprüft, ob sich die beiden Objekte entsprechen: Dim fnt01 As Font, fnt02 As Font Set fnt01 = ActiveDocument.Words(1).Font Set fnt02 = ActiveDocument.Words(2).Font Debug.Print fnt01 Is fnt02 ' False Die ersten beiden Wörter im Dokument sind identisch formatiert, trotzdem ergibt der Vergleich mit 'Is' False. Set fnt01 = ActiveDocument.Words(1).Font Set fnt02 = ActiveDocument.Words(1).Font Debug.Print fnt01 Is fnt02 ' False Hier wird zwar auf das selbe Objekt verwiesen, trotzdem ergibt der Vergleich mit 'Is' False. Set fnt01 = ActiveDocument.Words(1).Font Set fnt02 = fnt01 Debug.Print fnt01 Is fnt02 ' True Nun wird beim Vergleich True zurückgegeben.

Vergleich umkehren (Not)

Sie können, wenn nötig, einen Vergleich umkehren, indem Sie ihm das Schlüsselwort 'Not' voranstellen: If Not strEmail Like "*@*.[a-z][a-z]*" Then Exit Function End If Hier wird geprüft, ob der Text der angegebenen Struktur entspricht. Wenn dies nicht der Fall ist, wird die Funktion verlassen. So kann in einer Funktion, welche prüfen soll, ob die eingegebene E-Mail-Adresse dem erwarteten Format entspricht, so aufgebaut werden, dass die Nicht-Erfüllung einer Bedingung zum Abbruch jedes weiteren Tests führt. Werden alle Tests bestanden, gibt die Funktion den Wert 'True' zurück. Eine alternative Formulierung wäre: If strEmail Like "*@*.[a-z][a-z]*" Then Else Exit Function End If Folgende Formulierungen entsprechen sich ebenfalls: If lngTest <> 3 Then '... End If If Not lngTest = 3 Then '... End If If lngTest = 3 Then Else '... End If

Option Compare

Die Option Compare-Anweisung steuert das Verhalten der Vergleichsoperatoren und wird, wenn sie ausdrücklich erscheinen soll, am Anfang des betroffenen Moduls (wie 'Option Explicit') angegeben.

Option Compare Binary (standard)

Ist die Standardeinstellung in VBA und bewirkt das oben beschriebene Verhalten bei Textvergleichen:

  • A < B < Z < a < b < z < Ä < Ü < Ø < ä < ö < ø usw. Der Vergleich erfolgt also immer unter Berücksichtigung der Groß- / Kleinschreibung und sämtliche Umlaute und Sonderzeichen werden hinter der Gruppe von Kleinbuchstaben angesiedelt.

Option Compare Text

  Option Compare Text.png Mit dieser Anweisung verwendet VBA das Gebietsschema Ihres Computers, um den Vergleich von Texten durchzuführen: * (A=a) < (À=à) < (Ä=ä) < (B=b) < (Z=z) < (Ø=ø) Die Groß- und Kleinschreibung wird hierbei nicht beachtet, Umlaute werden (im deutschen Gebietsschema!) den Grundbuchstaben zugeordnet. Bitte beachten: Abhängig vom eingestellten Gebietsschema kann der Vergleich sehr unterschiedlich ausfallen. In Finnland wird z. B. das 'Ü' dem 'Y' gleichgesetzt und somit nicht dem 'U' zugeordnet. Bitte beachten: Die Anweisung 'Option Compare Text' müsste, wenn Sie immer beim Textvergleich mit dieser Einstellung arbeiten möchten, in jedem betroffenen Modul explizit angegeben werden. Besser ist es, eine eigene Klasse für Textvergleiche zu erstellen und in dieser mit der 'Option Compare Text' zu arbeiten. Tipp: Sie können das Verhalten der Gebietsschema-abhängigen Textvergleiche prüfen, indem Sie in Ihren Windows-Systemeinstellungen unter 'Region' den Eintrag 'Format' ändern.