2008-11-11 8 views
5

lassen Sie uns sagen, ich habe ein Tabellenblatt excel wie unten:Wie kann eine Reihe von Zellen in VBA zurückgegeben werden, ohne eine Schleife zu verwenden?

 
col1 col2 
------------ 
dog1 dog 
dog2 dog 
dog3 dog 
dog4 dog 
cat1 cat 
cat2 cat 
cat3 cat 

Ich möchte eine Reihe von Zellen zurückzukehren (dog1, dog2, Dog3, dog4) oder (cat1, cat2, cat3), basierend auf entweder „dog "oder" Katze "

Ich weiß, dass ich eine Schleife machen kann, um eins nach dem anderen zu überprüfen, aber gibt es irgendeine andere Methode in VBA, also kann ich das Ergebnis in einer Aufnahme" filtern "?

vielleicht kann die Range.Find (XXX) helfen, aber ich sehe nur Beispiele für nur eine Zelle, nicht eine Reihe von Zellen.

Bitte Rat

Grüße

+0

Das von Ihnen gepostete Beispiel sieht sehr seltsam aus, bitte ändern Sie es, damit es lesbar ist. – schnaader

+0

Es ist kein Problem mit der Leertaste. Er benutzt einen komischen Zeichensatz oder so etwas. –

+0

Und es zeigt sich nur auf etwas von seinem Text? – FlySwat

Antwort

0

Dank DJ.

Diese FindAll Lösung verwendet immer noch eine VBA-Schleife, um Dinge zu tun.

Ich versuche, einen Weg zu finden, ohne Benutzer-Level-Loop zu verwenden, um einen Bereich in Excel VBA zu filtern.

Hier fand ich eine Lösung. Es nutzt die Vorteile von Excel-Engine, um die Arbeit zu erledigen.

(1) verwenden worksheetfunction.CountIf ("Katze"), um die Anzahl der "Katze" Zellen zu erhalten

(2) verwenden .Find ("Katze") die erste Reihe der „Katze zu bekommen "

mit der Anzahl der Zeilen und der ersten Zeile kann ich den" cat "Bereich bereits bekommen.

Der gute Teil dieser Lösung ist: keine Schleife auf Benutzerebene, dies könnte die Leistung verbessern, wenn die Reichweite groß ist.

+0

Ich habe auch festgestellt, dass die Leistung für das Durchlaufen einer großen Range sehr langsam sein kann. Wenn Sie jedoch VBA verwenden und die Range-Werte zuerst in ein Array und dann in eine Schleife konvertieren, erhalten Sie einen enormen Leistungsschub. Selbst wenn Sie danach zurück konvertieren müssen. –

0

Excel unterstützt das ODBC-Protokoll. Ich weiß, dass Sie eine Verbindung zu einer Excel-Tabelle aus einer Access-Datenbank herstellen und abfragen können. Ich habe es nicht getan, aber vielleicht gibt es eine Möglichkeit, die Tabelle mit ODBC aus Excel abzufragen.

0

Es sei denn, Sie verwenden eine veeeeery alte Maschine, oder Sie haben ein XL2007 Arbeitsblatt mit einer Bazillion Zeilen, eine Schleife wird schnell genug sein. Ehrlich!

Vertrauen Sie mir nicht? Schau dir das an. Ich füllte eine Million Reihe Bereich mit zufälligen Buchstaben dies mit:

=CHAR(RANDBETWEEN(65,90)) 

Dann habe ich diese Funktion geschrieben und nannte es von einem 26-Zellbereich mit gedrückter Ctrl-Shift-Enter:

=TRANSPOSE(UniqueChars(A1:A1000000)) 

Hier ist die nicht-sehr-optimierte VBA-Funktion ich in ein paar Minuten gehackt aus:

Option Explicit 

Public Function UniqueChars(rng As Range) 

Dim dict As New Dictionary 
Dim vals 
Dim row As Long 
Dim started As Single 

    started = Timer 

    vals = rng.Value2 

    For row = LBound(vals, 1) To UBound(vals, 1) 
     If dict.Exists(vals(row, 1)) Then 
     Else 
      dict.Add vals(row, 1), vals(row, 1) 
     End If 
    Next 

    UniqueChars = dict.Items 

    Debug.Print Timer - started 

End Function 

auf meinen Jahre alten Core 2 Duo T7300 (2 GHz) Laptop nahm es 0,58 Sekunden.

1

Forgot eine andere XL2007-Funktion: erweiterte Filterung.Wenn Sie es in VBA wollen, habe ich dies von einem aufgezeichneten Makro:

Range("A1:A1000000").AdvancedFilter Action:=xlFilterCopy, CopyToRange:= Range("F1"), Unique:=True 

I timed es bei etwa 0,35 sec ...

zwar nicht viel, wenn Sie nicht 2007 haben Sie

2

Hier sind einige Hinweise zur Verwendung eines Recordsets zur Rückgabe des Bereichs.

Sub GetRange() 
Dim cn As Object 
Dim rs As Object 
Dim strcn, strFile, strPos1, strPos2 

    Set cn = CreateObject("ADODB.Connection") 
    Set rs = CreateObject("ADODB.Recordset") 

    strFile = ActiveWorkbook.FullName 

    strcn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _ 
    & strFile & ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1';" 

    cn.Open strcn 

    rs.Open "SELECT * FROM [Sheet1$]", cn, 3 'adOpenStatic' 

    rs.Find "Col2='cat'" 
    strPos1 = rs.AbsolutePosition + 1 
    rs.MoveLast 
    If Trim(rs!Col2 & "") <> "cat" Then 
     rs.Find "Col2='cat'", , -1 'adSearchBackward' 
     strPos2 = rs.AbsolutePosition + 1 
    Else 
     strPos2 = rs.AbsolutePosition + 1 
    End If 
    Range("A" & strPos1, "B" & strPos2).Select 
End Sub 
Verwandte Themen