Blog JSystems - uwalniamy wiedzę!

Szukaj

Power BI - Model danych i relacje

Pusta wartość w fragmentatorze po relacji - wiersze faktów bez dopasowania w wymiarze

W skrócie

  • Pusta wartość we fragmentatorze Power BI, opisana jako (Puste), pojawia się, gdy tabela faktów ma klucze, których nie ma w tabeli wymiaru po stronie jeden relacji.
  • Silnik dokłada wtedy do wymiaru pusty wiersz, do którego trafiają wszystkie niedopasowane transakcje. To naruszenie integralności danych, a nie pusta wartość zapisana w wymiarze.
  • Znajdź brakujące klucze zapytaniem z EXCEPT albo miarą z RELATED i ISBLANK, a naprawę zrób w Power Query: dopisz brakujące pozycje do wymiaru albo popraw klucz w faktach.

Pusta wartość we fragmentatorze Power BI zaskakuje zwykle po odświeżeniu danych: lista sklepów albo produktów ma nagle pozycję (Puste), choć w tabeli wymiaru nie ma pustego wiersza. Trafia na to autor raportu, gdy system źródłowy dopisał do sprzedaży kod, którego słownik jeszcze nie zna. Pokazujemy, skąd bierze się ta pozycja, jak policzyć niedopasowane wiersze na modelu Nordvelli i jak naprawić dane, żeby kwota wróciła pod właściwą nazwę.

Jak to wygląda w praktyce

We fragmentatorze, na osi wykresu albo w wierszach macierzy pojawia się pozycja (Puste) z kwotą, a suma pozostałych pozycji jest mniejsza od sumy całości właśnie o tę kwotę. Filtr na pustą wartość w widoku tabeli wymiaru niczego nie znajduje, bo tego wiersza nie ma w danych wymiaru.

Na modelu Nordvelli takiej pozycji nie ma: miary Sieroty produktow, Sieroty sklepow i Sieroty dat z lekcji o modelu danych zwracają 0, a ten sam test dla zwrotów, budżetu i ankiet też daje 0. Żeby pokazać skalę zjawiska, policzyliśmy, co by się stało, gdyby z DimSklepy wypadł wiersz sklepu Nordvella Online, na przykład przez filtr w zapytaniu wymiaru. Pod pozycję (Puste) trafiłoby 32 737 transakcji za 141 772 848,59 zł, czyli ponad 30 procent sprzedaży sieci.

Dlaczego tak się dzieje

Według dokumentacji Microsoft relacja zwykła rozszerza tabelę po stronie wiele o kolumny strony jeden tak jak złączenie lewostronne. Gdy wartość klucza po stronie wiele nie ma pary po stronie jeden, silnik dodaje do tabeli wymiaru pusty wiersz wirtualny. Dokumentacja nazywa go nieznanym elementem (ang. unknown member) i wiąże wprost z naruszeniem integralności referencyjnej, czyli kluczem bez odpowiednika w wymiarze. Fragmentator pokazuje ten wiersz jako (Puste).

Typowe przyczyny to nowy kod w faktach, którego nie ma jeszcze w słowniku, ten sam kod zapisany inaczej po obu stronach (z zerami wiodącymi w jednej tabeli i bez nich w drugiej) oraz filtr w zapytaniu wymiaru, który usuwa pozycje nadal używane w faktach. Zera wiodące opisujemy w poście Power Query obcina zera wiodące w kodach. Funkcja VALUES zwraca pusty wiersz, a DISTINCT go pomija, co potwierdza dokumentacja funkcji VALUES. To przydaje się przy sprawdzaniu modelu.

Co zrobić krok po kroku

  1. Policz niedopasowane wiersze miarą z lekcji o modelu danych. RELATED zwraca pustą wartość, gdy wiersz faktów nie ma pary w wymiarze, a końcowe + 0 zamienia pusty wynik na zero. Dodaj ją w tabeli faktów przez Nowa miara i wstaw na kartę. Na Nordvelli wynik to 0. Taką miarę zrób dla każdego klucza każdej tabeli faktów.
    Sieroty produktow =
    COUNTROWS(
        FILTER(
            FaktSprzedaz,
            ISBLANK(RELATED(DimProdukty[ProduktID]))
        )
    ) + 0
  2. Wypisz brakujące klucze zapytaniem w widoku zapytań w języku DAX. EXCEPT zwraca wartości z pierwszej tabeli, których nie ma w drugiej. Na Nordvelli zapytanie zwraca pustą tabelę, czyli każdy SklepID ze sprzedaży ma swój sklep.
    EVALUATE
    EXCEPT(VALUES(FaktSprzedaz[SklepID]), VALUES(DimSklepy[SklepID]))
  3. Tak wygląda wynik, gdy klucza brakuje. W tym zapytaniu porównaliśmy sprzedaż z wymiarem bez sklepu numer 15: EXCEPT zwraca 15, a do brakującego klucza należy 32 737 transakcji za 141 772 848,59 zł. Tyle samo pokazałaby pozycja (Puste) we fragmentatorze sklepów.
    EVALUATE
    VAR WymiarBezOnline =
        SELECTCOLUMNS(FILTER(DimSklepy, DimSklepy[SklepID] <> 15), "SklepID", DimSklepy[SklepID])
    VAR Brakujace = EXCEPT(VALUES(FaktSprzedaz[SklepID]), WymiarBezOnline)
    RETURN
        ROW(
            "Brakujące klucze", CONCATENATEX(Brakujace, [SklepID], ", "),
            "Transakcje", COUNTROWS(FILTER(FaktSprzedaz, FaktSprzedaz[SklepID] IN Brakujace)),
            "Wartość", SUMX(FILTER(FaktSprzedaz, FaktSprzedaz[SklepID] IN Brakujace), FaktSprzedaz[WartoscNetto])
        )
  4. Obejrzyj same wiersze. W widoku tabeli zaznacz tabelę faktów, kliknij Nowa kolumna i wpisz tymczasowo Nazwa produktu = RELATED(DimProdukty[Nazwa]). W nagłówku nowej kolumny kliknij strzałkę, odznacz (Zaznacz wszystko), zaznacz (Puste) i kliknij OK. Zostaną transakcje bez produktu w wymiarze. Potem usuń kolumnę: prawy przycisk w panelu Dane i Usuń z modelu.
  5. Napraw przyczynę w Power Query: dopisz brakujące pozycje do zapytania wymiaru albo popraw klucz w zapytaniu faktów, jeśli to literówka lub inny format. Dopasowanie kluczy sprawdzisz przed załadowaniem, scalając fakty z wymiarem, co opisujemy w poście scalanie zapytań daje puste wartości po rozwinięciu.
  6. Gdy źródła nie da się poprawić od razu, nie chowaj pozycji (Puste) filtrem wizualizacji. Filtr wyklucza razem z nią kwotę tych transakcji, więc suma w raporcie spada. Lepiej dodać do wymiaru jawny wiersz, na przykład „Sklep nieprzypisany” z własnym kluczem, i w Power Query zamieniać na ten klucz wszystkie kody bez pary. Kwota zostaje wtedy w raporcie pod czytelną nazwą.

Jak sprawdzić, że problem zniknął

Po poprawce miary sierot znowu pokazują 0, a zapytanie z kroku 2 zwraca pustą tabelę. Drugi test porównuje VALUES i DISTINCT na kolumnie wymiaru. Na Nordvelli obie funkcje zwracają 15 sklepów, a sprzedaż pustego elementu jest pusta. Gdy VALUES zwraca o jedną pozycję więcej niż DISTINCT, model nadal ma pusty wiersz.

EVALUATE
ROW(
    "VALUES", COUNTROWS(VALUES(DimSklepy[Nazwa])),
    "DISTINCT", COUNTROWS(DISTINCT(DimSklepy[Nazwa])),
    "Sprzedaż pustego elementu",
        CALCULATE([Łączna sprzedaż], FILTER(VALUES(DimSklepy[SklepID]), ISBLANK(DimSklepy[SklepID])))
)

Trzymaj w raporcie stronę kontrolną z kartami sierot dla każdego wymiaru, tak jak w lekcji o modelu danych, i oglądaj ją po każdym odświeżeniu. Jeśli fragmentator pokazuje pozycje bez danych, a nie (Puste), przyczyna jest inna i opisujemy ją w poście fragmentator pokazuje wartości bez danych.

Strona kontrolna modelu w Power BI: trzy karty Sieroty produktow, Sieroty sklepow i Sieroty dat, każda pokazuje 0
Strona kontrolna Nordvelli z trzema kartami miar sierot. Trzy zera znaczą, że każda transakcja znajduje w wymiarach swój produkt, swój sklep i swoją datę.

Źródła i sposób sprawdzenia

  • Microsoft Learn: Model relationships in Power BI Desktop (Relationship evaluation, blank virtual row) (źródło)
  • Microsoft Learn: VALUES function (DAX) (źródło)
  • Microsoft Learn: EXCEPT function (DAX) (źródło)
  • Sprawdzone zapytaniami DAX na modelu Nordvelli: miary sierot dla wszystkich tabel faktów, EXCEPT kluczy, VALUES i DISTINCT, wymiar sklepów bez sklepu Nordvella Online.

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

Skąd się bierze pusta wartość we fragmentatorze Power BI?
Z wierszy tabeli faktów, których klucz nie ma pary w tabeli wymiaru. Silnik dodaje wtedy do wymiaru pusty wiersz wirtualny i przypisuje do niego wszystkie takie transakcje, a fragmentator pokazuje go jako (Puste). Przyczyną bywa nowy kod, którego słownik jeszcze nie zna, albo ten sam kod zapisany w innym formacie.
Jak znaleźć wiersze bez dopasowania w wymiarze w Power BI?
Zapytanie EVALUATE EXCEPT(VALUES(FaktSprzedaz[SklepID]), VALUES(DimSklepy[SklepID])) wypisuje klucze ze sprzedaży, których nie ma w wymiarze. Miara COUNTROWS(FILTER(FaktSprzedaz, ISBLANK(RELATED(DimProdukty[ProduktID])))) + 0 liczy takie wiersze. Na czystym modelu obie zwracają zero.
Czy można ukryć pozycję (Puste) we fragmentatorze?
Można ją odfiltrować, ale razem z nią z sumy znika kwota niedopasowanych transakcji. Lepiej naprawić dane w Power Query albo dodać do wymiaru jawny wiersz, na przykład Sklep nieprzypisany, i zamieniać na jego klucz kody bez pary.
Czym różni się VALUES od DISTINCT przy pustym wierszu w Power BI?
VALUES zwraca także pusty wiersz dodany przez silnik przy kluczach bez pary, a DISTINCT go pomija. Gdy VALUES na kolumnie wymiaru zwraca o jedną pozycję więcej niż DISTINCT, w modelu są niedopasowane wiersze faktów. Na modelu Nordvelli obie funkcje zwracają po 15 sklepów.

Komentarze (0)

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

Brak komentarzy...