Null, leere Zeichenkette, Nothing und Co.

Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.

In Datenbanken wie Microsoft Access gibt es einen entscheidenden Unterschied zwischen einem leeren Feld und einem Feld mit einer leeren Zeichenkette. Und es gibt noch mehr interessante Dinge rund um dieses Thema, zum Beispiel die Funktion IsNull, die Funktion Nz und weitere VBA-Elemente, die sich mit ähnlichen Dingen befassen – wie etwa Nothing, Empty oder Missing. Dieser Beitrag erläutert diese VBA-Elemente und zeigt die wichtigsten Unterschiede und Einsatzzwecke auf.

Wer hat sich beim Einstieg in die Access-Welt nicht mindestens einmal in die Nesseln gesetzt, als er versucht hat, ein leeres Textfeld mit dem Wert “” (für eine leere Zeichenkette) zu vergleichen

Schauen wir uns ein einfaches Szenario an: Das Formular aus Bild 1 ist an eine Tabelle mit einem Primärschlüsselfeld und den beiden Textfeldern Vorname und Nachname gebunden. Wenn der Benutzer auf die Schaltfläche Speichern klickt, sollen die Felder validiert werden. Verläuft die Validierung erfolgreich, wird der Datensatz gespeichert.

Ein einfaches Formular mit einem Textfeld

Bild 1: Ein einfaches Formular mit einem Textfeld

Dazu legen wir zunächst die Prozedur für die Schaltfläche cmdSpeichern an, welche schlicht eventuell vorhandene Änderungen am Datensatz speichert:

Private Sub cmdSpeichern_Click()
     On Error Resume Next
     RunCommand acCmdSaveRecord
     Select Case Err.Number
         Case 0, 2501
         Case Else
             MsgBox "Fehler " & Err.Number & " " _
                 & Err.Description
     End Select
     On Error GoTo 0
End Sub

Die Fehlerbehandlung haben wir hinzufügt, weil der Versuch, den Datensatz zu speichern, beim Abbrechen mit der nachfolgend vorgestellten Prozedur einen Fehler auslösen würde. Die folgende Ereignisprozedur wird durch das Ereignis Vor Aktualisierung ausgelöst. Es prüft, ob das Feld Nachname eine leere Zeichenkette enthält. Ist das nicht der Fall, soll eine entsprechende Meldung erscheinen, das Textfeld den Fokus erhalten und die Aktualisierung durch Setzen des Parameters Cancel auf den Wert True abgebrochen werden:

Private Sub Form_BeforeUpdate(Cancel As Integer)
     If Me!Nachname = "" Then
         MsgBox "Der Nachname ist eine leere Zeichenkette.", µ 
                                                   vbOKOnly
         Me!Nachname.SetFocus
         Cancel = True
     End If
End Sub

Wenn wir dies ausprobieren, geschieht – nichts! Obwohl doch das Textfeld leer ist! Warum Weil das Textfeld tatsächlich leer ist und der Inhalt genau nicht einer leeren Zeichenkette entspricht.

Die Access IsNull()-Funktion

Diesen Sachverhalt prüfen wir nicht mit =””, und auch nicht mit = Null. Und auch das Is-Schlüsselwort kommt hier nicht zum Einsatz, Is Null hilft also auch nicht. Hier gibt es vielmehr zwei Möglichkeiten. Die erste ist, zusätzlich zum Vergleich mit der leeren Zeichenkette auch noch die Funktion IsNull einzusetzen:

...
If IsNull(Me!Nachname) Then
     MsgBox "Der Nachname ist Null.", vbOKOnly
     Me!Nachname.SetFocus
     Cancel = True
End If
...

Wenn wir den Datensatz nun speichern wollen, erscheint die gewünschte Meldung (s. Bild 2). Die Bedingung Me!Nachname = “” wird übrigens mit den Standardeinstellungen nicht eintreten.

Es wurde ein Textfeld mit dem Inhalt Null erkannt.

Bild 2: Es wurde ein Textfeld mit dem Inhalt Null erkannt.

