Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1496to1500
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Makro beschleunigen (Zählenwenns)

Makro beschleunigen (Zählenwenns)
20.06.2016 17:52:00
Christoph
Hallo,
ich habe mal wieder ein Problem.
Habe eine große Datenmenge von ca. 30000 Datensätzen.
In Spalte H und I sind die Kriterien für meine Zählenwenns-Funktion.
Es soll dann gezählt werden wenn ein Verkäufer mehrmals vorkommt und in der dazugehörigen Zeile ein A steht.
Ich möchte dann zum Schluss eine Liste von den Verkäufern auf die das zutrifft.
Der Zähler von Zählenwenns soll größer als 3 sein also mindestens 3 zutreffende Ergebnisse.
Habe es erstmal damit versucht, einen Filter zu setzen der mir nur die a´s anzeigt und nur diese Zeilen durchsucht.
Hat schon etwas geholfen, aber vielleicht hat ja jemand eine Idee damit es noch schneller geht.
Hier die Beispieldatei mit wenig Daten.
im Reiter Verkäufer soll dann das Ergebnis stehen.
https://www.herber.de/bbs/user/106366.xlsm
Gruß
Christoph

8
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Makro beschleunigen (Zählenwenns)
20.06.2016 18:43:05
ransi
Hallo Christof,
Ich hab mal was anderes probiert.
Teste mal selber:
Option Explicit

Sub machs()
    Dim arr As Variant
    Dim L As Long
    Dim Element
    Dim myDic As Object
    Set myDic = CreateObject("scripting.Dictionary")
    With Sheets("Woche")
        arr = Intersect(.Range("I1").CurrentRegion, .Range("H:I"))
        For L = LBound(arr) To UBound(arr)
            If arr(L, 2) = "a" Then
                myDic(arr(L, 1)) = myDic(arr(L, 1)) + 1
            End If
        Next
        For Each Element In myDic
            If myDic(Element) < 3 Then
                myDic.Remove (Element)
            End If
        Next
        'Ausgeben
        .Range("K1").Resize(myDic.Count) = WorksheetFunction.Transpose(myDic.Keys)
        .Range("L1").Resize(myDic.Count) = WorksheetFunction.Transpose(myDic.items)
    End With
End Sub



ransi

Anzeige
AW: Makro beschleunigen (Zählenwenns)
20.06.2016 18:58:28
Christoph
Hallo ransi,
bin begeistert.
Hatte mal überlegt mich mit Dictionary zu beschäftigen. Das war mir dann aber doch irgendwie zuviel als VBA-Laie.
Habe eventuell noch ein, zwei Kleinigkeiten. Lasse den Beitrag aber erstmal auf beantwortet und melde mich dann nochmal.
Gruß Christoph

AW: Makro beschleunigen (Zählenwenns)
20.06.2016 19:24:32
Michael
Hi zusammen,
Ransis Code ist natürlich unschlagbar schlank und fix, allerdings trifft er die Vorgabe nicht exakt: die Spalte mit dem Datum wird so nicht übernommen.
Mein Vorschlag ist einer Reihe von Excel-Handgriffen nachempfunden und läuft etwas langsamer, schreibt aber die Datumsspalte.
ransi: ca. 15, meins: ca. 54 Millisekunden.
Ob die Datumsangaben relevant sind, mußt Du entscheiden: alle drei Varianten führen zu den gleichen Ergebnissen, aber zu unterschiedlichen Datümern (so weit vorhanden) und einer unterschiedlichen Sortierreihenfolge...
Die Datei: https://www.herber.de/bbs/user/106373.xlsm
Schöne Grüße,
Michael

Anzeige
AW: Makro beschleunigen (Zählenwenns)
20.06.2016 21:18:21
Daniel
Hallo
Wobei sich natürlich die Frage stellt, welcher von den Datumswerten jetzt genommen werden soll.
manuell kann man die Tabelle auch recht einfach mit Hilfe einer Pivottabelle erstellen:
Im Assisten der PivotTabelle folgende Einstellungen:
- ZEILEN: Spalte H "Verkäufer"
- SPALTEN: Spalte I "Kauf"
- WERTE: irgendeine Spalte nach Anzahl, Spalte A ENDE(Datum) nach Maximum (oder Minmum)
in der fertigen Pivottabelle:
- DropDown-Filter "Spaltenbeschriftungen" der Pivottabelle alles ausblenden ausser "a"
- Pivottabelle kopieren und an gleicher oder anderer Stelle als Wert einfügen (Pivotbeziehung aufheben)
- in der Ergebnisspalte "a" per Autofilter die Zeilen Fertig.
ansonsten kann man das auch manuell so erledigen:
1. Tabelle nach Spalte H (Verkäufer) und Spalte I (kauf) sortieren
2. in einer ersten Hilfsspalte (J) folgende Formel
=Wenn(I2="a";Wenn(H2=H1;J1+1;1);"")
3. in einer zweiten Hilfspalte (K) folgende Formel:
=Wenn(Und(I2="a";Oder(H2H3;I2I3);J2>=3);1;"")
4. dann alle Zeilen kopieren, bei denen in K eine 1 steht (Autofilter oder SpecialCells)
das sieht als Code dann so aus:
Sub Suchen_und_Kopiern()
With Sheets("Woche")
With .Cells(1, 1).CurrentRegion
.Sort key1:=.Cells(1, 8), order1:=xlAscending, _
key2:=.Cells(1, 9), order2:=xlAscending, Header:=xlYes
With .Columns(.Columns.Count).Resize(.Rows.Count - 1, 2).Offset(1, 1)
With .Columns(1)
.FormulaR1C1 = "=IF(RC9=""a"",IF(RC8=R[-1]C8,R[-1]C+1,1),"""")"
End With
With .Columns(2)
.FormulaR1C1 = _
"=IF(AND(RC9=""a"",OR(RC8R[1]C8,RC[-2]R[1]C[-2]),RC[-1]>=3),1,"""")"
If WorksheetFunction.Sum(.Cells) > 0 Then
Intersect(.SpecialCells(xlCellTypeFormulas, 1).EntireRow, _
.Worksheet.Columns(8)).Copy Sheets("Verkäufer").Cells(2, 1)
Intersect(.SpecialCells(xlCellTypeFormulas, 1).EntireRow, _
.Worksheet.Columns(1)).Copy Sheets("Verkäufer").Cells(2, 2)
End If
End With
.ClearContents
End With
End With
End With
End Sub
bei sehr grossen Datenmengen könnte man nochmal die Hilfsspalten kopieren und als Wert einfügen und dann die Tabelle nach der zweiten Hilfsspalte sortieren, so dass die zu kopierenden Daten einen lückenlosen Zellblock bilden.
Gruß Daniel

Anzeige
AW: Makro beschleunigen (Zählenwenns)
20.06.2016 22:20:36
Christoph
Hallo Michael,
ich danke dir mal wieder. Das trifft es genau.
Habe noch nach Spalte B sortieren lasse. Damit habe ich jetzt genau das gleiche Ergebnis wie von meinen Daten. Brauche immer das kleinste Datum von einem Verkäufer.
25000 Daten laufen ohne Probleme in 226 Millisekunden durch.
Lösung von Ransi ist trotzdem abgespeichert, vielleicht schaffe ich es ja mal irgendwann beide Codes zu verstehen :).
Nochmals VIELEN DANK!!
Gruß Christoph

kleine Fehlerkorrektur
21.06.2016 23:14:13
Michael
Hi zusammen,
ich freue mich natürlich, daß die Geschichte funktioniert und Dir gefällt.
Allerdings ist mir noch ein kleiner Fehler aufgefallen: in der Zeile...
Set c = nachWs.Range("D1:D" & maxZ).Find(2, nachWs.Range("D1"), _
xlValues, xlWhole)

sucht das Makro nach der Zahl 2, aber das funktioniert leider nur zufällig, wenn die zweite Zeile ungleich der ersten ist.
Deshalb weiter oben die Änderung:
maxZ = nachWs.Range("A" & vonWs.Rows.Count).End(xlUp).Row
If maxZ > 1 Then
nachWs.Range("A2:C" & maxZ).Clear       ' nur bis C statt D
nachWs.Range("D2:D" & maxZ).Value = 2   ' neu ***
End If

Damit wird die komplette Spalte D mit 2ern vorbelegt, d.h. damit ist sichergestellt, daß die 2 definitiv vorhanden ist und damit mit .find gefunden wird.
Um "beide Codes zu verstehen" fängst Du am besten damit an, sie mit F8 schrittweise laufen zu lassen bzw. geeignete Haltepunkte zu setzen (z.B. vor oder nach Schleifen, bei denen man sich nicht ALLE Durchgänge ansehen will) oder einfach eine Zeile mit
Stop

einzufügen.
Ganz nett ist es auch, "ganz oben" eine Konstante zu setzen, z.B.
Const testen = True

und dann im Code an besagten Stellen zu schreiben
If testen Then Stop

dann muß man nur testen = False definieren, um die Stops "auszublenden".
Happy Exceling,
Michael

Anzeige
AW: kleine Fehlerkorrektur
22.06.2016 04:51:18
Christoph
Hallo Michael,
den Fehler habe ich gestern auch schon bemerkt.
Da ich mir erstmal nicht anders zu helfen wusste, habe ich einfach eine weitere IF-Schleife geschrieben und nach 3 suchen lassen. Hat auch funktioniert.
Aber deine Variante ist natürlich professioneller und sicherer.
Das mit der Hilfe, die Codes zu verstehen werde ich mir mal anschauen.
Gruß Christoph

na, dann bin ich ja froh,
22.06.2016 12:56:29
Michael
lieber Christoph,
daß ich den Fehler "vor Dir" erwähnt habe...
Das schöne an den Stops ist, daß man während der Unterbrechung der Codeausführung ansehen kann, was jeweils in den betreffenden Tabellenblättern steht. DAMIT kannst Du nachvollziehen, was wann passiert.
Mit F8 geht es halt zeilenweise und mit F5 wird das Makro bis zum nächsten Stop bzw. Ende ausgeführt, d.h. mit F8 kannst Du bei Schleifen mal ein, zwei Durchgänge machen (Mauszeiger über einer Variable zeigt den Wert derselben in einem Tooltip an) und mit F5 bis zu einem gesetzten Stop direkt unter der Schleife springen.
Viel Spaß & LG,
Michael
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige