mreske
Goto Top

Mehrfachsuche in Listbox

Guten Abend zusammen,

ich bräuchte mal wieder Hilfe.
Und zwar möchte ich
eine Suche über alle Spalten in einer Listbox laufen lassen
dabei sollen alle Suchbegriffe abgefragt werden.

Beispiel:
Das Marko soll z.B. in jeder Zeile der Listbox prüfen, ob dort ein oder mehrere dieser Begriffe vorkommen: "Hosen" "Herren" "Peter"
2022-06-02_185030

Hier mal eine kleine Datei, die Listbox wird beim Öffnen der Userform geladen.
VBA_Test.xlsm

Vielleicht hat jemand eine Idee, wie man das umsetzen kann.

Vielen Dank
Gruß

Content-ID: 2969587568

Url: https://administrator.de/forum/mehrfachsuche-in-listbox-2969587568.html

Ausgedruckt am: 22.12.2024 um 07:12 Uhr

colinardo
colinardo 02.06.2022 aktualisiert um 21:15:01 Uhr
Goto Top
Hattest du hier schon mal gefragt face-smile. Code dafür findest du hier:

Listbox nach String der Reihe nach Suchen und markieren (SpinButton)

Mir den mehreren Begriffen in der selben Box machst du dann einfach ein Split() an den Leerzeichen und itterierst mit einem for-Loop über die einzelne Begriffe innerhalb des Loops in dem der Inhalt der Zelle geprüft wird.

Grüße Uwe
mreske
mreske 02.06.2022 um 21:41:14 Uhr
Goto Top
Hallo Uwe,
ja stimmt, so etwas Ähnliches hatte ich wohl schon mal,
Dieses Mal sollen aber in der Listbox nur die Treffer angezeigt werden.
Da komme ich nicht weiter.

Gruß
colinardo
colinardo 02.06.2022 aktualisiert um 23:18:40 Uhr
Goto Top
Zitat von @mreske:

Hallo Uwe,
ja stimmt, so etwas Ähnliches hatte ich wohl schon mal,
Dieses Mal sollen aber in der Listbox nur die Treffer angezeigt werden.
Da komme ich nicht weiter.

Gruß

Auch das hatte ich mit dir hier schon durch 🙂.

Spalte E nach beliebig vielen Suchbegriffen (mit Leerzeichen getrennt) durchsuchen und in Listbox ausgeben
mreske
mreske 03.06.2022 um 00:45:21 Uhr
Goto Top
Hallo Uwe,
auch das stimmt und ich hatte mich auch in meiner Beschreibung des Problems falsch ausgedrückt

Was ich eigentlich wollte war:
1. Es soll immer nur eine Zeile markiert werden, wenn ALLE Suchbegriffe darin vorkommen.
In meinem Beispiel soll die Zeile nur markiert werden, wenn in ihr "Hosen" + "Herren" + "Peter" vorkommen.

2. Danach möchte ich die NICHT markierten Zeilen über die RemoveItem löschen

Die Markierungen der Trefferzeilen habe ich schon hinbekommen (allerdings unabhängig voneinander).
a. Was muss ich ändern, damit die Zeile nur markiert wird, wenn ALLEN Begriffe in ihr vorkommen.
b. bei .RemoveItem (i) kommt die Fehlermeldung "Nicht näher definierter Fehler". Was mache ich da falsch

Hier der Link auf die Datei
VBA_Test.xlsm

Private Sub Suchen_Click()
Dim lngRow As Long, lngColumn As Long, i As Long
Dim strSearchText As String
'Dim strTeilSuchbegriff As String  
Dim strgSuchbegriff As String
Dim ArrayListbox1 As Variant
Dim objLbx As Object

Set objLbx = Me.ListBox1

ArrayListbox1 = Me.ListBox1 'Komplette Listbox1 im Array "zwischenspeichern"  

strgSuchbegriff = Me.TextBox1

'Alle Markierungen aufheben  
With objLbx
For lngRow = 0 To .ListCount - 1
.Selected(lngRow) = False
Next
End With

'Wenn Leerzeichen am Ende des Suchstrings steht, dieses löschen  
If Right$(strgSuchbegriff, 1) = " " Then 'Wenn das letzte Zeichen ein Leerzeichen ist, gibt es keine Suchtreffer  
strgSuchbegriff = Left(strgSuchbegriff, Len(strgSuchbegriff) - 1) 'Also letztes Leerzeichen entfernen  
Else 'Sonst nichts entfernen  
End If

'Suchstring festlegen  
If Trim$(strgSuchbegriff) <> "" Then  
strSearchText = "*" & Trim$(strgSuchbegriff) & "*"  
End If

With objLbx
.MultiSelect = fmMultiSelectMulti
arrSearchTerms = Split(strgSuchbegriff, " ", -1, vbTextCompare) 'die Suchbegriffe nach Leerzeichen trennen  
    
'Suche jedes Wort  
For i = 0 To UBound(arrSearchTerms) 'Schleife für jedes Wort  
strgSuchbegriff = "*" & Trim$(arrSearchTerms(i)) & "*" 'Teil-Suchbegriff  
    'Suche durchführen  
    For lngRow = 0 To .ListCount - 1
    For lngColumn = 0 To .ColumnCount - 1
    If .List(lngRow, lngColumn) Like strgSuchbegriff Then
    .Selected(lngRow) = True
    Exit For
    End If
    Next lngColumn
    Next lngRow