Dies erreichen Sie erst, wenn zwei bestimmte Eigenschaften des Feldes im Tabellenentwurf spezielle Werte aufweisen. Die Eigenschaft Eingabe erforderlich muss dabei den Wert Ja aufweisen, die Eigenschaft Leere Zeichenfolge ebenfalls den Wert Ja (s. Bild 3).

Einstellung für leere Zeichenketten

Bild 3: Einstellung für leere Zeichenketten

Erst dann können Sie tatsächlich eine leere Zeichenfolge in das Feld Nachname eingeben – siehe Bild 4. Um auf Nummer Sicher zu gehen, was die zugrunde liegende Tabelle angeht, können Sie auch einfach eine Kombination der beiden Bedingungen nutzen:

Eingabe einer leeren Zeichenkette

Bild 4: Eingabe einer leeren Zeichenkette

If Me!Nachname = "" Or IsNull(Me!Nachname) Then
     MsgBox "Der Nachname ist Null oder eine leere  Zeichenkette.", vbOKOnly
     Me!Nachname.SetFocus
     Cancel = True
End If

Die Nz()-Funktion

Und es geht noch eine Nummer eleganter: Die Funktion Nz() erwartet den zu prüfenden Ausdruck, also beispielsweise ein Textfeld wie in unserem Beispiel. Wenn der Inhalt des Textfeldes Null ist, liefert die Funktion den Wert zurück, der standardmäßig für diesen Datentyp verwendet wird. Bei Textfeldern ist das eine leere Zeichenkette.

Sie können allerdings auch explizit angeben, welcher Wert zurückgegeben werden soll, wenn der geprüfte Ausdruck den Wert Null liefert. In diesem Fall geben Sie als zweiten Parameter etwa die leere Zeichenkette an und prüfen dann nur noch, ob die Funktion eine leere Zeichenkette zurückgeliefert hat:

If Nz(Me!Nachname, "") = "" Then
     MsgBox "Der Nachname ist Null oder eine leere  Zeichenkette.", vbOKOnly
     Me!Nachname.SetFocus
     Cancel = True
End If

Bei einem Feld, das entweder den Wert Null oder den Wert 0 aufweisen darf, wird es interessanter. Dazu fügen wir der Tabelle ein Fremdschlüsselfeld namens AnredeID hinzu, mit der der Benutzer einen der Datensätze der Tabelle tblAnreden auswählen können soll. Für das Kombinationsfeld, mit dem wir dies erledigen wollen, hinterlegen wir die folgende Datensatzherkunft:

SELECT 0, "<Auswählen>" 
FROM tblAnreden 
UNION 
SELECT [tblAnreden].[AnredeID], [tblAnreden].[Anrede] 
FROM tblAnreden;

Dies liefert, wenn wir als Standardwert den Wert 0 einstellen, die Auswahl aus Bild 5 für einen neuen Datensatz. Wenn wir die beiden Textfelder ausfüllen und das Kombinationsfeld so beibehalten, gibt es Fehler 3201 (Der Datensatz kann nicht hinzugefügt oder geändert werden, da ein Datensatz in der Tabelle ””tblAnreden”” mit diesem Datensatz in Beziehung stehen muss.). Diesen wollen wir natürlich verhindern, und zwar mit einer passenden Validierung. Damit der Fehler nicht ausgelöst wird, nehmen wir diesen zunächst in die Ereignisprozedur der Schaltfläche cmdSpeichern hinzu:

Ein Kombinationsfeld, das nicht den Wert 0 oder Null liefern soll

Bild 5: Ein Kombinationsfeld, das nicht den Wert 0 oder Null liefern soll

Private Sub cmdSpeichern_Click()
     ...
     Select Case Err.Number
         Case 2501, 3201
     ...
End Sub

Danach legen wir die folgende If…Then-Bedingung in der Methode Form_BeforeUpdate an:

    If IsNull(Me.AnredeID) Then
         MsgBox "Wählen Sie eine Anrede aus.", vbOKOnly
         Me!AnredeID.SetFocus
         Cancel = True
     End If

Wenn wir nun allerdings einen neuen Datensatz anlegen, die beiden Textfelder ausfüllen, den Standardwert des Kombinationsfeldes beibehalten und auf die Schaltfläche cmdSpeichern klicken, geschieht nichts! Der Datensatz wird nicht gespeichert, aber es erscheint auch keine Fehlermeldung. Der Grund ist einfach: Sobald Sie den Datensatz in den Bearbeitungsmodus versetzen, was geschieht, wenn Sie eines der Felder ändern, wird der ursprüngliche Wert, also Null, durch den als Standardwert festgelegten Wert ersetzt, also 0. Den Wert 0 fangen wir nicht ab, also wird der Datensatz einfach kommentarlos nicht gespeichert. Also prüfen wir einfach auf den Wert 0 statt auf Null (und klappen das Kombinationsfeld auch noch auf, wenn es den Wert 0 enthält):

If Nz(Me!AnredeID, 0) = 0 Then
     MsgBox "Wählen Sie eine Anrede aus.", vbOKOnly
     Me!AnredeID.SetFocus
     Me!AnredeID.Dropdown
     Cancel = True
End If

Nun kann es allerdings sein, dass der Benutzer einfach das Kombinationsfeld leert. Dies würde bedeuten, dass der Wert Null im entsprechenden Feld der Datenbank gespeichert wird, denn wir prüfen in der Validierung nicht auf dieses Feld und in der mit referenzieller Integrität festgelegten Beziehung ist der Wert Null auch erlaubt. Wir möchten aber weder den Wert 0 noch Null im Feld AnredeID haben. Also prüfen wir auf beide:

If Nz(Me!AnredeID, 0) = 0 Then

Wenn AnredeID den Wert Null hat, wird es durch die Funktion Nz in 0 konvertiert, anderenfalls hat es gegebenenfalls durch den Standardwert bereits den Wert 0. In beiden Fällen erscheint eine entsprechende Meldung.

Da es sich bei dem Feld AnredeID um ein Zahlenfeld handelt, können Sie sogar den zweiten Parameter der Nz-Funktion weglassen – diese liefert dann ohnehin den Wert 0 als Standardwert für Zahlenwerte, die Null sind:

If Nz(Me!AnredeID) = 0 Then
...

Null in Variant-Variablen

Der Wert Null kann nicht nur in Datenbankfeldern vorkommen, sondern natürlich auch in VBA-Variablen. Allerdings gibt es nur einen einzigen Variablendatentyp, der den Wert Null aufnehmen kann, und das ist der Datentyp Variant. Das folgende Beispiel zeigt den Unterschied etwa zwischen dem Datentyp Variant und dem Datentyp String:

Public Sub VariantNull()
     Dim strTest As String
     Dim var As Variant
     strTest = ""
     strTest = 123
     strTest = Null
     var = ""
     var = 123
     var = Null
End Sub

So nimmt die String-Variable natürlich die Zeichenkette auf und auch die Zahl, wobei diese in eine Zeichenkette umgewandelt wird. Aber die Zuweisung des Wertes Null liefert einen Fehler (s. Bild 6). Bei der Variant-Variablen var hingegen erfolgen alle Zuweisungen ohne Fehler. Die Zahl wird als Zahl gespeichert und der Wert Null als Null. Dies macht den Datentyp Variant natürlich prädestiniert für Fälle, in denen der übergebene Wert gleich Null werden kann.

Fehler beim Zuweisen des Wertes Null zu einer String-Variablen

Bild 6: Fehler beim Zuweisen des Wertes Null zu einer String-Variablen

Leere Variant-Variablen

Wo wir schon beim Datentyp Variant sind, können wir uns auch gleich noch seine Besonderheiten ansehen. Wenn wir eine String-Variable deklarieren, wird diese automatisch mit dem Wert “” initialisiert. Die folgende Prozedur gibt die Inhalte der Variablen aus:

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

Testzugang

eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar