🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA Find in Excel — Zellen richtig durchsuchen (es liefert einen Range zurück, keine Position)

|

VBA Find in Excel — Zellen richtig durchsuchen (es liefert einen Range zurück, keine Position)

Kurz gesagtRange.Find ist das Ctrl+F von Excel für Code. Es liefert keine Zeilennummer und keine Position zurück — es liefert einen Range, der auf die passende Zelle zeigt, oder Nothing, wenn es keinen Treffer gibt. Das Allererste, was Sie mit dem Ergebnis tun, ist daher die Prüfung auf Is Nothing; lassen Sie sie weg, stürzt der erste Lauf ohne Treffer mit „Objektvariable nicht festgelegt“ (Fehler 91) ab. Zwei Argumente sind nicht verhandelbar, weil Find sie sich vom letzten Mal merkt: Setzen Sie LookIn:=xlValues und LookAt:=xlWhole bei jedem Aufruf, sonst erbt Ihr Makro, was ein Nutzer zuletzt in den Find-Dialog eingetippt hat.

' "Widget" in Spalte A finden und die Zeile melden - sicher.
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Data")
Dim found As Range
Set found = ws.Columns("A").Find( _
        What:="Widget", _
        LookIn:=xlValues, _
        LookAt:=xlWhole)          ' xlWhole = Zelle IST GLEICH "Widget", nicht nur enthaelt sie es

If found Is Nothing Then
    MsgBox "Not found"
Else
    MsgBox "Found in row " & found.Row     ' found ist ein Range - .Row, .Address, .Value nutzen
End If

Ein Blatt zu durchsuchen ist das Häufigste, was ein Makro tut, und Find ist das richtige Werkzeug dafür — es ist Excels eigene optimierte Suchmaschine und schlägt eine handgeschriebene Schleife über jede Zelle bei echten Daten mit weitem Abstand. Doch Find hat mehr verborgenen Zustand als fast jede andere Methode im Objektmodell, und dieser Zustand ist der Grund, warum derselbe Code auf verschiedenen Rechnern verschiedene Antworten liefert. Diese Anleitung dreht sich um zwei Tatsachen — Find liefert ein Objekt zurück, und Find ist klebrig — und alles Übrige folgt daraus.

Was Sie lernen

  • Das mentale Modell — Find liefert einen Range (oder Nothing) zurück, keine Position
  • Die Prüfung, die den Absturz mit Fehler 91 verhindert — auf Is Nothing testen, bevor Sie das Ergebnis anfassen
  • Die Falle der klebrigen Argumente — warum LookIn und LookAt jedes einzelne Mal gesetzt werden müssen
  • xlWhole vs xlPart — der Unterschied zwischen „ist gleich“ und „enthält“
  • Mit FindNext schleifen, um jeden Treffer zu erreichen, ohne Endlosschleife
  • Wann Find eine Schleife schlägt und wie es sich von InStr unterscheidet

Das mentale Modell: Find liefert eine Zelle, keine Zahl

Wenn Sie von InStr kommen, wirkt Find vertraut und verhält sich völlig anders. InStr sucht innerhalb eines Strings und gibt eine Zahl zurück — die Zeichenposition des Treffers oder 0. Range.Find sucht über Zellen hinweg und gibt einen Range zurück — einen lebendigen Zeiger auf die Zelle, auf der es gelandet ist, oder den besonderen Wert Nothing, wenn nichts passte.

Dieser eine Unterschied treibt alles an. Weil das Ergebnis ein Objekt ist, weisen Sie es mit Set zu und lesen daran ab, was Sie brauchen: found.Row, found.Column, found.Address, found.Value. Und weil „kein Treffer“ durch Nothing dargestellt wird und nicht durch 0 oder "", können Sie es nicht mit = prüfen. If found = Nothing kompiliert nicht so, wie Sie es erwarten — Nothing wird mit dem Schlüsselwort Is geprüft: If found Is Nothing.

Behalten Sie dieses Bild im Kopf — Find gibt Ihnen die Zelle, oder es gibt Ihnen Nothing — und der häufigste Absturz weiter unten ist offensichtlich, bevor er passiert.