Next i
End With

'Jetzt alles, was nicht markiert ist aus der Listbox löschen  
With objLbx
For i = .ListCount - 1 To 0 Step -1
If .Selected(i) = False Then
'objLbx.RemoveItem (i)  
End If
Next
End With
End Sub
colinardo
Lösung colinardo 03.06.2022 aktualisiert um 09:39:54 Uhr
Goto Top
Zitat von @mreske:
Was ich eigentlich wollte war:
1. Es soll immer nur eine Zeile markiert werden, wenn ALLE Suchbegriffe darin vorkommen.
In meinem Beispiel soll die Zeile nur markiert werden, wenn in ihr "Hosen" + "Herren" + "Peter" vorkommen.
OK.
2. Danach möchte ich die NICHT markierten Zeilen über die RemoveItem löschen
Das geht bei einer Listbox nicht wenn du die Eigenschaft RowSource verwendest. Damit bindest du eine Listbox an einen Datenbereich, und deswegen kannst du hier die Methode RemoveItem nicht nutzen, die funktioniert damit nicht! Das geht nur wenn man die List Eigenschaft auf einen Range setzt.

Der Workaround hierfür besteht darin entweder die Listbox ungebunden zu erstellen, die Zeilen im Sheets zu suchen und dann der Listbox über AddItem hinzuzufügen, oder das Sheet zu durchsuchen und die Suchergebnisse auf ein verstecktes Sheet zu schreiben und die Row-Source auf die Suchergebnisse des unsichtbaren Sheets zu setzen.

Die erste Methode hat den Nachteil das sie max 10 Spalten unterstützt, du hast aber 11 Spalten deswegen ist Variante 2 bei dir vorzuziehen. Diese Methode habe ich dir in folgendem Sheet zusammengestellt:

search_form_multiterm_2969587568.zip

screenshot

Grüße Uwe
mreske
mreske 03.06.2022 um 12:23:18 Uhr
Goto Top
Hallo Uwe,

vielen Dank - damit kann ich schon sehr viel anfangen.

Nur noch eine Verständnisfrage:
Angenommen, die Listbox ist ungebunden.

Wie könnte ich über den "found" - Zähler die Treffer markieren?
Also wenn ich z.B. die Zeilen markieren will, in der "Klaus" + "C1" vorkommen?

Und wie kann ich danach die nicht markierten Zeilen löschen? Geht das in einer ungebundenen Multiselect Listbox?

2022-06-03_122154

Wie müsste ich diesen Code dafür ändern?

With objLbx
.MultiSelect = fmMultiSelectMulti
arrSearchTerms = Split(strgSuchbegriff, " ", -1, vbTextCompare) 'die Suchbegriffe nach Leerzeichen trennen  

For lngColumn = 0 To .ColumnCount - 1
For lngRow = 0 To .ListCount - 1
found = 0
    For i = 0 To UBound(arrSearchTerms) 'Schleife für jedes Wort  
    strgSuchbegriff = "*" & Trim$(arrSearchTerms(i)) & "*" 'Teil-Suchbegriff  
    'Wenn Treffer, dann soll zum nächsten Suchbegriff gewechselt werden  
    If .List(lngRow, lngColumn) Like strgSuchbegriff Then
    'verlasse diesen Suchbegriff und nehme den nächsten  
    Exit For
    End If
    found = found + 1
    Next
    'wenn der Zähler mit der an Anzahl der Sucbegriffe übereinstimmt  
     If found = UBound(arrSearchTerms) + 1 Then
     .Selected(lngRow) = True
End If
Next
Next
End With

'Jetzt alles, was nicht markiert ist aus der Listbox löschen  
With objLbx
For i = .ListCount - 1 To 0 Step -1
If .Selected(i) = False Then
'objLbx.RemoveItem (i)  
End If
Next
End With
colinardo
Lösung colinardo 03.06.2022 aktualisiert um 12:40:15 Uhr
Goto Top
Zitat von @mreske:
Wie könnte ich über den "found" - Zähler die Treffer markieren?
In meiner Vorlage hast du ja die Variable cell, und damit bekommst du auch die Position der Zeile im Sheet mit cell.Row. davon brauchst du nur 2 abziehen (Header und 0 basierter Index), und mit dem Index kannst du markieren wie du lustig bist

Und wie kann ich danach die nicht markierten Zeilen löschen?
Ebenso über den o.g Row-Index
Geht das in einer ungebundenen Multiselect Listbox?
Ja, aber wozu aufwändig löschen wenn man sowieso nur die Suchfunde in die Listbox einträgt? Dann entfällt das überflüssige Löschen. Mach es also gleich vernünftig. Nimmt die Tabelle nämlich an Einträgen zu ist sie am Ende länger damit beschäftigt Zeilen zu löschen = ineffizient, solltest du mal drüber nachdenken ...
mreske
mreske 03.06.2022 um 17:13:13 Uhr
Goto Top
Hi Uwe,
danke - ich habe es mit der "Suchergebisse" Tabelle so eingebaut und es ist perfekt so.
Riesen Hilfe, tausend Dank und ein schönes VBA-freies Wochenende!

Gruß