2009-05-14 18 views
1

Ich habe ein Blatt voller roher Daten, etwa 20.000 Zeilen und 50 Spalten. (Anzahl der Zeilen, die erhöht werden sollen, wahrscheinlich doppelt, wenn nicht dreifach)Excel/VBA, um zu prüfen, ob eine Zeile existiert

Ich brauche eine Formel, um diese Daten zu betrachten und festzustellen, ob eine Zeile für Daten in zwei angegebenen Spalten existiert. Meine derzeitige Formel lautet wie folgt.

Function CheckExists(Table As Range, SearchCol1 As Integer, SearchVal1 As Variant, SearchCol2 As Integer, SearchVal2 As Variant) 

    Dim i As Long 
    Dim exists As Boolean 

    exists = False 

    For i = 1 To Table.Rows.Count 
     If Table.Cells(i, SearchCol1) = SearchVal1 Then 
      If Table.Cells(i, SearchCol2) = SearchVal2 Then 
       exists = True 
       Exit For 
      End If 
     End If 
    Next i 

    CheckExists = exists 

End Function 

Ich führe diese Formel aus einem anderen Blatt, mit etwa 5000 Zeilen.

Mein Problem ist, dies tötet meinen PC, es dauert ewig, um die Zellen zu berechnen. Ich hoffe, dass jemand einige Vorschläge machen kann, wie man das schneller oder sogar besser machen kann, eine eingebaute Formel, die tun kann, wonach ich suche.

+1

Wenn Sie erwarten, dass sich die Anzahl der Zeilen verdreifacht, sind Sie in Schwierigkeiten. Excel lässt nur 65536 Zeilen im Worksheet-Objekt zu. – HardCode

Antwort

2

Ich empfehle, eine Spalte hinzuzufügen, um die Werte in den zwei Spalten von Interesse zu verketten, und dann die MATCH-Arbeitsblattfunktion zu verwenden, um die neue Spalte zu suchen.

2

Wenn Sie Cells.Find verwenden, sparen Sie viel über Zellen, die nie den gewünschten Wert enthalten.

z.B.

Cells.Find(What:="-1", After:=ActiveCell, LookIn:=xlValues, LookAt:= _ 
     xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _ 
     , SearchFormat:=False).Activate 

wird die Zelle aktiviert, dass sie den Wert in finden. Sie können dann überprüfen, ob die andere Zelle Sie vergleichen den richtigen Wert hat (wenn die Zelle angeordnet wurde).

Sie müssen auch überprüfen, ob die Zeile/Spalte, in der Sie sich befinden, die richtige für den Wert ist, den Sie suchen. Insbesondere wenn Sie nach der Zahl 20 suchen, wird die Nummer gefunden 20 in der falschen Reihe.

Haben Sie ein Spiel, ich denke, Sie werden feststellen, es ist ziemlich viel schneller als normale Iteration.

Zusätzliche, möglicherweise ungerechtfertigte Ratschläge: Mit so vielen Daten wäre eine Datenbank nicht sinnvoll?

Update:
ich ein schnelles Spiel gehabt habe - diese Funktion ersetzt die bestehenden Sie oben unter Verwendung sind, lassen Sie mich wissen, ob es schneller ist.

Function FindCheckExists(Table As Range, SearchCol1 As Integer, _ 
         SearchVal1 As Variant, SearchCol2 As Integer, _ 
         SearchVal2 As Variant) 

    Dim i As Long 
    Dim exists As Boolean 
    Dim result As Range 

    exists = False 
    Do While (Not exists) 

     Set result = Cells.Find(What:=SearchVal1, After:=Cells(1, SearchCol1), _ 
      LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, _ 
      SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False) 

     If (result Is Nothing) Then Exit Function 

     If result.Offset(0, (SearchCol2 - SearchCol1)).Value = SearchVal2 Then _ 
      exists = True 

    Loop 

    FindCheckExists = exists 

End Function 

die oben mit neu formatiert wurde _ ist ordentlicheres auf der Seite Stackoverflow passen, wird es wahrscheinlich in Excel, ohne sie sehen einfach besser aus.

+0

Danke, ich werde Find suchen. Wir haben eine Datenbank, die aus einer Datenbank abgerufen wird, und ich kann alle erforderlichen Dinge in SQL erledigen. Allerdings müssen wir dazu in der Lage sein, ohne auf SQL zurückgreifen zu müssen. Es ist mehr eine Ermächtigung der Kundenübung. –

+0

Okay, das macht Sinn :) Werfen Sie einen Blick auf meine aktualisierte Lösung oben und lassen Sie mich wissen, ob es besser ist. – Andy

3

Sie könnten eine Spalte am Ende der Rohdaten mit einer einfachen Formel if hinzufügen, z.

if(AND(A1=4, B1=6), 1, 0) 

Wo A1/B1 sind die Spalten zu überprüfen und 4 und 6 würden durch die tatsächlichen Werte ersetzt werden. Die Prüfung, ob eine Zeile dann überprüft wird, existiert nur die Summe dieser Spalte:

if(sum(C:C) > 0, TRUE, FALSE) 

wobei C die Spalte mit der Formel ist. Bei großen Excel-Dokumenten finde ich im Allgemeinen einen zusammengesetzten Ansatz, der am effizientesten ist. Wenn Sie ein Beispiel der Daten veröffentlichen, kann ich möglicherweise weiter verfeinern.

0

Ich habe es am schnellsten gefunden, Autofilter zu verwenden. Filtern Sie es anhand Ihrer Kriterien und löschen Sie dann die verbleibenden sichtbaren Zeilen.

z.B.Ws.Rows(1).Insert 'Filter does not check first row Ws.AutoFilterMode = False Ws.Cells.AutoFilter searchCol1, "=*" & searchVal1 & "*", , , False Ws.Cells.AutoFilter searchCol2, "=*" & searchVal2 & "*", , , False Ws.AutoFilter.Range.SpecialCells(xlCellTypeVisible).EntireRow.Delete ActiveSheet.AutoFilterMode = False

Hoffe, dass hilft.

1

Es ist nicht notwendig, VBA zu verwenden, um dies zu erreichen - Sie können es mit nur einer regulären Front-End-Formel tun. Die Formel unten (die erste hat gerade Reihen 1-5000, aber der zweite wird die gesamte Spalte tun) wird ermittelt, ob die Kombination in Frage besteht:

=SUMPRODUCT(--(A1:A5000="SearchValue1"),--(B1:B5000="SearchValue2")) 

=SUMPRODUCT(--(A:A="SearchValue1"),--(B:B="SearchValue2")) 

, es zu benutzen, würden Sie nur fix „SearchValue1“ und „SearchValue2“ werden die Werte Sie suchen, und ändern Sie die Spaltenbuchstaben, wenn Sie nicht A und B mit

1

ich würde sagen, ähnlich wie rwmnau, außer ich in der Regel verwenden:

=SUMPRODUCT((A1:A5000="SearchValue1")*(B1:B5000="SearchValue2")) 

BEARBEITEN Wenn Sie Excel 2007 verwenden, können Sie u se COUNTIFS-Funktion (beachten Sie das S am Ende).

Verwandte Themen