Die wichtigste Regel: auf Is Nothing prüfen, bevor Sie das Ergebnis anfassen

Hier ist der Bug, und fast jeder schreibt ihn einmal:

' FALSCH - nimmt an, dass Find immer erfolgreich ist.
Dim found As Range
Set found = ws.Columns("A").Find(What:="Widget", LookIn:=xlValues, LookAt:=xlWhole)
MsgBox found.Row        ' Fehler 91 in dem Moment, in dem "Widget" nicht da ist

Der Code funktioniert im Test einwandfrei — weil Ihre Testdaten „Widget“ enthalten. Geben Sie ihn frei, füttern Sie ihn mit einem Blatt, auf dem der Wert fehlt, und Find gibt Nothing zurück. Die nächste Zeile fragt Nothing nach seinem .Row, und VBA wirft Laufzeitfehler 91, „Objektvariable oder With-Blockvariable nicht festgelegt“. Es ist der häufigste Find-Fehler überhaupt, und er ist vollständig vermeidbar:

' RICHTIG - zuerst auf Is Nothing verzweigen.
Set found = ws.Columns("A").Find(What:="Widget", LookIn:=xlValues, LookAt:=xlWhole)
If found Is Nothing Then
    ' den "not found"-Fall behandeln - Meldung, Standardwert, Ausstieg
Else
    ' sicher, found.Row, found.Value usw. zu nutzen
End If

Auf jedes Find folgt ein Is Nothing-Test. Behandeln Sie die beiden als eine Einheit, die Sie zusammen tippen, so wie On Error und sein Handler zusammen reisen. Es gibt kein Find, von dem Sie sicher sein können, dass es trifft — der ganze Sinn des Suchens ist, dass Sie es nicht wissen.

Die Falle, die Stunden kostet: Find merkt sich seine letzten Argumente

Das ist das Verhalten, das Find wie verhext wirken lässt. Die meisten seiner Argumente sind optional, und wenn Sie eines weglassen, nutzt Find keinen festen Standardwert — es verwendet erneut den Wert vom letzten Mal, als Find lief, irgendwo in dieser Excel-Sitzung. Dazu gehört die letzte Suche, die ein Nutzer von Hand in den Ctrl+F-Dialog eingetippt hat.

Dieser harmlos aussehende Aufruf:

Set found = ws.Cells.Find(What:="2026")     ' LookIn? LookAt? MatchCase? ...geerbt

kann bei einem Lauf auf Formeln passen und beim nächsten auf Werte, einmal auf die ganze Zelle und beim nächsten Mal auf einen Teil — je nach Zustand, den Sie nicht sehen und nicht gesetzt haben. Das Symptom ist zermürbend: „Gestern ging es“, „Auf meinem Rechner läuft es“, „Manchmal findet es ihn“. Die Lösung ist Disziplin — übergeben Sie die Argumente, die das Ergebnis bestimmen, ausdrücklich, jedes Mal:

Set found = ws.Cells.Find( _
        What:="2026", _
        LookIn:=xlValues, _      ' xlValues (was Sie sehen) vs xlFormulas (die zugrunde liegende Formel)
        LookAt:=xlWhole, _       ' xlWhole (ist gleich) vs xlPart (enthaelt)
        MatchCase:=False, _
        SearchOrder:=xlByRows)

Meine Regel: Wenn ein Argument ändern könnte, auf welcher Zelle Sie landen — LookIn, LookAt, MatchCase —, benennen Sie es bei jedem Aufruf und verlassen sich nie auf den Standardwert. Die drei Tastenanschläge sind billiger als der Fehlerbericht.

xlWhole vs xlPart: ist gleich gegenüber enthält

LookAt ist das Argument, das man am häufigsten falsch macht, weil beide Werte „funktionieren“ und nur einer für die Aufgabe richtig ist. LookAt:=xlWhole passt auf eine Zelle, deren gesamter Inhalt Ihrem Suchbegriff entspricht. LookAt:=xlPart passt auf jede Zelle, die den Begriff irgendwo enthält.

