Live-Forum - Die aktuellen Beiträge
Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender

Forumthread: VB- Funktion für WorksheetFunction.Match

VB- Funktion für WorksheetFunction.Match
MichaV
Hallo,
ich glaube es gibt für WorksheetFunction.Match eine eigene VB- Funktion. Komme aber nicht auf den Namen, kann mir bitte jemand auf die Sprünge helfen?
Danke, Micha
PS: Oder verwechsele ich das mit Choose? Warum gibts nicht mehr diesen schönen "siehe auch"- Link in der XL2007- Hilfe? Neumodisches Zeug...
Anzeige
Choose, Switch, Iif, Select Case
14.03.2010 13:12:38
Erich
Hi Micha,
eine weitgehende Entsprechung für Match (VERGLEICH) kenne ich in VBA nicht.
Ein paar Funktionen, die irgendwo in der Nähe liegen, habe ich dir in den Betreff geschrieben.
Rückmeldung wäre nett! - Grüße von Erich aus Kamp-Lintfort
AW: Choose, Switch, Iif, Select Case
14.03.2010 13:21:57
MichaV
Danke Erich, die kenne ich auch.
Habs wohl mit Choose verwechselt...
Anzeige
AW: Application.Match ? o.r.T
14.03.2010 13:31:10
Gerd
Hallo Micha!
Oder sehe ich das zu einfach?
Gruß Gerd
Ja, denn das ist die WshFct! Gruß owT
14.03.2010 13:55:06
Luc:-?
:-?
AW: :-?
14.03.2010 14:25:18
Gerd
Hi Luc,
kannst noch einen kleinen Leitartikel darüber schreiben, weshalb die WF bei keinem Treffer in einen
nicht abfangbaren Fehler läuft (wohlbemerkt bei Fehlerbehandlung mit "On Error Resume Next"),
während Application.Match eine auswertbare Fehlernummer zurückgibt ?
Gruß Gerd
Anzeige
Ich schreibe udF, da passiert das nicht!
14.03.2010 15:20:14
Luc:-?
…Und mit On Error Resume Next wird der Fehler ja nicht wirklich abgefangen, sondern nur übergangen. In Subroutinen fange ich Fehler meist ab und entscheide anhand der FehlerNr und weiterer Umstände, was dann passieren soll. Ggf setze ich auch fort. Resume Next kann nämlich auch nach dem Abfangen noch eingesetzt wdn. Ist auch beim Testen ganz nützlich.
In meinen udF liefert …Match immer eine auswertbare Fehlernr (Err.Number = xlErrNA), aber es kann natürlich sein, dass eine Subroutine diese xlFehlerwerte nicht anerkennt bzw feststellt und durch Weglassen von WorksheetFunction quasi dazu gezwungen wird. Möglicherweise kann man den Fehler auch bei Verwendung von WorksheetFunction feststellen, wenn man dazu ebenfalls eine entsprechende WorksheetFunction benutzt. Aber das habe ich noch nicht ausprobiert. Interessant wäre ggf auch zu wissen, welche FNr Application.Match im Ggsatz zu WorksheetFunction.Match zurück gibt. Das kann man mit echtem F-Abfangen (On Error GoTo xyz) und einer MsgBox ganz leicht feststellen.
Ich habe hier ja schon öfter diese Begründung für die Verwendung von WorksheetFunction-Namen als Eigenschaft von Application gelesen, muss aber sagen, dass mir dieses Problem, auch bei Subroutinen, zuvor nie aufgefallen war. Das mag verschiedene Ursachen haben — viell mache ich aber auch nur irgendwas entscheidend anders… ;-)
Gruß+schöSo, Luc :-?
Anzeige
Mein vorhergehender Betreff stimmt so nicht!
14.03.2010 19:47:32
Luc:-?
Habe das jetzt doch mal etwas eingehender getestet, Folks,
und kann deshalb mit dem Mythos aufräumen, dass es da einen Unterschied zwischen Fkts- u.Subprozeduren gäbe. Es gibt keinen! Das Ganze muss mit der Objektregie von xlVBA zusammenhängen. Wenn nämlich bei WorksheetFunction.Match der Suchbegriff nicht gefunden wird, entsteht ein Fehler, weil dem Objekt die Eigenschaft .Match nicht zugeordnet wdn kann (Err.Number = 1004). Der vergebliche Versuch das zu tun, könnte natürl etwas zusätzl Zeit kosten, aber das ist wohl zu vernachlässigen. Genau diesen Fehler kann man dann auch abfangen u.auswerten, nicht den Inhalt der Variablen, der die Berechnung zugewiesen wdn soll. Die bleibt nämlich leer. Ist sie als Variant deklariert, kann man das auch mit IsEmpty(…) auswerten.
Wird mit Application.Match gearbeitet, muss man zwar auf den xlfktsspezifischen VBA-Intellisense verzichten, erhält dafür aber stets ein Ergebnis. Ist die Variable wiederum als Variant deklariert, kann das auch ein F-Wert sein. Allerdings wird dadurch kein abfangbarer Fehler ausgelöst; das müsste man bspw mit Err.Raise CLng(dieseVariable) selbst pgmieren. Allerdings enthält die Variable dann bereits den xlF-Wert, der so natürlich auch ausgewertet bzw problemlos übergangen wdn könnte. Wenn man das alles weiß und berücksichtigt, ist es eigentl (fast) nur noch Geschmackssache, was man verwendet. VBA-Standard ist dabei auf jeden Fall die WorksheetFunction-Variante.
Ich kann mich des begründeten Verdachts kaum erwehren, dass bei Vielen einfach nur eine Begriffsverwirrnis in Bezug auf Fehler und wie man sie abfängt herrscht…
XL-Fehlerwerte haben mit VBA-Fehlern nichts zu tun — wenn man eine Err.Number abfragt, wird man also normalerweise keine xlFehlerNr (7 diskrete im Bereich von 2000…2042) erhalten und einen ggf zugehörigen F-Text natürlich erst recht nicht. Für VBA ist das kein Fehler, sondern nur ein Wert vom Datentyp Fehler. Das ist ein Unterschied!
Einen VBA-Fehler fängt man ab, indem man an den Anfang des Pgms On Error GoTo znr|marke setzt. Am Sprungziel muss man eine anders vom Pgm nicht erreichbare F-Behandlungsroutine einsetzen, in der man den Fehler analysiert und ggf unterschiedl Maßnahmen wie MsgBox-Anzeigen, Pgm mit nächstem Befehl nach Auftreten des Fehlers (Resume Next) bzw an definierter Stelle fortsetzt oder mit/ohne eine spezifische Ausgabe/Datenweitergabe etc beendet. Mit On Error Resume Next übergeht/ignoriert man den Fehler nur. Genau das sagt auch die Anweisung aus. Und hier liegt auch ein gewisser Unterschied zwischen den Prozedurarten. Eine Fkt wird so etwas eher tolerieren als eine Routine, denn die Zelle verlangt nach einem Ergebnis, aber letztlich hängt's doch überwiegend vom Pgmcode ab.
Es wäre natürlich nicht ganz auszuschließen, dass mal eine andere Fkt den gleichen Namen hat wie eine xl/vbFkt, aber das müsste dann schon eine fremde sein, die garantiert nicht zur Application gehört, — MS dürfte das berücksichtigt haben. Wenn man selber udFktt schreibt u.engl Namen verwendet, kann man schon mal 'ne ActiveX-Fkt o.ä. erwischen — ist mir auch schon mal passiert. Das gibt dann aber eher Probleme als 'ne Arbeitserleichterung. Die unterschiedlichen Arbeitsgeschwindigkeiten der Match-„Varianten“ dürften auf unterschiedl interne Arbeitsumgebungen zurückzuführen sein. D.h., es wdn unterschiedl viele interne Subroutinen angesprochen. Möglicherweise unterscheiden sich die internen Abläufe sogar noch weitergehender…
Gruß Luc :-?
Anzeige
AW: Aha, so nicht!
14.03.2010 21:27:59
Gerd
Hi Luc,
nach meinem "Archithekturverständnis" können diese Unterschiede nicht aus dem selben "Objekt" herrühren. Match der Application ist allenfalls eine Kopie von Match des Worksheetfunction-Objekts, aber wohl keine identische. Die Fehlervermeidung, die in beiden Fällen möglich wäre, u. die Fehlerbehandlung waren nicht mein Thema.
Damit die Sache nicht so theoretisch abgehandelt bleibt:
Sub test_App_Match()
Dim x
On Error GoTo weiter
x = Application.Match("Luc", Range("A1:A10"), 0)
weiter:
Err.Clear
MsgBox CStr(x)
End Sub
Sub test_WF_Match()
Dim x
On Error GoTo weiter:
x = WorksheetFunction.Match("Luc", Range("A1:A10"), 0)
weiter:
Err.Clear
MsgBox CStr(x)
End Sub
Gruß Gerd
Anzeige
AW: Fehler sollten wenn möglich vermieden werden
14.03.2010 21:36:51
Daniel
z.B in dem man vorab prüft, ob der Suchwert überhaupt vorhanden ist, z.B. mit CountIF.
Wenn der Suchbegriff fehlt, ist eh meist eine andere Vorgehensweise im Code erforderlich.
Gruß, Daniel
AW: Stimmt, aber ...
14.03.2010 21:42:08
Gerd
..... das war hier nicht der Punkt.
Gruß Gerd
match() zu lahm und ausserdem...
14.03.2010 14:58:43
ransi
HAllo
...versagen beide wenn die Arrays größer als 65536 Elemente werden.
Ich bin schon vor einiger Zeit von match() abgerückt.
Egal ob Application.Match() oder Worksheetfunction.MATCH().
Ich klapper die Arrays Element für Element ab.
MAn bekommt keine Fehler und ausserdem ists auch schneller als Match().
Hier mal ein (sinnlo´ser Beispielcode)
10000 DAten in ein Array.
Erst werden die 10000 Daten mit Match() gesucht, und in der letzten Schleife wird jeder Wert im Array angefasst. Die benötigten ZEiten werden in den Msgboxen ausgegeben.
' **********************************************************************
' Modul: Tabelle2 Typ: Element der Mappe(Sheet, Workbook, ...)
' **********************************************************************

Option Explicit


Public Sub test()
Dim L As Long
Dim I As Long
Dim tmp
Dim T As Double
Dim arr(1 To 10000)
Randomize Timer
For L = 1 To 10000
    arr(L) = CStr(Rnd)
Next
'#############
'Mit Match()
T = Timer
For L = 1 To 10000
    tmp = WorksheetFunction.Match(arr(L), arr, 0)
Next
MsgBox Timer - T
'#############
'Array einzeln absuchen
T = Timer
For L = 1 To 10000
    For I = 1 To 10000
        If arr(L) = arr(I) Then
            tmp = L
            Exit For
        End If
    Next
Next
MsgBox Timer - T
End Sub


ransi
Anzeige
Na, dann kann man ja beruhigt sein, was die...
14.03.2010 15:36:44
Luc:-?
…Pgm-Performance bei Feldern betrifft, Ransi;
viele Diskussionen dazu wdn dadurch ggstdslos und der Einsatz reduziert sich so allerhöchstens auf Zellbereiche. Aber durch das schnelle Umwandeln der Bereiche in Datenfelder ist das ja auch nicht nötig. Interessant bleibt die xlFkt dann wahrscheinl nur noch für den Einsatz in gesplitteten Texten, weil das Schreibaufwand spart und der so entstandene, ein Array beinhaltende Variant auch kaum mehr als einige 100 Elemente enthalten dürfte…
Gruß+schöSo, Luc :-?
Anzeige
2.Aspekt: Man kann sich so etwas natürl...
14.03.2010 15:42:35
Luc:-?
…auch als eigene vbFkt bereitstellen, Folks… ;-)
Gruß Luc :-?
AW: nur match( , , 0) ist langsam
14.03.2010 15:50:33
Daniel
Match( , , 1) hingegen ist deutlich schneller.
man muss die Daten zwar vorher sortieren, aber das kann Excel ja sehr gut.
Gruß, Daniel
der Aufwand lohnt sich aber nur...
14.03.2010 16:20:39
Tino
Hallo,
, wenn man wie in Deinem Beispiel viele Daten immer wieder durchsuchen muss.
Wenn man nur einmal eine Spalte durchsuchen muss um
z. Bsp. ein Datum zu finden um mit dieser Position weiterzuarbeiten reicht auch die Match Funktion.
Gruß Tino
Anzeige
AW: Wie man es sieht ....
14.03.2010 17:03:56
Gerd
Hallo,
ein realistischeres Beispiel Application.Match und Worksheetfunction.Match am Range-Objekt,
Auslesen in das Datenfeld aus der Tabelle für die "lineare Methode" u. jeweils nur eine Suche.
Zunächst stelle ich fest, dass Application.Match u. Worksheetfunction.Match unterschiedliche Geschwindigkeiten haben, also verschiedene Funktionen sein müssen.
Und im Datenfeld ist die Laufzeit so gering, dass ich beim Timer noch etwas dazuschreiben musste, damit überhaupt ein Wert größer (absolut) Null herauskommt. :-)
Die Ergebnisse auf meinem PC:
T1 0,421875
T2 0,359375
T3 0,000000000001
Public Sub test2()
Dim L As Long
Dim I As Long
Dim tmp
Dim T1 As Double, T2 As Double, T3 As Double
Dim arr()
For L = 1 To 10000
Cells(L, 1) = L
Next
'Mit Application.Match()
T1 = Timer
For L = 1 To 10000
tmp = Application.Match(9000, Range("A1:A10000"), 1)
Next
T1 = Timer - T1
'Mit Worksheetfuncion.Match()
T2 = Timer
For L = 1 To 10000
tmp = WorksheetFunction.Match(9000, Range("A1:A10000"), 1)
Next
T2 = Timer - T2
'Array einzeln absuchen
T3 = Timer
arr = Application.Transpose(Range("A1:A10000"))
For L = 1 To 10000
If arr(L) = 9000 Then Exit For
Next
T3 = Timer - T3 + 1 / 1000000000000
Debug.Print T1
Debug.Print T2
Debug.Print T3
End Sub
Gruß Gerd
Anzeige
AW: Und noch realistischer
14.03.2010 17:20:11
Gerd
Hallo,
ich hatte vergessen, bei den beiden Match-Varianten die Schleifen herauszunehmen.
So kann ich bei einer Suche nirgends mehr die (zu geringe) Geschwindigkeit messen.
Tino, da liegst Du also völlig richtig. Immerhin war der erste Test für die andere Feststellung hilfreich.
Gruß Gerd
Anzeige
AW: Choose, Switch, Iif, Select Case
14.03.2010 16:32:50
wsp
Hallo alle zusammen,
eine Alternative ist die Find-Methode eines Range-Objectes, diese erzeugt auch "ordentliche" Error-
Codes , aber ! sie funktioniert nicht in Funktionen, die in einer Zellformel aufgerufen werden.
Gruss Wolfgang
SPAM!
14.03.2010 15:48:05
MichaV
Leute, warum bekomme ich nun bei jedem neuen Beitrag ZWEI Benachrichtigungs- Emails? Eine im gewohnten schlichten Stil, und eine in hässlichen Farben. Hat Hans da was geschraubt? Ist ja schauerlich...
Und interessante Diskussion ist das hier (vor allem wg dem unterschiedlichen Fehlerferhalten von application. und worksheetfunction.), aber ich suchte nach einer reinen VB- Funktion, also ohne irgendwas mit Punkt davor.
Gruss- Micha (geht jetzt ins Kino)
Anzeige
Viel Spaß! Ansonsten scheinst du ja nun...
14.03.2010 15:58:29
Luc:-?
…langsam, aber sicher zum ægte Normann zu mutieren, Micha… ;-)
Gruß Luc :-?
PS: Hätte da noch was für dich, setze ich hier evtl noch nach…
OT.. was hab ich denn nun wieder..
14.03.2010 21:22:56
MichaV
..gemacht? Warum sagst Du sowas? (langsam, aber sicher zum ægte Normann zu mutieren, Micha)
underlig...
Anzeige
Nutze die Maus! ;-) Gruß owT
16.03.2010 01:35:23
Luc:-?
:-?
ArrayList,
14.03.2010 16:28:31
ransi
HAllo
aber ich suchte nach einer reinen VB- Funktion, also ohne irgendwas mit Punkt davor.
Na dann kannst du doch auch reine VB-Elemente nutzen. ;-)
Eine ArrayList kann sowas.
ArrayList.IndexOf-Methode (Object, Int32)
Sucht nach dem angegebenen Object und gibt den nullbasierten Index des ersten Vorkommens innerhalb des Abschnitts der ArrayList zurück, der sich vom angegebenen Index bis zum letzten Element erstreckt.
ArrayList.LastIndexOf-Methode (Object, Int32)
Sucht nach dem angegebenen Object und gibt den nullbasierten Index des letzten Vorkommens innerhalb des Abschnitts der ArrayList zurück, der sich vom ersten Element bis zum angegebenen Index erstreckt.
Schau es dir mal an:
Option Explicit




Public Sub test()
Dim L As Long
Dim tmp
Dim objAL As Object
Dim T As Double
Set objAL = CreateObject("System.Collections.Arraylist")
Randomize Timer
For L = 1 To 10000
    objAL.Add CStr(Rnd)
Next
T = Timer
For L = 0 To 9999
    tmp = objAL.indexof(objAL(L), 0)
Next
MsgBox Timer - T
End Sub


ransi
Anzeige
Schöne Sache! Werde ich bei Gelegenheit...
14.03.2010 18:49:52
Luc:-?
…mal anwenden, Ransi…
Gruß Luc :-?
AW: Schöne Sache! Werde ich bei Gelegenheit...
14.03.2010 21:15:31
MichaV
Hallo,
ganz nett, aber das ist genausowenig "reines" VB wie VBA. Du bindest ja ein Objekt ein, und schon greifst Du auf VB-fremde Elemente zu.
Gruss- Micha
PS: zurück aus dem Wunderland.... Gott was war es da schlecht.
Aha...! Gruß owT
16.03.2010 01:37:40
Luc:-?
:-?
Anzeige
;

Forumthreads zu verwandten Themen

Anzeige
Entdecke relevante Threads

Schau dir verwandte Threads basierend auf dem aktuellen Thema an

Alle relevanten Threads mit Inhaltsvorschau entdecken
Anzeige
Anzeige

Infobox / Tutorial

VB-Funktion für WorksheetFunction.Match in Excel VBA


Schritt-für-Schritt-Anleitung

  1. Öffne den Visual Basic for Applications (VBA) Editor: Drücke ALT + F11, um den Editor zu öffnen.
  2. Erstelle ein neues Modul: Klicke mit der rechten Maustaste im Projektfenster und wähle Einfügen > Modul.
  3. Füge den folgenden Code ein:
Sub TestUsingMatch()
    Dim searchValue As Variant
    Dim result As Variant

    searchValue = "Luc" ' Suchwert anpassen
    ' Anwendung der WorksheetFunction.Match
    On Error Resume Next
    result = Application.WorksheetFunction.Match(searchValue, Range("A1:A10"), 0)

    If IsError(result) Then
        MsgBox "Wert nicht gefunden!"
    Else
        MsgBox "Wert gefunden in Zeile: " & result
    End If
End Sub
  1. Führe die Funktion aus: Klicke auf Run oder drücke F5, um die Funktion zu testen.

Häufige Fehler und Lösungen

  • Fehler bei der Verwendung von WorksheetFunction.Match:

    • Problem: Run-time error '1004' wenn der Suchwert nicht gefunden wird.
    • Lösung: Verwende On Error Resume Next, um den Fehler zu ignorieren, oder überprüfe vorher mit CountIf, ob der Wert existiert.
  • Falscher Datentyp:

    • Problem: Wenn der Suchwert in der Range nicht vorhanden ist.
    • Lösung: Stelle sicher, dass der Datentyp des Suchwertes mit dem Datentyp der Range übereinstimmt.

Alternative Methoden

  • Find-Methode: Diese Methode ist schneller und erzeugt klare Fehlermeldungen, funktioniert jedoch nicht in UDFs:
Sub FindExample()
    Dim rng As Range
    Set rng = Range("A1:A10").Find("Luc", LookIn:=xlValues)
    If Not rng Is Nothing Then
        MsgBox "Wert gefunden in Zelle: " & rng.Address
    Else
        MsgBox "Wert nicht gefunden!"
    End If
End Sub
  • ArrayList: Eine ArrayList kann auch verwendet werden, um Indizes effizient zu finden:
Sub ArrayListExample()
    Dim objAL As Object
    Set objAL = CreateObject("System.Collections.ArrayList")
    objAL.Add "Luc"
    MsgBox "Index von Luc: " & objAL.IndexOf("Luc")
End Sub

Praktische Beispiele

  • Beispiel 1: Suche nach einem Wert in einem bestimmten Bereich:
Sub ExampleMatch()
    Dim searchValue As String
    Dim result As Variant

    searchValue = "Test" ' Suchwert
    result = Application.Match(searchValue, Range("A1:A10"), 0)

    If Not IsError(result) Then
        MsgBox "Wert gefunden in Zeile: " & result
    Else
        MsgBox "Wert nicht gefunden!"
    End If
End Sub
  • Beispiel 2: Anwendung von Excel Vba Match Funktion in einer Schleife:
Sub LoopThroughMatch()
    Dim i As Long
    Dim result As Variant

    For i = 1 To 10
        result = Application.Match(i, Range("A1:A10"), 0)
        If Not IsError(result) Then
            MsgBox "Wert " & i & " gefunden in Zeile: " & result
        End If
    Next i
End Sub

Tipps für Profis

  • Verwende die Application.Match-Funktion anstelle von WorksheetFunction.Match, wenn du sicherstellen möchtest, dass du keine Laufzeitfehler bekommst, da sie eine Fehlernummer zurückgibt, die abgefangen werden kann.
  • Überprüfe vorher, ob der Suchwert existiert, um unnötige Fehler zu vermeiden.
  • Denke daran, dass die Geschwindigkeit von Application.Match und WorksheetFunction.Match unterschiedlich sein kann. Teste die Leistung bei großen Datenmengen.

FAQ: Häufige Fragen

1. Was ist der Unterschied zwischen Application.Match und WorksheetFunction.Match?
Application.Match gibt eine Fehlernummer zurück, während WorksheetFunction.Match einen Laufzeitfehler auslöst, wenn der Wert nicht gefunden wird.

2. Wie kann ich die Geschwindigkeit der Suche verbessern?
Verwende Application.Match für große Datenmengen oder prüfe zuerst mit CountIf, ob der Wert vorhanden ist, bevor du Match aufrufst.

3. Kann ich die Match-Funktion in einer UDF verwenden?
Ja, jedoch solltest du vorsichtig sein, da die WorksheetFunction.Match in UDFs nicht die gleichen Fehlerbehandlungen hat wie in regulären Subroutinen.

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Entdecke mehr
Finde genau, was du suchst

Die erweiterte Suchfunktion hilft dir, gezielt die besten Antworten zu finden

Suche nach den besten Antworten
Unsere beliebtesten Threads

Entdecke unsere meistgeklickten Beiträge in der Google Suche

Top 100 Threads jetzt ansehen
Anzeige