Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1840to1844
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

Zählenwenn... Beschleunigung VBA?

Zählenwenn... Beschleunigung VBA?
24.07.2021 01:37:47
Frank
Hallo Leute,
leider muss ich ">" durch "gr." ersetzen, also in den Formeln steht anstatt ">" "gr.".
ich muss 700 Zählenwennfunktionen abarbeiten und ausgeben (gr.1, gr.2, gr.3 usw... jeweils als einzelnes Ergebnis in 700 Zellen, kann nicht zusammengefasst werden) und zwar über 800000 Zeilen aus Spalte A, die 700 Ergebnisse sind dann in Spalte B. Muss Excel benutzen, falls jemand das über eine Datenbank lösen will. Das geht leider nicht.
Ich bräuchte also VBA Code wäre für: Zählenwenn Spalte A >1, Ausgabe in Zelle B1.
VBA (countif?) soll wohl schneller sein wg. anderer Berechnungart als mit zählenwenn via Formel, dazu komme ich gleich.
sieht dann so aus, ganz einfach: (A=Spalte A)
A
5
(leere Zelle)
6
(leere Zelle)
(leere Zelle)
8
(leere Zelle)
4
.
.
usw.
Zum Glück sind nur ca. 2000 von 800000 Zeilen gefüllt in Spalte A, das gibt etwas Spielraum für Formeln / VBA.
Ohne VBA konnte ich mir nur bedingt behelfen:
Leider dauert eine Berechnung dann ca. 30 Sekunden da ich 700 Zählenwennfunktionen (Ausgabe in Spalte B1 bis B700) benutze und z.B. hier in Spalte B ausgebe
(also B1=Zählenwenn(A1:A800000;"gr."1)
(also B2=Zählenwenn(A1:A800000;"gr."2)
usw.
Ich konnte den Code schon etwas beschleunigen mit einer vorherigen Abbruchfunktion.
Habe aus
B1=zählenwenn(a1:a800000;"gr."1) diese Formel gemacht =wenn(a1:a800000<=1;0;zählenwenn(a1:a800000;"gr."1))
B2=zählenwenn(a1:a800000;"gr."2) diese Formel gemacht =wenn(a1:a800000<=2;0;zählenwenn(a1:a800000;"gr."2))
Komischerweise müsste der Code viel schneller sein wenn Excel wirklich abbrechen würde wenn die wenn-Funktion erfüllt ist, da von den 800000 Zellen nur ca. 2000 wirklich mit Werten gefüllt sind. Leider macht das Excel wohl intern nicht so und eine Berechnung dauert kürzer aber immer noch 25 Sekunden.
Daher ist das leider keine Lösung.
Eine sehr unelegante Lösung ohne VBA ist Folgende und dauert auch noch relativ lange, da die Zeilenanzahl aus Spalte A (800000) einfach zu hoch ist für's filtern/kopieren:
Filter setzen auf Spalte A, "leere" abwählen, dann die restlichen Zellen (nicht leeren) kopieren und in neue Tabelle kopieren in Spalte A und hier dann die Zählenwennfunktionen in Spalte B nur über z.b. 10000 Zellen ausführen (sind ja meistens nur 2000 gefüllt bei mir, da reichen dann 10000 aus, also Spalte B kann ich dann z.B. verringern von 800000 auf 10000 Zellen, das wäre dann: B1=zählenwenn(a1:a10000;"gr."1) und das geht dann natürlich deutlich schneller.
Das kann man auch alles in ein Makro packen, finde ich aber sehr unelegant und dauert auch noch relativ lange durch das einfügen der gefilterten Zellen in das
neue Tabellenblatt, da Excel trotzdem immer noch mit den 800000 Zellen zu kämpfen hat(warum auch immer) - obwohl ja nur noch 2000 kopiert/eingefügt werden.
Eine neue Berechnung ist dann auch noch nötig was wieder Zeit kostet.
kurz: Das ist Murks.
-----------------------
Habt Ihr viell. noch eine andere Lösung ohne VBA?
Ansonsten:
Ich habe gehört, dass die VBA-Excel-funktion (countif?) dieses Problem wohl nicht hat und deutlich schneller zählen kann.
Mir ist klar, dass auch das eine nicht unerhebliche Arbeit werden wird 700 mal VBA "count if" zu coden, aber dass muss ich dann nur einmal machen (da ich 700 Ergebnisse brauche in 700 Zellen)
Die Ausgabe wäre dann z.B. in Spalte B.
Spalte B1 wäre dann alle größer 1 aus Spalte A
Spalte B2 wäre dann alle größer 2 aus Spalte A
Spalte B3 wäre dann alle größer 3 aus Spalte A
Usw....
Kann mir hier jemand den VBA-Code für B1 zur Verfügung stellen?
Das wäre dann ohne VBA gesprochen:
B1 = zählenwenn(A1:A800000;"gr."1) - ich brauche also diese Formel in VBA (countif ist glaube der Ansatz). Kann mir auch gut vorstellen, dass wenn man die leeren Zellen via VBA nicht zählt der Code noch schneller läuft (oder langsamer?) - das weiß ich aber nicht.
Für B2 usw. kann ich dann ja (700 mal....) den Code aus B1 manuell abändern und dahinter einfügen (das wird wohl das längste Makro dass ich jemals hatte)...
Das Problem bei Zählenwenn ohne VBA ist wohl, dass Excel den entsprechenden Bereich der gezählt werden soll wohl nicht linear abarbeitet und immer wieder Zellen auf Veränderungen überprüft beim Zählen. Daher steigt die Rechenintensität bei Zählenwenn ohne VBA exorbitant an bei größeren Zellenmengen (bei mir halt 800000).
---------------
Vielleicht hat jemand von Euch noch eine ganze andere Lösung? VBA Code wäre super für Zählenwenn Spalte A >1, Ausgabe in Zelle B1.
Vielen Dank für Eure Mühe !

10
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Zählenwenn... Beschleunigung VBA?
24.07.2021 02:24:41
Daniel
Hi
Schau dir mal die Funktion Häufigkeit an.
Die berechnet solche Auswertungen ziemlich zügig.
Du müsstet dann in B1:B700 die Zahlen 1-700 eintragen und dann
Die Zellen C1:C701 markieren, die Formel =Häufigkeit(A1:A800000;B1:700) eingeben und mit STRG+SHIFT+ENTER abschließen.
Das ist wahrscheinlich noch nicht ganz dein Wunschergebnis, aber das kannst du relativ einfach dann aus diesen Werten ableiten.
Häufigkeit ist hier sehr schnell, weil es nicht 700 Formeln sind, die 700x 800000 Zellen überprüfen müssen, sondern es ist eine Formel, die nur einmal über die 800000 Zellen läuft und dann die 700 Ergebnisse auspuckt.
Gruß Daniel
Anzeige
In Ergänzung: Natürlich als plurale MatrixFml, ...
24.07.2021 03:36:27
Luc:-?
…Frank;
nebenbei, die HTML-Schreibung für > & Co kannst du auch in Fmln verwenden oder eben die Fml in pre-Tags setzen. Letzteres wäre vor allem bei notwendig mehreren zusammenhängenden normalen Leerzeichen in einer Fml erforderlich, da alle Browser die in plain.Text reduzieren.
Es muss übrigens ">1" usw in deinen Fmln heißen.
Morhn, Luc :-?
AW: evtl. mit DBANZAHL() ? ...
24.07.2021 09:26:06
neopa
Hallo Frank,
... allerdings bedarf es dazu der Einfügung einer Überschrift (hab diese hier z.B. einfach "Wert" benannt) über Deinem ersten Datenwert.
Ich weiß aber nicht, ob damit das von Dir angestrebte erreicht wird. Ich nutzte diese Funktionalität bisher selbst noch nie wirklich, habe nur gelesen, dass sie sehr schnell auswerten soll. Teste doch mal.
Wenn ich Deine Aufgabenstellung richtig verstanden habe, dann z.B. wie folgt. Kopiere die Zellen D1:D2 ziehend nach rechts bis ZX (Spalte700) und die Formel B2 bis B701:
Arbeitsblatt mit dem Namen 'Tabelle3'
 ABCDEFGH
1WertAnz WertWertWertWertWert
526 >1&gt2&gt3&gt4&gt5
3 19      
4616      
5 9      
674      
7        
8        
98       
10        
1111       
122       

ZelleFormel
B2=DBANZAHL(A$1:A$800000;"Wert";INDEX(D$1:ZX$2;;ZEILE(A1)))
D2="&gt"&SPALTE(A1)
Verwendete Systemkomponenten: [Windows (32-bit) NT 6.02] MS Excel 2010
Diese Tabelle wurde mit Tab2Html (v2.6.0) erstellt. ©Gerd alias Bamberg

Gruß Werner
.. , - ...
Anzeige
AW: zur Auswertung mt HÄUFIGKEIT() ...
24.07.2021 11:26:01
neopa
Hallo nochmal,
... plurale Matrixformeln sind sicherlich bzgl. Geschwindigkeit effizienter als singuläre, jedoch fällt mir momentan keine plurale Lösungsformel mit HÄUFIGKEIT() ein, deren Ergebnis vergleichbar zu meiner DBANZAHL()-Formel-Vorschlag ist.
Als singuläre Formel sieht die bei mir wie folgt aus::
=ANZAHL(A$2:A$800000)-HÄUFIGKEIT(A$2:A$800000;ZEILE(A1)) und diese entsprechend weit nach unten kopieren.
Gruß Werner
.. , - ...
AW: zur Auswertung mt HÄUFIGKEIT() ...
24.07.2021 11:48:29
Daniel
Hi
Bei dieser Fragestellung ist Häufigkeit nur ein Zwischenschritt in der Berechnung.
Für das Endergebnis muss man in Spalte C die Summe der darunter liegenden Zellen bilden, also in
C1 bis C700: = Summe(B2:B$701)
Oder da wir ja effizient rechnen wollen
C1 bis C700: =B2+C2
Gruß Daniel
Anzeige
AW: in Bezug zu Deinem vorherigen Beitrag ...
24.07.2021 18:05:41
neopa
Hallo Daniel,
... passt das aber mE so noch nicht ganz. Denn in Spalte B hattest Du eine Hilfsspalte mit Zahlen von 1 bis 700 und in Spalte C eine plurale Matrixformel mit Bezug auf Spalte B. Insofern verstehe ich Deine jetzige 1. Formelangabe für C1 bis C700: = Summe(B2:B$701) nicht.
Deine jetzige 2. Formel: würde ich nun so interpretieren, dass Du in D1 (nicht C1, denn in Spalte C steht ja Deine Matrixformel) folgende Formel schreiben wolltest: =C1+D2 und diese nach unten kopierst. Oder Du hast zuvor auf die Hilfsspalte in Spalte B verzichtet und dort die plurale Matrixformel: {=HÄUFIGKEIT(A1:A800000;ZEILE(A1:A700))} eingesetzt und die Addition in Spalte C wie angegeben vorgenommen.
Allerdings werden so Zahlen &lt=1 mit ausgewertet. Insofern müsste die Addition erst ab Zeile 2 beginnen mit =B2+C3 und diese nach unten kopieren. Die dann so vorgenommene Kombination plurale Matrixfomel plus die zusätzliche Endergebnisspalte mit einer einfachen Summenbildung dürfte dann sicherlich insgesamt schneller als meine hilfsspaltenfreie singuläre Formellösung sein.
Gruß Werner
.. , - ...
Anzeige
AW: in Bezug zu Deinem vorherigen Beitrag ...
24.07.2021 21:43:10
Daniel
Ersetze Spalte C durch D.
AW: in Bezug zu Deinem vorherigen Beitrag ...
24.07.2021 23:20:39
Frank
Hallo Ihr beiden,
also Daniel's Lösung hat schon wunder bewirkt (musste ich anpassen wie er schon schrieb, konnte Werte aber genau so zusammensetzen wie mit zählenwenn), hier mal die Vergleichszeiten:
Spalte C1 bis C700 Ergebnisse und A1 bis A800000 Werte:
C1=zählenwenn(A1:A800000;"gr.1") (und das dann 700mal, also von C1 bis C700) : Dauer: 20 Sekunden
Daniel's Lösung in Spalte C1 bis C700:
{=häufigkeit(A1:A800000;B1:B700)} : Dauer 2-3 Sekunden (also 80-90% schneller) (mit Shift+Strg+Enter abschließen)
Man muss aber dazu sagen, dass ich nicht weiß ob Daniel's Lösung auch z.B. bei Kommazahlen funktioniert. Bei mir wird ja genau nach einer bestimmten Zahl gesucht, da ich in A exakt die gesuchten Werte habe (1,2,3,4 usw.), daher funktioniert der "Trick" mit Spalte B (1,2,3,4,5,6,7,....) hervorragend bei mir in Bezug auf Häufigkeit. Wenn ich jetzt in A z.B 1,3 oder 5,45 hätte weiß ich nicht ob es funktionieren würde.
Werner's Lösung habe ich noch nicht ausprobiert, auch vielen Dank dafür! - Man merkt aber leider, dass Excel doch an seine Grenzen stößt bei größeren Berechnungen. Da muss man dann schon genau überlegen wie man Formeln formuliert oder eben VBA programmiert um Rechenleistung zu sparen.
Trotzdem ist Excel für mich unschlagbar. Danke für Eure Hilfe, Ihr seid Ehrenmänner
Anzeige
AW: dazu beachte noch ...
25.07.2021 09:39:33
neopa
Hallo Frank,
... dass die HÄUFIGKEIT()s-Formellösung allein noch nicht das von Dir angestrebte Ergebnis ergibt sondern noch der Addition mit der Hilfsspaltenformel bedarf. Doch beachte auch, dass der erste mit der HÄUFIGKEIT()s-Formel ermittelte Wert, die Anzahl der Werte für &lt=1 ist (siehe dazu auch mein Beitrag von gestern Abend).
Die zusätzliche Hilfsspaltenberechnung nimmt nur Bruchteile einer Sekunde in Anspruch und fällt bzgl. somit zeit mäßig nicht auf.
Mich würde nun interessieren, wie viel mehr Zeit meine beiden anderen Lösungen benötigen. Vielleicht könntest Du das mal testen.
Zu Deiner Fragen: Wenn Deine Auswertungen weiterhin immer im Vergleich zu Ganzzahlen stattfinden soll, dann ist es ob in Spalte A Ganzzahlen oder Dezimalzahlen stehen. Sollte aber Deine Ermittlung bezogen auf Dezimalzahlen erfolgen, dann müsstest Du eben diese in Spalte B einschreiben.
Gruß Werner
.. , - ...
Anzeige
AW: in Bezug zu Deinem vorherigen Beitrag ...
25.07.2021 15:54:34
Daniel
Mit dem zweiten Parameter definierst du Klassen
Dabei ist der jeweilige Zellwert die obere Grenze und der nächst kleinere Wert aus der Liste die untere Grenze der Klasse.
Das Ergebnis ist dann, wieviele Werte aus der Auflistung des ersten Parameters sich in der jeweiligen Klasse befinden, also zwischen oberer und unterer Grenze liegen (die obere Grenze gehört noch zur Klasse, dir untere nicht.
Gruß Daniel

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige