Blog JSystems - uwalniamy wiedzę!

Szukaj

Power BI - Komunikaty błędów DAX

Wykryto zależność cykliczną w Power BI - kolumna obliczeniowa i relacje

W skrócie

  • Komunikat „Wykryto zależność cykliczną” w Power BI pojawia się, gdy kolumny obliczeniowe tej samej tabeli zależą od siebie nawzajem, na przykład gdy w tabeli faktów są dwie kolumny z CALCULATE albo z odwołaniem do miary.
  • CALCULATE w kolumnie obliczeniowej zamienia bieżący wiersz na filtr wszystkich kolumn tabeli, więc każda taka kolumna zależy od pozostałych, także od drugiej kolumny obliczeniowej.
  • Wartość wiersza licz bez CALCULATE, sumę grupy z ALLEXCEPT i listą kolumn grupujących, a wynik do wizualizacji przenieś do miary.

Pierwsza kolumna obliczeniowa z CALCULATE w tabeli faktów liczy się bez błędu, a po dodaniu drugiej Power BI zgłasza komunikat Wykryto zależność cykliczną. To samo dzieje się, gdy obie kolumny odwołują się do gotowych miar, i przy miarach, które odwołują się do siebie nawzajem. Wyjaśniamy, skąd bierze się ta zależność, dlaczego w tabeli wymiaru te same formuły działają i jak poprawić kolumny bez zmiany wyników.

Jak to wygląda w praktyce

Power BI Desktop pokazuje komunikat silnika w miejscu, w którym zgłasza błędy formuł, czyli pod paskiem formuły. Na modelu Nordvelli dodaliśmy do tabeli FaktBudzet (3600 wierszy budżetu: 15 sklepów, 4 kategorie, 60 miesięcy) dwie kolumny oparte na miarach [Budżet marży] i [Budżet sprzedaży]:

Marża budżetu % = DIVIDE([Budżet marży], [Budżet sprzedaży])
Koszt budżetu % = DIVIDE(SUM(FaktBudzet[BudzetKosztow]), [Budżet sprzedaży])

Gdy obie są w tabeli, silnik odpowiada dosłownie: „Wykryto zależność cykliczną: 'FaktBudzet'[Koszt budżetu %], 'FaktBudzet'[Marża budżetu %], 'FaktBudzet'[Koszt budżetu %].” (w angielskiej wersji: „A circular dependency was detected: 'FaktBudzet'[Koszt budżetu %], 'FaktBudzet'[Marża budżetu %], 'FaktBudzet'[Koszt budżetu %].”).

Lista w komunikacie zaczyna się i kończy tym samym obiektem, a pozycje pomiędzy to droga, którą biegnie cykl. Ten sam komunikat dotyczy miar: dla [Miara A] = [Miara B] + 1 i [Miara B] = [Miara A] + 1 dostaliśmy „Wykryto zależność cykliczną: 'FaktSprzedaz'[Miara A], 'FaktSprzedaz'[Miara B], 'FaktSprzedaz'[Miara A].”

Dlaczego tak się dzieje

Kolumna obliczeniowa ma kontekst wiersza, czyli zna wartości wszystkich kolumn bieżącego wiersza. CALCULATE, także to ukryte w każdej miarze, wykonuje przejście kontekstu: zamienia ten wiersz na kontekst filtra, czyli zestaw warunków nałożonych na każdą kolumnę tabeli. Dlatego Marża budżetu % zależy od wszystkich kolumn FaktBudzet, w tym od Koszt budżetu %, a ta z tego samego powodu od Marża budżetu %. Żadnej nie da się policzyć jako pierwszej. Sam mechanizm przejścia kontekstu opisujemy w poście kolumna obliczeniowa z CALCULATE liczy coś innego niż bez niej.

Znaczenie ma też miejsce tabeli w relacjach. Tabela DimSklepy jest po stronie jeden relacji z kluczem SklepID i ma już kolumnę Sprzedaż sklepu = CALCULATE(SUM(FaktSprzedaz[WartoscNetto])) z lekcji 14. Dopisaliśmy obok drugą, Marża sklepu z tym samym wzorcem, i obie policzyły się bez błędu (Nordvella Online: 141 772 848,59 zł sprzedaży i 19 703 618,62 zł marży). W FaktBudzet, po stronie wiele relacji, i w tabeli parametru Rabat proc bez żadnej relacji para kolumn z samym CALCULATE od razu dała zależność cykliczną. Jak działa relacja jeden do wielu, opisujemy w lekcji o modelu gwiazdy i relacjach.

