Live-Forum - Die aktuellen Beiträge
Datum
Titel
28.03.2024 21:12:36
28.03.2024 18:31:49
Anzeige
Archiv - Navigation
980to984
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
980to984
980to984
Aktuelles Verzeichnis
Verzeichnis Index
Verzeichnis Index
Übersicht Verzeichnisse
Suche mit 2 Kriterien
24.05.2008 00:22:00
Gernot
Guten Abend!
Ich habe hier eine Tabelle mit Terminen, diese enthält 13 Spalten, darunter die Spalte Aktenzeichen und Status.
Jetzt möchte ich nach einem Aktenzeichen suchen das aber nur den Status "offen" enthält oder ein anderes fest definiertes Merkmal aus dieser Tabelle hat (wird in einer Listbox festgelegt) und soll in einer Liste im Userformular ausgegeben werden.
Wie die Suche mit einem Kriterium geht kenn ich, hier meine Code:

Private Sub Suche_HautpmenüCmd6_Click()
Dim rngC As Range, strAddress As String, varSB As Variant, lngX As Long
Dim lngZ As Long
If txtsuche = "" Then Exit Sub
varSB = txtsuche
lsthm.Clear
Worksheets("Forderungen").Select
With [A2:Z65536]
Set rngC = .Find(varSB, LookIn:=xlValues, Lookat:=xlPart)
If Not rngC Is Nothing Then
strAddress = rngC.Address
Do
On Error GoTo Ende
lngX = lngX + 1
lngZ = rngC.Row
With lsthm
.AddItem Cells(lngZ, 1)
.List(.ListCount - 1, 1) = Cells(lngZ, 2)
.List(.ListCount - 1, 2) = Cells(lngZ, 3)
.List(.ListCount - 1, 3) = Cells(lngZ, 4)
.List(.ListCount - 1, 4) = Cells(lngZ, 5)
.List(.ListCount - 1, 5) = Cells(lngZ, 6)
.List(.ListCount - 1, 6) = Cells(lngZ, 7)
.List(.ListCount - 1, 7) = Cells(lngZ, 8)
.List(.ListCount - 1, 8) = Cells(lngZ, 9)
.List(.ListCount - 1, 9) = Cells(lngZ, 10)
.List(.ListCount - 1, 10) = Cells(lngZ, 11)
.List(.ListCount - 1, 11) = Cells(lngZ, 12)
.List(.ListCount - 1, 12) = Cells(lngZ, 13)
.List(.ListCount - 1, 13) = Cells(lngZ, 14)
.List(.ListCount - 1, 14) = Cells(lngZ, 15)
.List(.ListCount - 1, 15) = Cells(lngZ, 16)
.List(.ListCount - 1, 16) = Cells(lngZ, 17)
.List(.ListCount - 1, 17) = Cells(lngZ, 18)
.List(.ListCount - 1, 18) = Cells(lngZ, 19)
.List(.ListCount - 1, 19) = Cells(lngZ, 20)
.List(.ListCount - 1, 20) = Cells(lngZ, 21)
.List(.ListCount - 1, 21) = Cells(lngZ, 22)
.List(.ListCount - 1, 22) = Cells(lngZ, 23)
.List(.ListCount - 1, 23) = Cells(lngZ, 24)
.List(.ListCount - 1, 24) = Cells(lngZ, 25)
.List(.ListCount - 1, 25) = Cells(lngZ, 26)
.List(.ListCount - 1, 26) = Cells(lngZ, 27)
.List(.ListCount - 1, 27) = Cells(lngZ, 28)
.List(.ListCount - 1, 28) = Cells(lngZ, 29)
.List(.ListCount - 1, 29) = Cells(lngZ, 30)
.List(.ListCount - 1, 30) = Cells(lngZ, 31)
.List(.ListCount - 1, 31) = Cells(lngZ, 32)
.List(.ListCount - 1, 32) = Cells(lngZ, 33)
.List(.ListCount - 1, 33) = Cells(lngZ, 34)
'.List(.ListCount - 1, 34) = Cells(lngZ, 35)
End With
Set rngC = .FindNext(rngC)
Loop While Not rngC Is Nothing And rngC.Address  strAddress
End If
End With
lblliste.Caption = lsthm.ListCount
If lngX = 0 Then
'MsgBox varSB & " wurde nicht gefunden! ", 64, "stelle fest..."
lsthm.AddItem Cells(1, 1)
lsthm.ColumnWidths = "120"
lsthm.ForeColor = vbRed
lsthm.List(lsthm.ListCount - 1, 0) = ("Kein Eintrag gefunden")
End If
Ende:
txtsuche = ""
txtsuche.SetFocus
End Sub


Wie stelle ich jetzt den og. Code um um mit 2 Kriterien oder mehr zu suchen?
Habe hier im Forum nichts gefunden.
Vielen Dank für Eure Hilfe im Voraus!
Mfg
Gernot

7
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Suche mit 2 Kriterien
24.05.2008 02:27:27
Daniel
Hi
da würde ich die "brute Force"-Methode empfehlen:
- Tabellendaten in ein Array kopieren
- Array in einer Schliefe durchlaufen und prüfen, ob die einzelnen Bedingungen erfüllt sind
als Code so:

Dim arr
Dim x As Long
arr = ActiveSheet.UsedRange.Value
For x = 1 To UBound(arr, 1)
If arr(x, 1) = "Wert1" Then
If arr(x, 2) = "Wert2" Then
If arr(x, 3) = "Wert 3" Then
'--- alle drei bedingungen erfüllt
'--- hier Code einfügen
End If
End If
End If
Next


da nicht mit der Tabelle selbst sondern mit einer Array-Variable gearbeitet wird, dürfte das genauo schnell sein, wie die FIND-Methode.
Gruß, Daniel

Anzeige
AW: Suche mit 2 Kriterien
25.05.2008 03:06:10
Gernot
Guten Abend!
Danke für die schnelle Hilfe!
Habe den Code jetzt so angepasst (jetzt erst mal nur einen Wert):
Dim arr
Dim x As Long
arr = Worksheets("Termine").Range("A2:M2000").Value
For x = 1 To UBound(arr, 1)
If arr(x, 1) = "offen" Then
'If arr(x, 2) = "Wert2" Then
' If arr(x, 3) = "Wert 3" Then
'--- alle drei bedingungen erfüllt
'--- hier Code einfügen
lstadr.List = arr.Rows(arr.Rows.Count).Value
' End If
' End If
End If
Next
Jetzt ist aber die Listbox leer. Habe ich das was falsches zum Befüllen geschrieben?
Ich bitte um Hinweise!
Danke!

Anzeige
AW: Suche mit 2 Kriterien
25.05.2008 14:44:00
Daniel
hI
ein Array ist eine normale Index-Variable und kein Range-Objekt, dementsprechend muss man es verwenden.
dein Code würde dann so aussehen:
Anlegen einer neuen Zeile in der Listbox und Einfügen des ersten Elements

ListBox1.AddItem arr(x, 2)


Einfügen von weiteren Spalten in die Listbox (in die letzte Zeile der Listbox)


Listbox1.List(Listbox1.Listcount-1, 1) = arr(x,3)


beachte, die Listboxindizierung beginnt bei 0 und nicht bei 1 (sowohl für Zeilen wie auch für Spalten)
Gruß, Daniel

Anzeige
AW: Suche mit 2 Kriterien
25.05.2008 15:12:00
fcs
Hallo Gernot,
du muss in deine Do ... Loop schleife die die Aktenzeichen einliest "nur" für die Fundstellen eine Prüfung einbauen, ob in der Zeile das Merkmal = dem Merkmal-Wert ist.
Ich hab deinen Code mal beispielhaft angepasst.
Die Bruze-Force Methode wird nämlich mit der Tabellengröße ziemlich langsam.
Gruß
Franz

