Mam stolik, w którym każda osoba ma zapis na każdy dzień roku. Użyłem tej funkcji do osiągnięcia sumy bieżącej na podstawie kolumny salda dziennego
CALCULATE(
SUM(Leave[Daily Balance]),
FILTER(
ALLEXCEPT(Leave, Leave[Employee Id]),
Leave[Date] <= EARLIER(Leave[Date])
))
ale potrzebuję sumy bieżącej, aby zrestartować od 1, jeśli Typ = Działający ORAZ bieżąca suma dziennego salda jest mniejsza niż zero ORAZ Typ poprzedniego rzędu nie jest równy Działającej. Poniżej zrzut ekranu z Excela. Potrzebna jest kolumna funkcji.
powerbi
dax
powerbi-desktop
LynseyC
źródło
źródło
Odpowiedzi:
Jest to nie tylko suma bieżąca z warunkiem, ale także zagnieżdżona / klastrowana, ponieważ logika musi być zastosowana na poziomie identyfikatora. W przypadku dużych tabel M jest w tym lepszy niż DAX, ponieważ nie zużywa tyle pamięci RAM. (Napisałem o tym tutaj blog: Link do Blogpost
Poniższa funkcja dostosowuje tę logikę do bieżącego przypadku i musi być zastosowana na poziomie identyfikatora: (Wymagane nazwy kolumn to: „Typ”, „Dzienny limit”, „Dostosowania”)
(MyTable as table) => let SelectJustWhatsNeeded = Table.SelectColumns(MyTable,{"Type", "Daily Allowance", "Adjustments"}), ReplaceNulls = Table.ReplaceValue(SelectJustWhatsNeeded,null,0,Replacer.ReplaceValue,{"Adjustments"}), #"Merged Columns" = Table.CombineColumns(ReplaceNulls,{"Daily Allowance", "Adjustments"}, List.Sum,"Amount"), TransformToList = List.Buffer(Table.ToRecords(#"Merged Columns")), ConditionalRunningTotal = List.Skip(List.Generate( () => [Type = TransformToList{0}[Type], Result = 0, Counter = 0], each [Counter] <= List.Count(TransformToList), each [ Result = if TransformToList{[Counter]}[Type] = "working" and [Result] < 0 and [Type] <> "working" then TransformToList{[Counter]}[Amount] else TransformToList{[Counter]}[Amount] + [Result] , Type = TransformToList{[Counter]}[Type], Counter = [Counter] + 1 ], each [Result] )), Custom1 = Table.FromColumns( Table.ToColumns(MyTable) & {ConditionalRunningTotal}, Table.ColumnNames(MyTable) & {"Result"} ) in Custom1
źródło
Przegląd
Jest to trudna sprawa, o którą prosi PowerBI, więc uporządkowane podejście może być trudne do znalezienia.
Największym problemem jest to, że model danych PowerBI nie obsługuje koncepcji liczenia działającego - przynajmniej nie tak, jak robimy to w Excelu. W programie Excel kolumna może odwoływać się do wartości występujących w „poprzednim wierszu” tej samej kolumny, a następnie być dostosowywana przez „dzienną zmianę” wymienioną w innej kolumnie.
PowerBI może to naśladować, sumując wszystkie codzienne zmiany w niektórych podzbiorach wierszy. Bierzemy wartość daty w naszym bieżącym wierszu i tworzymy filtrowaną tabelę, w której wszystkie daty są mniejsze niż data bieżącego wiersza, a następnie podsumowujemy wszystkie codzienne zmiany z tego podzbioru. Może się to wydawać subtelną różnicą, ale jest dość znacząca:
Oznacza to, że nie ma możliwości „zastąpienia” naszej sumy bieżącej. Jedyną matematyką, która jest wykonywana, jest kolumna zawierająca codzienne zmiany - kolumna zawierająca „sumę bieżącą” jest tylko wynikiem - nigdy nie jest używana w obliczeniach kolejnych wierszy.
Musimy porzucić koncepcję „resetu” i zamiast tego wyobrazić sobie utworzenie kolumny zawierającej wartość „korekty”. Nasza korekta będzie wartością, którą można uwzględnić, aby po spełnieniu opisanych warunków suma dziennych sald i korekt wyniosła 1.
Jeśli spojrzymy na obliczone wyniki podane przez OP, zobaczymy, że wartość naszej sumy bieżącej w dniu „niepracującym” tuż przed dniem „roboczym” daje nam potrzebną kwotę, która, jeśli zostanie odwrócona, wyniesie zero i spowodować, że suma bieżąca w każdym kolejnym dniu roboczym wzrośnie o jeden. To jest nasze pożądane zachowanie (z jednym problemem, który zostanie opisany później).
Wynik
Pomaga poznać różnicę między kontekstami wierszy i filtrów oraz sposób działania EARLIER w celu wykonania tego obliczenia. W tym scenariuszu możesz myśleć o „WCZEŚNIEJ” jako oznaczającym, że „to odniesienie wskazuje na wartość w bieżącym wierszu”, a w innym przypadku odniesienie wskazuje na całą tabelę zwróconą przez „ALLEXCEPT (Leave, Leave [Id]).” W tym w ten sposób znajdujemy miejsca, w których bieżący wiersz ma typ „Pracujący”, a wiersz z poprzedniego dnia ma inny typ.
Obliczenia imitują operację typu „wypełnij”. Mówi: „Patrząc na wszystkie wiersze, których data jest wcześniejsza niż data W TYM wierszu, zwróć największą wartość w polu„ Ostatnia data przed pracą ”.
Teraz, gdy w każdym wierszu znajduje się pole wyjaśniające, gdzie znaleźć saldo dzienne, które można wykorzystać jako naszą korektę, możemy po prostu spojrzeć w górę ze stołu.
I na koniec dostosowujemy naszą sumę bieżącą dla ostatecznego wyniku.
Problem
Podejście to nie rozwiązuje problemu zliczania, o ile bieżące saldo dzienne nie spadnie poniżej zera. Wcześniej udowodniono, że się mylę, ale powiedziałbym, że nie można tego osiągnąć w samym języku DAX, ponieważ powoduje to zależność cykliczną. Zasadniczo stawiasz wymaganie: użyj wartości zagregowanej, aby określić, co powinno zostać uwzględnione w agregacji.
To tyle, ile mogę ci przynieść. Mam nadzieję, że to pomoże.
źródło
Mam nadzieję, że następnym razem wkleisz plik csv lub kod, który generuje przykładowe dane zamiast obrazu. :)
Pozwól, że zasugeruję Ci wykonanie obliczeń w PowerQuery. Próbowałem podzielić kod na kilka kroków, aby poprawić czytelność. Może to wyglądać na nieco bardziej złożone, jednak działa dobrze. Wystarczy wkleić go w zaawansowanym edytorze, a następnie zastąpić źródło danymi źródłowymi. Powodzenia!
źródło
Myślę, że mam!
Oto wynik, bazując na rozwiązaniu, które opublikowałem wcześniej: (Dane zostały zmodyfikowane, aby pokazać więcej zachowań „praca / brak pracy” i przypadki użycia)
WYNIK
DETALE
(1) Zrzuć kolumny „Skorygowane saldo dzienne” i „Korekta dziennego salda”. Za chwilę uzyskamy ten sam wynik o jeden krok mniej.
(2) Utwórz następującą kolumnę (RDB = „bieżące saldo dzienne”) ...
Po utworzeniu „Ostatniej daty przed zakończeniem pracy” mamy w rzeczywistości element niezbędny do wykonania „resetu”, który, jak twierdziłem, był wcześniej niemożliwy. Filtrując to pole, mamy możliwość rozpoczęcia każdego wycinka od „1”
(3) Nadal mamy ten sam problem, nie możemy spojrzeć na wynik w naszej kolumnie i użyć go do podjęcia decyzji, co zrobić później w tej samej kolumnie. Ale MOŻEMY zbudować nową kolumnę dostosowania, która będzie przechowywać te informacje! Mamy już odniesienie do „Ostatniej daty przed pracą” - to ostatni dzień w poprzedniej grupie ... wiersz z potrzebnymi informacjami!
Więc patrzymy na ostatni dzień w każdej poprzedniej grupie i jeśli całkowita suma tych korekt ma wartość dodatnią, stosujemy ją, a jeśli jest ujemna, zamiast tego pozostawiamy ją w spokoju. Ponadto, jeśli pierwsze dni naszej osoby są dniami wolnymi od pracy, nie chcemy wcale tego początkowego ujemnego bitu w naszym dostosowaniu, więc również zostanie odfiltrowane.
(4) Ten ostatni krok doprowadzi dostosowanie do ostatecznego wyniku. Zsumuj dwie nowe kolumny i w końcu powinniśmy mieć nasz Skorygowany dzienny bilans salda. Voila!
Po drodze do tego wyniku zbudowaliśmy wiele dodatkowych kolumn, co zwykle nie jest moją ulubioną rzeczą. Ale to było trudne.
źródło
Trochę to zajęło, ale udało mi się wymyślić obejście. Zakładając, że wartość bilansowa dla pustych miejsc wynosi zawsze -1, a wartość wynosi 1 dla „Pracujących”, a dane są dostępne dla wszystkich dat bez odstępów, coś takiego jak poniższe obliczenie może działać:
Pamiętaj, że to może nie być gotowy produkt, ponieważ pracowałem z małą próbką, ale to powinno zacząć. Mam nadzieję że to pomoże.
źródło
Obliczenia są nieco długie, ale wydaje się, że działają w przykładowych danych, których używam. Wypróbuj to:
Użyłem tutaj wielu zmiennych. Być może uda ci się wymyślić krótszą wersję. Zasadniczo chodzi o to, aby znaleźć poprzednie pierwsze wystąpienie „Praca”, aby znaleźć od czego zacząć obliczenia. Jest to obliczane w zmiennej „Prev_Blank2”. Kiedy znamy punkt początkowy (zaczyna się tutaj od 1), możemy po prostu policzyć liczbę dni za pomocą „Working” lub blank () pomiędzy Prev_Blank2 a datą bieżącego rekordu. Korzystając z tych dni, możemy zwrócić końcową wartość dla sumy całkowitej.
Mam nadzieję, że to załatwi sprawę;)
źródło