2016-12-15 3 views
0

Ich habe ein Suchfeld entworfen, das meine Tabelle filtert, wenn Text in besagtem Suchfeld eingegeben wird. Das Problem ist, dass es so langsam ist, es ist fast gar nicht wert, es in meinem Arbeitsbuch zu haben.VBA-Code für Suchfeld, das Tabelle filtert

Kann irgendjemand über irgendeine Möglichkeit nachdenken, diesen Code zu überarbeiten/verbessern?

Hier ist mein Code zur Zeit:

Private Sub TextBox1_Change() 
Dim searchArea As Range, searchRow As Range, searchCell As Range 
Dim searchString As String 
Dim lastRow As Integer 

Application.ScreenUpdating = False 
searchString = "*" & LCase(TextBox1.Value) & "*" 
Rows.Hidden = False 

lastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row 
Set searchArea = Me.Range("f3:f791", "f3" & lastRow) 
searchArea.EntireRow.Hidden = True 

For Each searchRow In searchArea.Rows 
    For Each searchCell In searchRow.Cells 
    If LCase(searchCell) Like searchString Then 
     searchRow.Hidden = False 
     Exit For 
    End If 
    Next searchCell 
Next searchRow 

Application.Goto Range("Z1"), True 
ActiveWindow.ScrollColumn = 1 
Application.ScreenUpdating = True 

End Sub 

meinen Code dieses Editiert:

Private Sub TextBox1_Change() 
    ActiveSheet.ListObjects("states").Range.AutoFilter Field:=1, _ 
     Criteria1:="*" & [G1] & "*", Operator:=xlFilterValues 
End Sub 

Dies ist jedoch nicht funktioniert. Es gibt Text und Zahlen in Feld 1, und dies auch nur filtert Text, nicht die Zahlen ...

+2

Betrachten wir die 'AutoFilter' Methode, anstatt Zeile-für-Zeile/Zelle-für-Zelle Iteration? –

+0

Wie also würde dieser Code aussehen? Entschuldigung, immer noch sehr neu bei VBA ... – Darren

+0

Sie iterieren auch über einen einzelnen Spaltenbereich und führen deshalb Redundanz ein, weil Sie 'für jede Suchzelle in searchrow.cells' machen. –

Antwort

1

Dies ist definitiv redundant überflüssig ist, weil Ihre Iteration über eine einzige Spalte ist:

For Each searchRow In searchArea.Rows 
    For Each searchCell In searchRow.Cells '### searchRow ONLY HAS ONE CELL! This second/inner loop is totally unnecessary 
    If LCase(searchCell) Like searchString Then 
     searchRow.Hidden = False 
     Exit For 
    End If 
    Next searchCell 
Next searchRow 

Rewrite als :

For Each searchCell in searchArea.Cells '## Assumes searchArea is single column 
    searchCell.EntireRow.Hidden = Not (LCase(searchCell) Like searchString) 
Next 

das allein sollte die Leistung verbessern, aber ich denke, AutoFilter eine bessere Methode ist, und Sie sollen den grundlegenden Code für das aus dem Makrorecorder ableiten können.

Dies würde in etwa so aussehen:

searchArea.AutoFilter Field:=1, Criteria1:="=" & searchString, _ 
    Operator:=xlAnd, Criteria2:="<>" 

Dies sollte filtern, um nur nicht-leere Zeilen angezeigt werden, die enthalten Ihre searchString

@ Yowe3k die Punkte über den Bereich assigment sollte auch beachtet werden, und Sie können Verwenden Sie das Ereignis AfterUpdate des Textfelds anstelle des Ereignisses Change.

AKTUALISIEREN Dies funktioniert möglicherweise, um Ihre gemischten Fälle von numerischen/Textwerten zu behandeln. Es könnte einen besseren Weg geben, aber ich sehe keine offensichtliche Lösung. Der AutoFilter soll mit entweder Text oder Zahlen arbeiten, aber nicht beides. Dies versucht also, numerische Werte in Zeichenfolgendarstellungen zu konvertieren. Sie müssen möglicherweise Änderungen an anderer Stelle machen, wenn die numerischen Werte in Formel referenziert werden usw.

Dim arr, v 
Dim tbl As ListObject 
Set tbl = ActiveSheet.ListObjects(1) 
' ## Disable filter if it's on already 
If tbl.Range.AutoFilter Then tbl.Range.AutoFilter 
arr = tbl.DataBodyRange.Columns(1).Value 
' ## Convert your range of mixed numeric/string to string 
For v = LBound(arr, 1) To UBound(arr, 1) 
    If IsNumeric(arr(v, 1)) Then 
     arr(v, 1) = "'" & CStr(arr(v, 1)) 
    End If 
Next 
' ## Put the string data back out to the worksheet 
tbl.DataBodyRange.Columns(1).Value = arr 
tbl.Range.AutoFilter Field:=1, _ 
     Criteria1:="*" & CStr([G1]) & "*", Operator:=xlFilterValues 
+0

Danke David. Ich habe meinen Code aktualisiert, habe aber immer noch Probleme damit. – Darren

+0

Grammatik Polizei: "Sie sind Iteration ist vorbei" -> "Ihre Iteration ist vorbei", oder "Sie iterieren über" – YowE3K

+0

@ YowE3K hahahah Sie wissen, was ich hin und her zwischen "Ihre Iteration ist "und" du "issierst über" und anscheinend verwirrt ich mich, werde reparieren :) –

Verwandte Themen