Private Sub Suche_HautpmenüCmd6_Click()
Dim rngC As Range, strAddress As String, varSB As Variant, lngX As Long
Dim lngZ As Long, lngSpalte As Long                         '####
If txtsuche = "" Then Exit Sub
varSB = txtsuche
lsthm.Clear
Worksheets("Forderungen").Select
With [A2:Z65536] 'hier nur den Bereich/Spalte(n) mit den Aktenzeichen angeben)###
Set rngC = .Find(varSB, LookIn:=xlValues, Lookat:=xlPart)
If Not rngC Is Nothing Then
strAddress = rngC.Address
'Spalte für Merkmal festlegen
Select Case ListboxMerkmal.Value
Case "Merkmal1": lngSpalte = 4
Case "Merkmal2": lngSpalte = 5
Case "Merkmal3": lngSpalte = 8
Case "Status": lngSpalte = 9
'usw.
Case Else
MsgBox "Für gewähltes Merkmal ist keine Spalte festgelegt"
GoTo Ende
End Select
Do
On Error GoTo Ende
lngX = lngX + 1
lngZ = rngC.Row
If Cells(lngZ, lngSpalte).Value = TextBoxMerkmalWert.Value Then 'Prüfung  _
Merkmal ###
With lsthm
.AddItem Cells(lngZ, 1)
.List(.ListCount - 1, 1) = Cells(lngZ, 2)
.List(.ListCount - 1, 2) = Cells(lngZ, 3)
.List(.ListCount - 1, 3) = Cells(lngZ, 4)
.List(.ListCount - 1, 4) = Cells(lngZ, 5)
.List(.ListCount - 1, 5) = Cells(lngZ, 6)
.List(.ListCount - 1, 6) = Cells(lngZ, 7)
.List(.ListCount - 1, 7) = Cells(lngZ, 8)
.List(.ListCount - 1, 8) = Cells(lngZ, 9)
.List(.ListCount - 1, 9) = Cells(lngZ, 10)
.List(.ListCount - 1, 10) = Cells(lngZ, 11)
.List(.ListCount - 1, 11) = Cells(lngZ, 12)
.List(.ListCount - 1, 12) = Cells(lngZ, 13)
.List(.ListCount - 1, 13) = Cells(lngZ, 14)
.List(.ListCount - 1, 14) = Cells(lngZ, 15)
.List(.ListCount - 1, 15) = Cells(lngZ, 16)
.List(.ListCount - 1, 16) = Cells(lngZ, 17)
.List(.ListCount - 1, 17) = Cells(lngZ, 18)
.List(.ListCount - 1, 18) = Cells(lngZ, 19)
.List(.ListCount - 1, 19) = Cells(lngZ, 20)
.List(.ListCount - 1, 20) = Cells(lngZ, 21)
.List(.ListCount - 1, 21) = Cells(lngZ, 22)
.List(.ListCount - 1, 22) = Cells(lngZ, 23)
.List(.ListCount - 1, 23) = Cells(lngZ, 24)
.List(.ListCount - 1, 24) = Cells(lngZ, 25)
.List(.ListCount - 1, 25) = Cells(lngZ, 26)
.List(.ListCount - 1, 26) = Cells(lngZ, 27)
.List(.ListCount - 1, 27) = Cells(lngZ, 28)
.List(.ListCount - 1, 28) = Cells(lngZ, 29)
.List(.ListCount - 1, 29) = Cells(lngZ, 30)
.List(.ListCount - 1, 30) = Cells(lngZ, 31)
.List(.ListCount - 1, 31) = Cells(lngZ, 32)
.List(.ListCount - 1, 32) = Cells(lngZ, 33)
.List(.ListCount - 1, 33) = Cells(lngZ, 34)
'.List(.ListCount - 1, 34) = Cells(lngZ, 35)
End With
End If                                                '####
Set rngC = .FindNext(rngC)
Loop While Not rngC Is Nothing And rngC.Address  strAddress
End If
End With
lblliste.Caption = lsthm.ListCount
If lngX = 0 Then
'MsgBox varSB & " wurde nicht gefunden! ", 64, "stelle fest..."
lsthm.AddItem Cells(1, 1)
lsthm.ColumnWidths = "120"
lsthm.ForeColor = vbRed
lsthm.List(lsthm.ListCount - 1, 0) = ("Kein Eintrag gefunden")
End If
Ende:
txtsuche = ""
txtsuche.SetFocus
End Sub