' Zelle enthaelt den Text: Order 100 shipped
ws.Cells.Find(What:="100", LookAt:=xlWhole)   ' KEIN Treffer - Zelle ist nicht exakt "100"
ws.Cells.Find(What:="100", LookAt:=xlPart)    ' Treffer - "100" kommt im Text vor

Sie schlagen eine ID, einen Code, einen exakten Schlüssel nach? Dann wollen Sie xlWhole, sonst treffen Sie „100“ in „1002“, „31007“ und „Order 100“. Sie durchsuchen längeren Text nach einem Stichwort? Dann wollen Sie xlPart. Den falschen zu wählen ist der klassische „Warum hat es diese Zelle getroffen?“-Bug, und er wirft nie einen Fehler — er gibt einfach den falschen Range zurück.

Jeden Treffer finden: die FindNext-Schleife

Find gibt eine Zelle zurück — den ersten Treffer nach der Zelle, ab der es starten soll. Um auf jedes Vorkommen zu wirken, schleifen Sie mit FindNext, das vom vorherigen Treffer aus weitermacht. Der Haken: FindNext springt am Ende des Bereichs wieder an den Anfang zurück, sodass eine naive Schleife ewig läuft. Die Lösung ist, sich die Adresse des ersten Treffers zu merken und aufzuhören, wenn Sie wieder bei ihr ankommen:

Dim found As Range, firstAddress As String
Set found = ws.Columns("A").Find(What:="Widget", LookIn:=xlValues, LookAt:=xlWhole)

If Not found Is Nothing Then
    firstAddress = found.Address          ' <-- merken, wo wir gestartet sind
    Do
        found.Offset(0, 1).Value = "seen" ' mit jedem Treffer etwas tun
        Set found = ws.Columns("A").FindNext(found)
    Loop While Not found Is Nothing And found.Address <> firstAddress
End If

firstAddress nicht festzuhalten ist der häufigste FindNext-Bug — die Schleife dreht endlos ihre Runden durch den Bereich und verarbeitet dieselben Treffer erneut. Noch eine Regel, die im Stillen zählt: löschen oder fügen Sie keine Zeilen innerhalb einer FindNext-Schleife ein. Das Raster mitten in der Suche zu ändern zerstört Finds Sinn für die Position; müssen Sie Treffer löschen, sammeln Sie zuerst ihre Adressen und löschen danach (siehe VBA Zeilen löschen für die Rückwärtsschleife und die Union-Muster).

Suchen und Ersetzen im Code

Range.Replace ist das Geschwister von Find und teilt dieselben klebrigen Argumente, erledigt aber die ganze Arbeit in einem Aufruf — keine Schleife, kein Is Nothing:

ws.Columns("A").Replace _
        What:="N/A", Replacement:="0", _
        LookAt:=xlWhole, MatchCase:=False

Weil Replace auf den gesamten Bereich auf einmal wirkt, ist es weit schneller, als Find zu schleifen und jede Zelle zu schreiben — und es gibt True/False zurück, ob sich etwas geändert hat, statt eines Bereichs. Greifen Sie zu Replace, wenn Sie Treffer ändern wollen, und zu Find/FindNext, wenn Sie sie untersuchen oder zu ihnen springen wollen.

Find vs InStr: Rastersuche gegenüber Stringsuche

Sie klingen austauschbar und sind es nicht. Nehmen Sie Find, wenn das, was Sie durchsuchen, das Arbeitsblatt ist — Sie wollen die Zelle und Sie wollen Excels schnelle native Suche. Nehmen Sie InStr, wenn das, was Sie durchsuchen, ein einzelner String bereits in einer Variablen ist — Sie wollen eine Zeichenposition innerhalb dieses Textes. Ein häufiges Muster nutzt beide: Find findet die Zeile, dann pickt InStr einen Teilstring aus einem Feld dieser Zeile heraus. Betreiben Sie Textchirurgie innerhalb von Strings, ist das InStr und Verwandte, nicht Find.

