Clever-Excel-Forum

Normale Version: [LAMBDA] Diverse Helferlein
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Seiten: 1 2
ACCUM(Einzelwerte) in Zeile oder Spalte. Kumuliert einen Vektor.

=ACCUM({1;2;5;3}) ergibt {1;3;8;11}

=LAMBDA(b;SCAN(;b;LAMBDA(c;a;a+c))) benannt als ACCUM 

Nutzen: Wird zur Differenzenbildung benötigt, die viel effektiver ist, als Summierung. Beispiel: Ablesetabellen für das Subtrahieren von Wahrscheinlichkeiten (z.B. Binomialverteilung).


DECUM(kumulierteWerte) in Zeile oder Spalte. Entkumuliert einen Vektor.

=DECUM({1;3;8;11}) ergibt {1;2;5;3}

=LAMBDA(x;LET(d;SEQUENZ(ZEILEN(x));INDEX(x;d)-(d>1)*INDEX(x;d-1))) benannt als DECUM

Nutzen: Zeigt die Differenzen kumulierter Werte (Einzelwerte). Umkehrfunktion zu ACCUM.

Hinweis: Ich hätte gedacht, dass das auch mit SCAN geht (dort: a-c). Vielleicht schafft es ja einer. Bei mir kam nur Müll raus.


DIFF.FIRST(Spaltenwerte) eines Spaltenvektors. Zeigt die Differenz vom Datensatzfeld zu dessen Vorgänger.

=DIFF.FIRST({-1;-1;2;3;4;5;6;6;6;9}+(1&-22)) ergibt {44561;0;3;1;1;1;1;0;0;3}

=LAMBDA(x;LET(d;SEQUENZ(ZEILEN(x));INDEX(x;d)-(d>1)*INDEX(x;d-1)))  benannt als DIFF.FIRST

Nutzen: Man kann Differenzen von 0 als teilweises Duplikat eines Datensatzes auffassen und diese wegfiltern (FILTER), ohne dass es sich um echte Duplikate (da nur teilweise Duplikat) handelt. Der jeweils erste (FIRST) Datensatz von Wiederholern bleibt dann stehen.


DIFF.LAST(Spaltenwerte;Endwert) eines Spaltenvektors. Zeigt die Differenz vom Datensatzfeld zu dessen Nachfolger.

=DIFF.LAST({-1;-1;2;3;4;5;6;6;6;9}+(1&-22);) ergibt {0;3;1;1;1;1;0;0;3;1}

=LAMBDA(x;o;LET(d;SEQUENZ(ZEILEN(x));WENN(d<ZEILEN(x);INDEX(x;d+1);WENN(o;o;MAX(x)+1))-INDEX(x;d))) benannt als DIFF.LAST

Nutzen: Wie DIFF.FIRST, nur dass hier der letzte (LAST) Wiederholer stehen bleibt. Das zweite Argument o der Funktion kann mit einem Endwert vorbesetzt werden (den kann der Vektor nämlich nicht wissen, da der Nachfolger des letzten Satzes nicht bekannt ist!), oder es wird das Maximum+1 der Spaltenwerte genommen.


SHOW.FIRST(Spalteninhalte) zeigt Übereinstimmung vom Datensatzfeld zu dessen Vorgänger an.

Wie DIFF.FIRST, nur sind hier auch alphanum. Werte möglich. Ausgabevektor daher mit WAHR und FALSCH.

=LAMBDA(x;LET(d;SEQUENZ(ZEILEN(x));INDEX(x;d)<>(d>1)*INDEX(x;d-1))) benannt als SHOW.FIRST


SHOW.LAST(Spalteninhalte;Endwert) zeigt Übereinstimmung vom Datensatzfeld zu dessen Nachfolger an.

Wie DIFF.LAST, nur sind hier auch alphanum. Werte möglich. Ausgabevektor daher mit WAHR und FALSCH.

=LAMBDA(x;o;LET(d;SEQUENZ(ZEILEN(x));WENN(d<ZEILEN(x);INDEX(x;d+1);WENN(o;o;MAX(x)+1))<>INDEX(x;d))) benannt als SHOW.LAST


CELL.COL(Einzelzelle) ergibt einen dynamischen Spaltenvektor, ausgehend von der Zelle

=CELL.COL(A1) ergibt A1:A9, wenn außer diesen 9 Einträgen ohne Lücke keine Spalteneinträge vorliegen.

=LAMBDA(b;LET(f;INDEX($A:$XFC;;SPALTE(b));INDEX(f;SEQUENZ(ANZAHL2(f);;ZEILE(b))))) benannt als CELL.COL

Nutzen: =CELL.COL(A1) erlaubt eine kürzere Schreibweise als =A1:INDEX(A:A;ANZAHL2(A:A))


CELL.ROW(Einzelzelle) ergibt einen dynamischen Zeilenvektor, ausgehend von der Zelle

=CELL.ROW(A2) ergibt A2:G2, wenn außer diesen 7 Einträgen ohne Lücke keine Zeileneinträge vorliegen.

=LAMBDA(b;LET(f;INDEX($A:$XFC;ZEILE(b););INDEX(f;SEQUENZ(;ANZAHL2(f);SPALTE(b))))) benannt als CELL.ROW

Nutzen: =CELL.ROW(A1) erlaubt eine kürzere Schreibweise als =A1:INDEX(1:1;ANZAHL2(1:1))


RANGE.LONGESTCOL(EinzeiligerRange) ergibt einen dynamischen Zeilenbereich bis vor die erste Leerzeile

=RANGE.LONGESTCOL(N3:Q3) ergibt einen dynamischen Bereich von N3:Qx, wobei x+1 die erste Leerzeile in den Spalten N:Q nach der Zeile 3 darstellt. Der Unterschied zu .CurrentRegion liegt in den anderen 3 Seiten des Ranges (oben, links und rechts), die hier nicht beachtet werden.

=LAMBDA(d;LET(b;INDEX($A:$XFC;SEQUENZ(9999;;ZEILE(d));SPALTE(d));
INDEX(b;SEQUENZ(VERGLEICH(;NACHZEILE(b;LAMBDA(b;SUMME(LÄNGE(b))));)-1);SEQUENZ(;SPALTEN(d)))))
benannt als RANGE.LONGESTCOL

Anmerkung: Die 9999 lässt die Funktion möglichst schnell rechnen. Sind mehr Datensätze vorhanden, kann die Zahl vergrößert und die Funktion damit verlangsamt werden.


_________________________________________________
Anmerkungen zu diesen Funktionen: Vermutlich kann eine der MS-LAMBDA-Helper-Funktionen (die ich noch nicht alle ausprobiert oder verstanden habe) hier noch abkürzen oder beschleunigen. Oder auch schlicht ein anderer Ansatz? Es würde mich freuen, das in diesem Thread zu lesen. - Was fällt mir sonst so auf? Manchmal reicht in den Definitionen von LET und LAMBDA =INDEX(A1:Z99;;5) aus, manchmal geht nur =INDEX(A1:Z99;SEQUENZ(ZEILEN(A1:Z99));5). Das System dahinter habe ich noch nicht verstanden.

Die DIFF.- und SHOW.-Funktionen sind - neben den Differenzinformationen - dafür da, dass man beim FILTERn - anders als bei EINDEUTIG() - noch weiß, welcher der Datensätze bestehen bleibt, etwa durch Nummernvergabe.

Angeregt durch diesen Thread: clever-excel-forum.de/Thread-LAMBDA-NACHZEILE-kann-anscheinend-nur-ein-Feld
Ich muss grad grinsen: DIFF.FIRST und DECUM sind identisch.
Moin,

schöne Funktionen!

PS: und Danke für den Hinweis mit WAHL.

Gruß
(15.02.2022, 12:25)LCohen schrieb: [ -> ]DECUM(kumulierteWerte) in Zeile oder Spalte. Entkumuliert einen Vektor.

=DECUM({1;3;8;11}) ergibt {1;2;5;3}

=LAMBDA(x;LET(d;SEQUENZ(ZEILEN(x));INDEX(x;d)-(d>1)*INDEX(x;d-1))) benannt als DECUM

Nutzen: Zeigt die Differenzen kumulierter Werte (Einzelwerte). Umkehrfunktion zu ACCUM.

Hinweis: Ich hätte gedacht, dass das auch mit SCAN geht (dort: a-c). Vielleicht schafft es ja einer. Bei mir kam nur Müll raus.
Wäre es nicht logischer wenn das Ausgabe-Array ein Element weniger hat?
Beispiel Stromzähler: Die Liste beginnt mit der ersten Ablesung. Weitere Ablesungen folgen. Ich möchte nun den täglichen Verbrauch ermitteln.
Arbeitsblatt mit dem Namen 'Tabelle1'
ABCD
1DatumWert
201.01.2020852852
302.01.20208564
403.01.2020857,651,65
504.01.2020860,482,83
605.01.2020861,881,4
706.01.2020862,570,69
807.01.2020867,314,74
908.01.2020870,883,57
1009.01.2020871,610,73
1110.01.2020872,641,03
1211.01.2020872,90,26
1312.01.2020873,420,52
1413.01.2020873,660,24
1514.01.2020874,691,03
1615.01.2020879,414,72
1716.01.2020882,272,86
1817.01.2020883,060,79
1918.01.2020884,081,02

ZelleFormel
D2=DECUM(B2:B19)
Verwendete Systemkomponenten: [Windows (32-bit) NT 10.00] MS Excel 2016
Diese Tabelle wurde mit Tab2Html (v2.6.2) erstellt. ©Gerd alias Bamberg
DECUM() zeigt dann an erster Stelle einen sehr großen Wert gefolgt von vielen kleinen Werten.
Das ist doch eine allgemeine Funktion. Die kann nicht dafür verantwortlich sein, ob sie auf höherem Zählniveau einsteigt, oder ganz am Anfang einer kumulierten Reihe (also mit einem durchschnittlich hohen ersten Schritt).

Also bleibt die Funktion selbst unangetastet (siehe jedoch unten). Man verschiebt sie halt bei Bedarf:

=DECUM(B2:19-B2) oder =DECUM(B2:19-B1)

Sogar ein extra Argument für das zweite B2 innerhalb von DECUM muss also sein.

Ich habe aber etwas Seltsames festgestellt (jetzt, wo Du geschrieben hast):

=DECUM({2;5;7;19}) ergibt zwar beim Markieren in der Statuszeile als Anzeige-Summe die korrekt erwartete 19 (also den letzten Wert, die Summe der Entkumulierung), aber =SUMME(DECUM({2;5;7;19})) ergibt -23. Keine Ahnung, warum. Schon bei SCAN hatte ich da ein Problem. Wer weiß - vielleicht haben wir sogar ein SPILL-Problem.
(13.03.2022, 22:23)LCohen schrieb: [ -> ]=DECUM(B2:19-B2)
OK, das wäre eine Alternative. Auf jeden Fall ergibt die Summe dann die Differenz zwischen erstem und letztem Wert wieder.
Es könnte aber sein dass in bestimmten Fällen es besser wäre das erste Element weg zu lassen.

(13.03.2022, 22:23)LCohen schrieb: [ -> ]aber =SUMME(DECUM({2;5;7;19})) ergibt -23.
Ich habe einfach mal probiert:
Code:
=SUMME(--DECUM({2;5;7;19}))
=SUMME(+DECUM({2;5;7;19}))
=SUMME(DECUM({2;5;7;19})*1)
=SUMME(DECUM({2;5;7;19})/1)
Toll, dass Du das gefunden hast. Verstehst Du das? Denn der Typ ist schon innerhalb der Funktion Zahl, nicht etwa Text. Ich kann also die Funktion von innen her nicht reparieren (es sei denn, ich fake irgendwas herum, was dort aber nicht hingehört).

Außerdem die Diskrepanz zwischen Anzeigesumme und Funktion Summe.

Sieht eher nach einem (weiteren) LAMBDA-Fehler aus, denn in XL Web gab es ja schon den Lokalisierungsfehler. Ich vermute keinen SPILL-Fehler.

@maninweb: Ein dringender Grund für eine Meldung, denn es gibt hier eklatante Rechenfehler. Es ist noch schlimmer, als das "100000 statt 65536-Problem" damals in XL2007.
(13.03.2022, 23:42)LCohen schrieb: [ -> ]Toll, dass Du das gefunden hast. Verstehst Du das?
Nein.
Ich könnte noch nicht mal sagen ob es durch LAMBDA() oder durch LET() kommt.
Oder durch den Namensmanager. Denn das funktioniert:
Code:
=SUMME(LAMBDA(x;LET(d;SEQUENZ(ZEILEN(x));INDEX(x;d)-(d>1)*INDEX(x;d-1)))({2;5;7;19}))
Mysteriös. Denn die Fehler bei XL Web enstanden gerade andersherum, nämlich bei nichtbenanntem LAMBDA. Hier anscheinend bei Benennung. 

LET scheidet als Ursache aus, denn wenn ich darauf in 

=LAMBDA(x;LET(d;SEQUENZ(ZEILEN(x));INDEX(x;d)-(d>1)*INDEX(x;d-1)))

verzichte, also

=LAMBDA(x;INDEX(x;
SEQUENZ(ZEILEN(x)))-(
SEQUENZ(ZEILEN(x))>1)*INDEX(x;
SEQUENZ(ZEILEN(x))-1))


verwende, bleibt die SUMME() falsch (und wird genauso durch -- usw. wieder richtig).

Ich habe vorsichtshalber Excel neu gestartet und ein blankes Blatt verwendet.

Also: Namensmanager.
Um der Beschreibung "Zeilen- oder Spaltenvektor" gerecht zu werden, muss DECUM

=LAMBDA(x;LET(d;SEQUENZ(ZEILEN(x));INDEX(x;d)-(d>1)*INDEX(x;d-1)))

übrigens richtig heißen:

=LAMBDA(x;LET(d;SEQUENZ(ZEILEN(x);SPALTEN(x));INDEX(x;d)-(d>1)*INDEX(x;d-1)))

Der Namensmanager-Fehler bleibt. Wird innerhalb eines LET einer Zelle das LAMBDA mehrfachverwendbar benannt ...

=LET(Decum;LAMBDA(x;LET(d;SEQUENZ(ZEILEN(x);SPALTEN(x));INDEX(x;d)-(d>1)*INDEX(x;d-1)));Decum({2.5.7.19}))

, ... ist das Ergebnis mit SUMME korrekt 19. Das ist der überzeugende Beweis der Fehlerquelle "Namensmanager".
Seiten: 1 2