Anzeige
AW: je nach dem
25.05.2008 17:24:00
Daniel
Hi
"Die Bruze-Force Methode wird nämlich mit der Tabellengröße ziemlich langsam."
das ist nur dann richtig, wenn die BruteForce-Methode mit Range-Objekten arbeitet.
Wenn man sich die Daten vorher in ein Array-Feld kopiert, sind beide Varianten ähnlich schnell.
Welche Variante schneller ist, hängt dann davon ab, viele Elemente gefunden werden.
je mehr, um so deutlicher ist die Suchschleife im Vorteil
was unter welchen Konstellationen schneller ist, kann man hier mal Testen
https://www.herber.de/bbs/user/52610.xls
ruhig auch mal die Extremvariante (65536 von 65536) eingeben und staunen
außerdem denke ich, daß sich die geforderten Mehrfachbedingungen in der Brute-Force schleife Anschaulicher programmieren lassen als sie noch irgendwie in die FIND-Methode einzubinden.
Gruß, Daniel

Anzeige
AW: je nach dem
26.05.2008 01:31:29
fcs
Hallo Daniel,
ich hab auf meinem schon etwas betagten System (Excel97, Win 98, Pentium III, Baujahr 2000) deine Datei getestet.
Bei Szenario 1000 von 65536 liegt die Find-Varinte mit ca. 0,7 zu 1,4 Sekunden vorn. Wird zusätzlich ScreenUpdating auf False gesetzt steigt der Vorsprung ca. 0,35 zu 1,4 Sekunden.
Bei Szenario 50 von 65536 sind die Zeiten 0,21 zu 1,4 bzw. 0,16 zu 1,4.
Das Festlegen des 2. Suchkriteriums (in welcher Spalte/Spalten welcher Begriff/Begriffe gesucht werden soll) muss für beide Varianten ähnlich sein.
Für ein einzelnes Kriterium in einer Spalte zu prüfen

If Cells(lngZ, lngSpalte).Value = TextBoxMerkmalWert.Value Then 'Prüfung Merkmal ###


oder bei mehreren Merkmalen diese in einem kleinen Array zu sammeln und in einer For-Next-Schleife auf ist gleich zu prüfen ist nicht so aufwendig zu programmieren und auch nicht unübersichtlichter als die Brute-Force Schleifen.
Der Geschwindigkeitsvorsprung der Find-Methode dürfte aber nochmals signifikant ansteigen.
Gruß
Franz

Anzeige
AW: je nach dem
26.05.2008 21:46:00
Daniel
Hi
bei mir liegt im 65000er Suchfeld der Gleichstand bei 1200 zu Suchenden, bei mehr ist die Schleife besser.
in Vorteil der Schleife könnte noch sein, wenn man viele Suchen im gleichen Array-Feld durchführen möchte, da das Array-Feld nur 1x eingelesen werden muss.
dazu hab ich ich nochmal ne Einstellbare Wiederholungsschleife eingebaut, man kann jetzt z.B. das Szenario 1 aus 1000 auch 1000x wiederholen lassen.
da zeigt sich dann, daß der Zeitfresser nicht die Suchschleife, sondern das Einlesen des Arrays ist.
und so bei wiederholten Suchen die Schleife im Vorteil ist.
https://www.herber.de/bbs/user/52636.xls
Gruß, Daniel
Anzeige

302 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige
Anzeige

Links zu Excel-Dialogen

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige