PDA

Vollständige Version anzeigen : suchen im Array


HolN
06.04.2012, 08:47
Hallo,

ich habe ein Array mit Werte von ca 30000 Zeilen und 3 Spalten gefüllt.

Jetzt möchte ich aus dem Array in der ersten Spalte einen Wert suchen und mir den Index als Ergebnis liefern. Habe gedacht das es geht ohne eine Schleife und bin mit folgenden Code leider nicht weiter gekommen


Sub test()

Dim arrNrBezGef
suchen = 300
lz = Range("A1").End(xlDown).Row
arrNrBezGef = Range("a1:c" & lz).Value

erg = Application.Match(suchen, arrNrBezGef, 0)
End Sub

Hat jemand ein Tipp für mich

danke + Gruß
nolle

CitizenX
06.04.2012, 09:21
Moin,

Application.Match funzt nur in eindimensionalen Arrays.
Versuch es mal so:

Option Explicit

Sub test()
Dim myArr(), myRange As Range, myMatch, lnglast As Long
Dim strSuche As String

Const inspalte = 2 'in welcher Spalte steht der Suchbegriff
strSuche = "300" 'Suchbegriff

lnglast = Cells(1, 1).End(xlDown).Row
Set myRange = Range("A1:C" & lnglast) 'Gesammtbereich der Suche

myArr = Intersect(myRange, Columns(myRange(, 1).Column + inspalte - 1)).Value 'Sucharray
myMatch = Application.Match(strSuche, myArr, 0)

If IsNumeric(myMatch) Then
MsgBox "gefunden in Zeile " & myMatch
Else
MsgBox "nix gefunden"
End If

End Sub

ransi
06.04.2012, 09:26
HAllo Nolle

<nobr><span style="font-family:Courier New,Arial; font-size:9pt ;" ><span style="color:#000080"; >Option</span> <span style="color:#000080"; >Explicit</span><br /><br /><br /><b><span style="color:#000080"; >Sub</span> test()</b><br /><br /><span style="color:#000080"; >Dim</span> arrNrBezGef <span style="color:#000080"; >As</span> <span style="color:#000080"; >Variant</span><br /><span style="color:#000080"; >Dim</span> suchen<br /><span style="color:#000080"; >Dim</span> lz <span style="color:#000080"; >As</span> <span style="color:#000080"; >Long</span><br /><span style="color:#000080"; >Dim</span> erg <span style="color:#000080"; >As</span> <span style="color:#000080"; >Variant</span><br /><span style="color:#000080"; >Dim</span> arrTmp <span style="color:#000080"; >As</span> <span style="color:#000080"; >Variant</span><br /><br />suchen = 300<br />lz = Range(<span style="color:#800000"; >"A1"</span>).End(xlDown).Row<br />arrNrBezGef = Range(<span style="color:#800000"; >"A1:C"</span> & lz).Value<br />arrTmp = WorksheetFunction.Index(arrNrBezGef, 0, 1) <span style="color:#008000"; >'Spalte1</span><br />erg = Application.Match(suchen, arrTmp, 0)<br /><br /><span style="color:#000080"; >If</span> <span style="color:#000080"; >Not</span> IsError(erg) <span style="color:#000080"; >Then</span><br />&nbsp;&nbsp;&nbsp;&nbsp;MsgBox erg<br />&nbsp;&nbsp;&nbsp;&nbsp;Else:<br />&nbsp;&nbsp;&nbsp;&nbsp;MsgBox <span style="color:#800000"; >"nix gefunden"</span><br /><span style="color:#000080"; >End</span> <span style="color:#000080"; >If</span><br /><br /><b><span style="color:#000080"; >End</span> <span style="color:#000080"; >Sub</span></b><br /></span></nobr>

Ich habs nicht getestet, aber das Durchlaufen eines unsortierten Arrays ist (glaube ich) schneller als match().

ransi

HolN
06.04.2012, 09:43
Hallo Steffen, hallo Ransi

danke Euch für die schnelle Antwort.

Steffen du schreibst
Application.Match funzt nur in eindimensionalen Arrays

wenn ich mir aber das Lokalfenster ansehe ist myArr aber ein 2 dim Array.
Als Ergebnis bekomme ich Fehler 2042

Ransi mit Deinem Code komme ich zu richtigen Ergebnis. Das Array ist sortiert.
Leider weiss ich nicht warum ein arrTmp angelegt wird, kannst mir das vielleicht nochmal erklären

Gruß
nolle

Beverly
06.04.2012, 10:04
Hi Nolle,

ich bin zwar nicht ransi, aber da mich das Thema ebenfalls brennend interessiert und ich nach einer praktikablen Lösung gesucht habe, habe ich natürlich mitgelesen. arrTemp ist ein einspaltiges Array, in welches die betreffende Suchspalte aus dem mehrspaltigen Array übergeben wird. In diesem einspaltigen Array lässt sich dann mittels Match die Position des gesuchten Wertes problemlos ermitteln.

Du könntest theoretisch bereits zu Beginn die Werte aus der Spalte A in ein zweites Array einlesen, wenn du dir sicher bist, dass du nur in dieser Spalte des Bereichs suchen willst. Allerdings ist die Übergabe aus dem mehrspaltigen Array wesentlich flexibler, da du dich auch später im Code z.B. in Abhängigkeit von irgendeiner Bedingung für eine bestimmte Spalte entscheiden kannst (falls das erforderlich sein sollte). Möglicherweise ist die Übernahme der Spalte aus dem Array auch schneller als aus dem Tabellenblatt (habe ich nicht getestet).

<hr width="20%" align="left"><img src="http://excel-inn.de/images/grusz.gif" height=35" align="left" alt="Grußformel"><a href="http://excel-inn.de/" onclick="window.open(this.href);return false"><img border="0" src="http://excel-inn.de/images/logo1.gif" height=35" align="middle" alt="Beverly's Excel - Inn"></a>

ransi
06.04.2012, 10:17
HAllo

Wie Steffen und Karin schon sagten:
Application.Match() funktioniert nur in einspaltigen Arrays.
arrTmp habe ich nur erstellt damit das Ganze etwas übersichtlich wird.
Ohne arrTmp wäre das so:

erg = Application.Match(suchen, WorksheetFunction.Index(arrNrBezGef, 0, 1), 0)

Da kann man schonmal den Überblick verlieren ;-)

Du schriebst:
"Das Array ist sortiert."

Dann gibt es eine richtig schnelle Suchroutine.
Die funktioniert genauso wie Zahlenraten.
Das Array wird solange halbiert bis der Wert gefunden wurde.
http://de.wikipedia.org/wiki/Bin%C3%A4re_Suche

Ich such mal den Code...

ransi

CitizenX
06.04.2012, 10:44
Hallo

Als Ergebnis bekomme ich Fehler 2042

das lag vermutlich daran ,dass ich dein Suchwert fälschlicherweise als String im Suchparameter eingegeben habe...
Wenn du im Suchparameter nur die Zahl 300 eingibst sollte es laufen .

hier noch eine Variante mit FIND die wesentlich schneller ist:


Sub test2()
Dim myRange As Range, SearchRange As Range, lnglast As Long, myMatch
Dim strSuche As String
Dim tt

tt = Timer
strSuche = 300

lnglast = Cells(1, 1).End(xlDown).Row
Set myRange = Range("A1:C" & lnglast)
Set SearchRange = Intersect(myRange, Columns(myRange(, 1).Column))

Set myMatch = myRange.Find(strSuche, Lookat:=xlWhole)

Debug.Print Timer - tt

If Not myMatch Is Nothing Then
MsgBox "gefunden in Zeile " & myMatch.Row
Else
MsgBox "nix gefunden"
End If

End Sub

HolN
06.04.2012, 10:58
Hallo Steffen,

super. Muß mich jetzt nur noch entscheiden welche Version ich nehme. Die von Ransi oder von dir. Sind beide sehr schnell.
Zum Suchen mit der Find Methode wird ja nicht einmal ein Array benötigt.

Gruß
nolle