Und die Einschätzung, die man klar aussprechen sollte: schreiben Sie keine For Each cell In range-Schleife, um einen Wert zu finden. Find ist Excels eigene indizierte Suche; in einer Spalte mit 100.000 Zeilen liefert es fast augenblicklich, während die Schleife sich durch jede Zelle quält. Die Suche von Hand zu bauen ist langsamer, länger und fehleranfälliger.

Wie ExcelMaster hilft

Find bündelt ungewöhnlich viel verborgenes Verhalten in einer Methode: die Rückgabe Objekt-statt-Zahl, das Nothing-Ergebnis, die klebrigen Argumente, die Wahl zwischen xlWhole/xlPart, die umlaufende Schleife. Jedes hat eine Fehlerart, die falsche Ergebnisse erzeugt, ohne einen Fehler zu werfen — genau die Art Bug, die den Test übersteht und in der Produktion auftaucht.

ExcelMaster lässt Sie stattdessen die Suche beschreiben. Sagen Sie „finde jede Zeile, deren Status Storniert ist, und markiere sie“ oder „schlage diese Rechnungsnummer nach und springe zu ihr“, und es schreibt das Find mit ausdrücklich fixierten Argumenten, der Is Nothing-Absicherung an Ort und Stelle und einer ordentlichen FindNext-Schleife, wenn Sie alle Treffer brauchen — und sichert das Blatt, bevor es irgendetwas ändert. Sie behalten die Arbeitsmappe und den Code; Sie sparen sich den Teil, in dem ein geerbtes LookAt klammheimlich die falsche Zelle trifft.

Häufig gestellte Fragen

Warum gibt VBA Find den Fehler 91 aus?

Weil Range.Find Nothing zurückgibt, wenn es keinen Treffer gibt, und Fehler 91 („Objektvariable oder With-Blockvariable nicht festgelegt“) in dem Moment auslöst, in dem Sie eine Eigenschaft wie .Row von Nothing lesen. Testen Sie immer If found Is Nothing Then, bevor Sie das Ergebnis nutzen. Der Absturz erscheint meist nur, wenn Ihren Daten der Suchbegriff fehlt — deshalb rutscht er durch den Test.

Was gibt VBA Find zurück, wenn es keinen Treffer gibt?

Es gibt den besonderen Wert Nothing zurück, nicht 0 und keine leere Zeichenkette. Sie müssen ihn mit dem Schlüsselwort Is prüfen — If found Is Nothing —, weil Nothing nicht mit = verglichen werden kann. Bei einem erfolgreichen Treffer gibt es einen Range zurück, der auf die gefundene Zelle zeigt.

Was ist der Unterschied zwischen LookAt xlWhole und xlPart in VBA Find?

xlWhole passt nur auf Zellen, deren gesamter Inhalt dem Suchbegriff entspricht; xlPart passt auf jede Zelle, die den Begriff irgendwo enthält. Nehmen Sie xlWhole für exakte Schlüssel wie IDs und Codes und xlPart, wenn Sie längeren Text nach einem Stichwort durchsuchen. Den falschen zu wählen gibt die falsche Zelle zurück, ganz ohne Fehler.

Wie finde ich in VBA alle passenden Zellen, nicht nur die erste?

Holen Sie mit Find den ersten Treffer, merken Sie sich seine .Address und schleifen Sie dann mit FindNext(found), bis die Adresse wieder zur ersten zurückkehrt: Loop While Not found Is Nothing And found.Address <> firstAddress. Die erste Adresse festzuhalten ist entscheidend — ohne sie läuft die Schleife ewig um den Bereich.

Soll ich zum Durchsuchen eines Blatts VBA Find oder eine Schleife nutzen?

Nehmen Sie Find. Es ist Excels eingebaute optimierte Suche und weit schneller als eine For Each-Schleife über jede Zelle, besonders bei großen Bereichen. Eine manuelle Schleife ist zudem länger und fehleranfälliger. Schleifen Sie nur, wenn Sie eine eigene Trefferlogik brauchen, die sich mit Finds Argumenten nicht ausdrücken lässt.

Getestet in

Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 08.08.2026.

Verwandte Anleitungen: VBA AutoFilter · VBA Sort · VBA Zeilen löschen · VBA InStr · VBA Range