Kurz gesagt —
Range.Findist das Ctrl+F von Excel für Code. Es liefert keine Zeilennummer und keine Position zurück — es liefert einenRange, der auf die passende Zelle zeigt, oderNothing, wenn es keinen Treffer gibt. Das Allererste, was Sie mit dem Ergebnis tun, ist daher die Prüfung aufIs 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 SieLookIn:=xlValuesundLookAt:=xlWholebei 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 —
Findliefert einenRange(oderNothing) zurück, keine Position - Die Prüfung, die den Absturz mit Fehler 91 verhindert — auf
Is Nothingtesten, bevor Sie das Ergebnis anfassen - Die Falle der klebrigen Argumente — warum
LookInundLookAtjedes einzelne Mal gesetzt werden müssen xlWholevsxlPart— der Unterschied zwischen „ist gleich“ und „enthält“- Mit
FindNextschleifen, um jeden Treffer zu erreichen, ohne Endlosschleife - Wann
Findeine Schleife schlägt und wie es sich vonInStrunterscheidet
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