Cykl może też przechodzić przez relację albo tabelę obliczeniową. Według dokumentacji Microsoft ulepszona walidacja zależności wykrywa cykle relacji, których wcześniej nie wykrywano, i część odświeżeń modeli w usłudze kończy się wtedy błędem zależności cyklicznej z tabelą obliczeniową. W tekstach Power BI Desktop 2.157 jest też ostrzeżenie (tylko po angielsku), że od 1 stycznia 2027 modele z zależnościami cyklicznymi nie będą przetwarzane.

Co zrobić krok po kroku

  1. Przeczytaj listę obiektów w komunikacie i znajdź je w panelu Dane. W przykładzie Nordvelli są to dwie kolumny tabeli FaktBudzet: Marża budżetu % i Koszt budżetu %. Gdy na liście są dwie miary, popraw tę, która nie powinna odwoływać się do drugiej.
  2. Sprawdź, czy kolumna naprawdę potrzebuje agregacji. Marża budżetu w jednym wierszu to iloraz dwóch kolumn tego samego wiersza, więc CALCULATE ani miara nie są potrzebne. Zaznacz kolumnę w panelu Dane i w pasku formuły zastąp jej formułę wersją bez CALCULATE, a drugą kolumnę popraw tak samo. W wierszu z budżetem 150 699,66 zł i marżą 17 444,51 zł dostaliśmy 11,58% marży i 88,42% kosztu, bez komunikatu o cyklu.
    Marża budżetu % = DIVIDE(FaktBudzet[BudzetMarzy], FaktBudzet[BudzetSprzedazy])
    
    Koszt budżetu % = DIVIDE(FaktBudzet[BudzetKosztow], FaktBudzet[BudzetSprzedazy])
  3. Gdy kolumna ma pokazywać sumę grupy, na przykład budżet sklepu w całym roku przy każdym miesiącu, zostaw CALCULATE, ale dodaj ALLEXCEPT. Ta funkcja usuwa filtry z tabeli poza wskazanymi kolumnami, więc kolumna zależy tylko od SklepID i Rok, a nie od innych kolumn obliczeniowych. Każdą formułę dodaj osobno: prawy przycisk na FaktBudzet w panelu Dane, Nowa kolumna. Obie kolumny razem liczą się bez błędu: dla Nordvella Warszawa Centrum w 2022 każdy z 48 wierszy pokazuje 6 850 503,31 zł budżetu i 1 277 897,78 zł budżetu marży.
    Budżet sklepu w roku =
    CALCULATE(
        SUM(FaktBudzet[BudzetSprzedazy]),
        ALLEXCEPT(FaktBudzet, FaktBudzet[SklepID], FaktBudzet[Rok])
    )
    
    Budżet marży sklepu w roku =
    CALCULATE(
        SUM(FaktBudzet[BudzetMarzy]),
        ALLEXCEPT(FaktBudzet, FaktBudzet[SklepID], FaktBudzet[Rok])
    )
  4. Gdy wynik ma się tylko wyświetlać w wizualizacji, zrób z niego miarę: prawy przycisk na FaktBudzet, Nowa miara. Miara liczy się w kontekście filtra wizualizacji i nie jest zapisywana w tabeli, więc kolumny obliczeniowe od niej nie zależą, dopóki same się do niej nie odwołują. Na modelu Nordvelli ta miara daje 17,11% dla całej sieci i 18,65% dla Nordvella Warszawa Centrum w 2022. Gdy wartość ma trafić do fragmentatora albo na oś, przeczytaj kiedy zamiast miary potrzebna jest kolumna albo parametr pól.
    Wskaźnik marży budżetu = DIVIDE([Budżet marży], [Budżet sprzedaży])
  5. Gdy w komunikacie jest tabela obliczeniowa albo kolumna, na której opiera się relacja, przejrzyj wymienione obiekty po kolei. Kolumnę klucza relacji licz z kolumn własnego wiersza, tak jak obliczeniowa DataID w FaktBudzet (FaktBudzet[Rok] * 10000 + FaktBudzet[Miesiac] * 100 + 1), na której opiera się relacja z DimKalendarz. Według dokumentacji Microsoft, gdy tabela obliczeniowa korzysta z SUMMARIZECOLUMNS, problem może rozwiązać jawny filtr wartości niepustych, a po zmianie trzeba sprawdzić wyniki modelu.

Jak sprawdzić, że problem zniknął

Po poprawce komunikat znika, a kolumny dostają wartości. Porównaj kolumnę z miarą na jednej grupie: na modelu Nordvelli Budżet sklepu w roku dla Nordvella Warszawa Centrum w 2022 to 6 850 503,31 zł, tyle samo co miara [Budżet sprzedaży] z filtrem na tym sklepie i roku. Ten sam wzorzec z ALLEXCEPT sprawdziliśmy w DimSklepy: suma kolumny po 15 sklepach to 467 775 009,17 zł, czyli tyle, ile miara [Łączna sprzedaż].

W kolumnach obliczeniowych tabel faktów nie odwołuj się do miar i nie używaj CALCULATE bez ALLEXCEPT, a obliczenia do wizualizacji trzymaj w miarach. Kolumny obliczeniowe według dokumentacji Microsoft są liczone przy przetwarzaniu modelu i zapisywane w pamięci, więc każda zbędna kolumna to dodatkowa praca przy odświeżeniu, o czym piszemy w poście o kolumnach obliczeniowych, które spowalniają odświeżanie.

Źródła i sposób sprawdzenia

  • Microsoft Learn: Model relationships in Power BI Desktop (sekcja Circular dependency issue) (źródło)
  • Microsoft Learn: CALCULATE function (DAX) (źródło)
  • Microsoft Learn: ALLEXCEPT function (DAX) (źródło)
  • Microsoft Learn: DAX overview (kontekst wiersza i kolumny obliczeniowe) (źródło)
  • Sprawdzone zapytaniami DAX na modelu Nordvelli: cykl w FaktBudzet i Rabat proc, brak cyklu w DimSklepy, poprawki bez CALCULATE, z ALLEXCEPT i z miarą.

Zachowanie programu sprawdziliśmy w Power BI Desktop 2.157 (wydanie z sierpnia 2026 r.) z polskim interfejsem, a przykłady na modelu sieci Nordvella z bezpłatnego kursu Power BI. Microsoft wydaje nową wersję Power BI Desktop co miesiąc, więc nazwy przycisków i limity usługi mogą się zmieniać. Aktualne wartości podaje dokumentacja Microsoft Learn.

Wróć do listy: 131 najczęstszych pytań i problemów związanych z Power BI

Najczęściej zadawane pytania

Co oznacza błąd wykryto zależność cykliczną w Power BI?
Dwie lub więcej kolumn, miar albo tabel zależy od siebie nawzajem, więc silnik nie wie, którą policzyć najpierw. Lista w komunikacie zaczyna się i kończy tym samym obiektem i pokazuje cały cykl. Przykładem są dwie kolumny obliczeniowe tabeli faktów z CALCULATE albo z odwołaniem do miary.
Dlaczego druga kolumna z CALCULATE daje zależność cykliczną?
CALCULATE w kolumnie obliczeniowej zamienia bieżący wiersz na filtr wszystkich kolumn tabeli, więc pierwsza kolumna zależy od drugiej, a druga od pierwszej. Na modelu Nordvelli taka para w tabeli FaktBudzet dała błąd, a w tabeli wymiaru DimSklepy, po stronie jeden relacji, liczyła się poprawnie.
Jak użyć ALLEXCEPT, żeby usunąć zależność cykliczną?
W CALCULATE dodaj ALLEXCEPT z tabelą i kolumnami, po których grupujesz, na przykład ALLEXCEPT(FaktBudzet, FaktBudzet[SklepID], FaktBudzet[Rok]). Kolumna zależy wtedy tylko od wskazanych kolumn i przestaje tworzyć cykl z innymi kolumnami obliczeniowymi. Wynik dla grupy jest taki sam jak suma z filtrem na tym sklepie i roku.
Czy zamiast kolumny obliczeniowej lepiej użyć miary?
Gdy wartość ma się tylko wyświetlać w wizualizacji, miara jest prostsza: liczy się w kontekście filtra wizualizacji i nie jest zapisywana w tabeli, więc kolumny obliczeniowe od niej nie zależą. Miara DIVIDE([Budżet marży], [Budżet sprzedaży]) daje na modelu Nordvelli 17,11% dla całej sieci. Kolumna zostaje potrzebna, gdy wartość ma być zapisana w każdym wierszu.

Komentarze (0)

Musisz być zalogowany by móc dodać komentarz. Zaloguj się przez Google

Brak komentarzy...