Blog JSystems - uwalniamy wiedzę!
Blog JSystems - uwalniamy wiedzę!
W skróciePower Query to wbudowany w Power BI edytor przekształceń: dane czyścisz raz, a każde odświeżenie powtarza te kroki na nowych danych. Na tabelach Nordvelli ustawiamy typy kolumn, usuwamy duplikaty, anulujemy przestawienie kolumn, scalamy i dołączamy zapytania, a listę Zastosowane kroki traktujemy jak audyt.
Lekcja 4 z 28 bezpłatnego kursu Power BI, od pierwszego raportu do Fabric i Copilota, na jednym zestawie danych sieci Nordvella.
<-- Spis wszystkich lekcjiDane w prawdziwej firmie nigdy nie przychodzą czyste. W arkuszu Nordvella nazwy produktów mają spacje na brzegach, ceny są zapisane jako tekst z symbolem "zł", data zatrudnienia pracownika to napis zamiast daty, a budżet działa w układzie, w którym każdy miesiąc jest osobną kolumną. Power Query to wbudowany w Power BI edytor przekształceń, czyli narzędzie, w którym te problemy naprawiasz raz, a przy każdym odświeżeniu Power BI powtórzy te same czynności automatycznie na nowych danych. W tym rozdziale przejdziemy przez to na konkretnych tabelach Nordvelli: poukładamy typy kolumn, usuniemy duplikaty bez gubienia danych, zrobimy anulowanie przestawienia (unpivot) budżetu, połączymy sprzedaż z produktami przez scalanie (Merge) i sklejimy dwa arkusze przez dołączanie (Append), a na koniec pokażemy, jak Zastosowane kroki działają jak audyt całej pracy.
Z tej lekcji dowiesz się:
Pliki do tej lekcji
Gotowy efekt: plik Power BI Desktop w stanie z końca tej lekcji, z tymi samymi zapytaniami, modelem i stronami raportu, które widać na zrzutach.
Pobierz nordvella_04_power_query.pbix
Plik startowy: odgałęzienie przygotowane pod tę lekcję. Zawiera trzy zapytania z pliku Nordvella_
Pobierz nordvella_03_zabrudzony.pbix
Dane źródłowe:
Nordvella_
Nordvella_
Pobierz Nordvella_zabrudzony.xlsxPobierz Nordvella_dane.xlsx
Plik do pobrania: w tym rozdziale pracujemy na celowo popsutej wersji arkusza Nordvelli: Nordvella_
Co chcemy osiągnąć. Dane Nordvelli przychodzą w stanie, w jakim zapisali je ludzie i systemy: ceny jako tekst z symbolem waluty, pracownik zapisany dwa razy, budżet z miesiącami w osobnych kolumnach. Chcemy wiedzieć, gdzie je uporządkować, zanim trafią do modelu, i dlaczego właśnie tam.
Zanim wejdziemy w szczegóły, ustalmy jedną rzecz, która oddziela osobę pracującą w Power BI świadomie od tej, która klika w ciemno. Power Query siedzi przed modelem danych. Wszystko, co robisz w edytorze, dzieje się na etapie ładowania: dane wpadają ze źródła, przechodzą przez kolejne przekształcenia i dopiero wtedy trafiają do modelu, na którym potem liczysz miary w języku DAX. Jeśli coś da się naprawić przy wczytywaniu (na przykład zły typ kolumny albo śmieciowy wiersz), zawsze robimy to w Power Query, a nie łataniem w mierze DAX. Miara nie powinna sprzątać po brudnym źródle.
Edytor otworzysz na trzy sposoby, w zależności od tego, gdzie jesteś:
FaktBudzet_szeroki, na którym w dalszej części rozdziału pokażemy zamianę kolumn na wiersze. Przycisk Przekształć dane zamiast Załaduj to cała różnica: dane nie wpadają do modelu, tylko trafiają najpierw do edytora.
| Skąd otwierasz | Co klikasz | Kiedy tak robisz |
|---|---|---|
| Wstążka, karta Narzędzia główne | Przekształć dane | Tabele są już w modelu i chcesz je posprzątać |
| Okno Nawigator (podczas importu) | Przekształć dane zamiast Załaduj | Chcesz wyczyścić dane, zanim wpadną do modelu |
| Panel Dane, prawy przycisk na tabeli | Edytuj zapytanie | Wracasz do jednej konkretnej tabeli po imporcie |
Trzy wejścia do tego samego edytora Power Query. Efekt jest identyczny, różni się tylko punkt startowy i moment, w którym decydujesz się posprzątać dane.
Wskazówka: jeśli źródłem jest baza danych, wybieraj Przekształć dane już przy imporcie i filtruj tam, gdzie się da. Power Query potrafi wtedy przetłumaczyć część kroków z powrotem na zapytanie do bazy (mechanizm nazywa się zawijaniem zapytania, query folding), więc filtrowanie wykona serwer bazy, a nie Twój komputer. To zamienia ładowanie kilkuminutowe w kilkusekundowe.
Co chcemy osiągnąć. Przez całą lekcję czyścimy tabele Nordvelli w edytorze Power Query. Chcemy znać jego cztery obszary, żeby przy każdym kroku wiedzieć, gdzie kliknąć i gdzie sprawdzić efekt.
Okno edytora Power Query dzieli się na cztery obszary. Nauka Power Query to w dużej mierze nauka poruszania się między nimi, więc opiszemy każdy dokładnie tak, jak wygląda, gdy otworzysz go w pliku startowym tej lekcji i klikniesz zapytanie DimProdukty.
To lista wszystkich tabel i zapytań pomocniczych. Po zaimportowaniu Nordvelli zobaczysz tu dziewięć pozycji: FaktSprzedaz, DimKalendarz, DimProdukty, DimKategorie, DimSklepy, DimPracownicy, FaktBudzet, FaktSatysfakcja i FaktZwroty. W popsutej wersji arkusza dochodzi dziesiąta, FaktBudzet_szeroki, i to na niej pokażemy przekształcanie kolumn na wiersze. Plik startowy tej lekcji ma tylko trzy zapytania: DimProdukty, DimPracownicy i FaktBudzet_szeroki. FaktSprzedaz dołożysz sam w sekcji o scalaniu. Kliknięcie nazwy przełącza podgląd na tę tabelę. W tym miejscu tworzysz też foldery, żeby oddzielić tabele faktów od tabel wymiarów, kopiujesz zapytania i wyłączasz ładowanie zapytań pomocniczych, których nie chcesz mieć w modelu.
Środek okna to podgląd tabeli po wszystkich dotychczasowych krokach. Uwaga na jedną rzecz, która myli początkujących: Power Query pokazuje w podglądzie tylko fragment danych (domyślnie do 1000 wierszy), więc przy dużej tabeli pasek stanu na dole okna pokazuje na przykład LICZBA WIERSZY: 999+, a obok informację, że profilowanie kolumn opiera się na pierwszych 1000 wierszach. Przy małej tabeli, takiej jak DimProdukty, widzisz pełną liczbę: LICZBA KOLUMN: 16, LICZBA WIERSZY: 30. To normalne. Wszystkie przekształcenia i tak zadziałają na komplecie wierszy przy właściwym ładowaniu, na przykład na 108 675 wierszach FaktSprzedaz, którą dołożysz w sekcji o scalaniu, podgląd służy tylko do tego, żebyś widział efekt na bieżąco. W nagłówku każdej kolumny jest ikonka typu danych (na przykład 123 dla liczby całkowitej, kalendarzyk dla daty, ABC dla tekstu), a pod nagłówkiem cienki pasek jakości kolumny pokazujący, ile wartości jest poprawnych, pustych i błędnych.
Panel Zastosowane kroki po prawej to serce Power Query. Każda czynność, którą wykonasz, dopisuje się tu jako osobny krok z czytelną polską nazwą. Kliknięcie kroku pokazuje tabelę w tym momencie. To pozwala cofać się w czasie, sprawdzać, gdzie coś poszło nie tak, i edytować parametry pojedynczej operacji bez powtarzania całej pracy. Do tego panelu wrócimy w ostatniej sekcji, bo to on zamienia zwykłe klikanie w powtarzalny, audytowalny proces.
Nad podglądem jest pasek formuły. Pokazuje kod w języku M, czyli w języku, w którym Power Query zapisuje każdy krok. Nie musisz jeszcze pisać w nim ręcznie (temu poświęcamy osobny rozdział o języku M), ale warto od początku zerkać, co się w nim pojawia po każdym kliknięciu. Zobaczysz wtedy, że nawet zmiana typu jednej kolumny to konkretna funkcja z argumentami. Sprawdź to od razu: w zapytaniu DimProdukty kliknij ikonę ABC/123 w nagłówku kolumny ProduktID i wybierz Liczba całkowita. Poniżej pokazujemy, jak taki krok wygląda w pasku formuły, a pod nim ten sam rodzaj kroku dla kilku kolumn tabeli FaktSprzedaz.
Table.TransformColumnTypes(#"Nagłówki o podwyższonym poziomie",{{"ProduktID", Int64.Type}}). Pierwszy argument to nazwa poprzedniego kroku, drugi to lista par: kolumna i typ. Nagłówek ProduktID zmienił ikonę z ABC/123 (typ Dowolny) na 1²₃ (liczba całkowita), a pod nagłówkiem pojawił się rozkład wartości: 30 odrębnych, 30 unikatowych. Nic tu nie pisaliśmy ręcznie - to zapis kliknięcia, który Power Query odtworzy przy każdym odświeżeniu. Ten krok usuń teraz krzyżykiem przy jego nazwie: typy całej tabeli ustawimy w następnej sekcji, po usunięciu końcówki „zł" z cen.= Table.TransformColumnTypes(
Zrodlo,
{
{"DataID", Int64.Type},
{"CenaNetto", type number},
{"WartoscNetto", type number},
{"WartoscBrutto", type number},
{"CzyZwrot", Int64.Type}
}
)To dokładnie to, co Power Query zapisuje, gdy zmieniasz typy kilku kolumn naraz. Kolumna DataID to liczba całkowita (Int64.Type), kwoty to liczby dziesiętne (type number), a flaga zwrotu to też liczba całkowita, 1 dla zwrotu i 0 dla zwykłej sprzedaży (Int64.Type). Zostawiamy ją jako liczbę, bo na warunku CzyZwrot = 1 opierają się później wszystkie miary zwrotów. Nie musisz tego pisać ręcznie, ale gdy nauczysz się czytać pasek formuły, przestaniesz się bać kroków, których nie da się poprawić przez menu.
Zobacz też: Szkolenie Power BI - Desktop, DAX i Online + Copilot
Co chcemy osiągnąć. Ceny w tabeli DimProdukty przyszły z arkusza jako tekst z symbolem waluty, a z tekstu Power BI nie policzy sumy ani marży. Chcemy zamienić je na liczby i ustawić poprawne typy kolumn, zanim tabela trafi do modelu.
Najczęstszy błąd początkujących to zostawienie typów kolumn tak, jak zgadł je Power Query. To zgadywanie bywa błędne, zwłaszcza gdy dane przychodzą z Excela lub z pliku CSV. Weźmy realny przypadek: tabela DimProdukty ma kolumnę CenaNetto, ale w źródłowym arkuszu ktoś wpisał ceny jako tekst z symbolem waluty, na przykład "3 499,00 zł". Power Query zaimportuje to jako tekst i wtedy w modelu nie da się tego zsumować, a próba zmiany typu na liczbę da w całej kolumnie same błędy.
Zobaczmy, jak wygląda tabela DimProdukty po surowym imporcie, zanim cokolwiek zrobimy:
| Nazwa | Kategoria | CenaNetto (ABC/123, tekst) | DostepnyOd (ABC/123, tekst) |
|---|---|---|---|
| Laptop Kelvani Vela 13 | Komputery | 2 849,00 zł | 23.03.2022 |
| Laptop Kelvani Forta 14 | Komputery | 2 449,00 zł | 01.02.2022 |
| Laptop Kelvani Forta 15 | Komputery | 2 199,00 zł | 28.03.2022 |
Przed czyszczeniem: CenaNetto i DostepnyOd mają typ Dowolny (ikona ABC/123 w nagłówku), a w środku leży tekst. Nazwa ma spacje na początku lub końcu. W tym stanie nie da się liczyć sum ani filtrować po dacie.
Sprzątanie robimy krok po kroku. Najpierw kolumna tekstowa Nazwa. Zaznacz ją, wejdź na kartę Przekształć i kliknij Formatuj, a potem Przytnij (usuwa spacje z początku i końca) oraz Wyczyść (usuwa niewidoczne znaki sterujące, które potrafią wejść przy kopiowaniu z innych systemów). W podglądzie zniknie wcięcie przed "Laptop Kelvani Forta 14" i spacje po "Laptop Kelvani Forta 15".
Teraz cena. Nie zmieniaj od razu typu na liczbę, bo "zł" zablokuje konwersję. Najpierw usuń symbol: zaznacz kolumnę CenaNetto, kliknij prawym i wybierz Zamień wartości, w polu "Wartość do znalezienia" wpisz " zł" (ze spacją przed), a pole "Zamień na" zostaw puste. Dopiero teraz kliknij ikonę typu w nagłówku i wybierz Liczba dziesiętna. Przy imporcie z polskiego arkusza użyj wariantu Używając ustawień regionalnych i ustaw język polski, żeby przecinek został poprawnie rozpoznany jako separator dziesiętny. Analogicznie kolumnę DostepnyOd zmień na Data z ustawieniami regionalnymi polskimi, bo format dzień, miesiąc, rok inaczej zostanie odczytany na odwrót.
Ta sama tabela po czyszczeniu:
| Nazwa (tekst) | Kategoria | CenaNetto (1.2, liczba dziesiętna) | DostepnyOd (data) |
|---|---|---|---|
| Laptop Kelvani Vela 13 | Komputery | 2849 | 2022-03-23 |
| Laptop Kelvani Forta 14 | Komputery | 2449 | 2022-02-01 |
| Laptop Kelvani Forta 15 | Komputery | 2199 | 2022-03-28 |
Po czyszczeniu: CenaNetto to liczba dziesiętna (można sumować i mnożyć), DostepnyOd to data (można filtrować po roku i budować oś czasu), Nazwa bez zbędnych spacji. Dopiero taka tabela nadaje się do modelu.
Cała sekwencja w języku M wygląda tak. Nie musisz jej pisać, ale warto ją znać. Nazwy kroków skróciliśmy, a ostatni krok od razu ustawia też typ kolumny DostepnyOd i polskie ustawienia regionalne. Kod, który powstaje z samych kliknięć, z oryginalnymi nazwami kroków, zobaczysz w Edytorze zaawansowanym na końcu rozdziału:
let
Zrodlo = Excel.Workbook(File.Contents("C:\Kurs_PBI\Nordvella_zabrudzony.xlsx"), null, true),
DimProdukty = Zrodlo{[Item="DimProdukty", Kind="Sheet"]}[Data],
Naglowki = Table.PromoteHeaders(DimProdukty, [PromoteAllScalars=true]),
PrzycietaNazwa = Table.TransformColumns(Naglowki, {{"Nazwa", Text.Trim, type text}}),
WyczyszczonaNazwa = Table.TransformColumns(PrzycietaNazwa, {{"Nazwa", Text.Clean, type text}}),
UsunZl = Table.ReplaceValue(WyczyszczonaNazwa, " zł", "", Replacer.ReplaceText, {"CenaNetto"}),
TypyKolumn = Table.TransformColumnTypes(
UsunZl,
{{"CenaNetto", type number}, {"DostepnyOd", type date}},
"pl-PL"
)
in
TypyKolumnPułapka: jeśli po zmianie typu w kolumnie pojawią się wartości Error, to znaczy, że część wartości nie dała się przekonwertować (na przykład jedna cena miała literówkę). Nie usuwaj od razu całych wierszy. Kliknij prawym na kolumnę, wybierz Zamień błędy i wstaw wartość zastępczą lub null, a błędne wiersze obejrzyj filtrem, żeby zrozumieć, skąd się wzięły. Ślepe kasowanie błędów potrafi po cichu wyciąć realną sprzedaż.
Co chcemy osiągnąć. Lista pracowników Nordvelli ma mieć jeden wiersz na osobę, a w źródle pracownik po awansie występuje dwa razy. Chcemy usunąć duplikat tak, żeby został rekord z aktualnym stanowiskiem, a nie przypadkowy.
Usuwanie duplikatów wygląda banalnie: zaznaczasz kolumnę, klikasz Usuń duplikaty i gotowe. W praktyce to jeden z częstszych sposobów na po cichu zepsucie danych, bo Power Query zachowuje pierwszy napotkany wiersz w bieżącej kolejności. Kolejność zależy od poprzednich kroków, więc bez wcześniejszego sortowania trudno przewidzieć, który rekord zostanie, a który zniknie.
Weźmy realny scenariusz z Nordvelli. Chcemy zbudować listę pracowników unikalnych po kolumnie PracownikID, ale w źródle jeden pracownik pojawia się dwa razy, bo najpierw był na starym stanowisku, a potem awansował. Po awansie chcemy zachować rekord z nowym stanowiskiem, czyli z późniejszą DataZatrudnienia. Zobaczmy dane wejściowe:
| PracownikID | Pracownik | Stanowisko | DataZatrudnienia |
|---|---|---|---|
| 104 | Adam Zieliński | Kasjer | 2021-08-25 |
| 104 | Adam Zieliński | Kierownik Sklepu | 2024-09-01 |
| 118 | Łukasz Zieliński | Serwisant | 2021-07-24 |
Pracownik 104 występuje dwa razy: raz jako Kasjer z 2021 roku, raz jako Kierownik Sklepu po awansie we wrześniu 2024. Chcemy zachować ten drugi wiersz.
Pierwszy odruch jest taki: posortujmy tabelę tak, żeby wiersz do zachowania był na górze. W pliku zabrudzonym DataZatrudnienia jest tekstem, więc najpierw kliknij ikonę typu w jej nagłówku i wybierz Data. Potem klikasz strzałkę w nagłówku kolumny DataZatrudnienia, wybierasz Sortuj malejąco, potem zaznaczasz kolumnę PracownikID i klikasz Usuń duplikaty. Wygląda to na komplet i taką radę znajdziesz w większości poradników. Sprawdźmy, co naprawdę zostanie w tabeli.
Sortowanie nie jest gwarancją. Funkcja Table.Sort jest w Power Query leniwa, a Table.Distinct nie wymusza, żeby wynik sortowania został wcześniej policzony do końca. Silnik ma prawo przestawić obie operacje i zwrócić dowolny z duplikatów. Najgorsze w tym jest to, że na małym zbiorze zwykle trafia dobrze - błąd ujawnia się dopiero wtedy, gdy danych przybędzie, czyli zwykle na produkcji.
Lekarstwem jest wymuszenie materializacji przez Table.Buffer. Wejdź w Narzędzia główne, Edytor zaawansowany i opakuj posortowaną tabelę tą funkcją. W Twoim kodzie krok nazywa się #"Usunięto duplikaty" i zawiera Table.Distinct(#"Posortowano wiersze", {"PracownikID"}). Zmieniasz go na Table.Distinct(Table.Buffer(#"Posortowano wiersze"), {"PracownikID"}). To jedna zmiana w jednej linii, poniżej w skróconym zapisie:
let
Zrodlo = DimPracownicy,
Sortowanie = Table.Sort(Zrodlo, {{"DataZatrudnienia", Order.Descending}}),
BezDuplikatow = Table.Distinct(Table.Buffer(Sortowanie), {"PracownikID"})
in
BezDuplikatow
Jeśli wolisz nie dotykać kodu, jest droga bez Edytora zaawansowanego: Grupuj według kolumny PracownikID z operacją Wszystkie wiersze, a potem wyciągnięcie z każdej grupy wiersza z największą datą. Jest dłuższa w klikaniu, ale nie zależy od kolejności wierszy w ogóle, więc nie da się jej zepsuć w sposób pokazany wyżej.
Zwróć uwagę, że w kodzie funkcja Table.Distinct dostała listę kolumn definiujących unikalność ({"PracownikID"}). Gdyby nie podać żadnej kolumny, Power Query usuwałby tylko wiersze identyczne we wszystkich kolumnach naraz, a to zupełnie co innego. To druga pułapka: usunięcie duplikatów po całym wierszu prawie nigdy nie robi tego, czego chcesz w tabeli faktów, bo dwa różne zakupy tego samego produktu w tym samym dniu wyglądają identycznie, a to są dwie osobne transakcje.
Pułapka wielkości liter: Power Query porównuje tekst z rozróżnieniem wielkości liter. Jeśli w kolumnie Miasto masz raz "Kraków", a raz "kraków", to dla mechanizmu duplikatów są to dwie różne wartości i oba wiersze zostaną. Zanim usuniesz duplikaty po kolumnie tekstowej, ujednolić wielkość liter: zaznacz kolumnę, wejdź w Przekształć, Formatuj, Wielka litera każdego wyrazu. Wtedy Kraków i kraków staną się tym samym.
Co chcemy osiągnąć. Dział controllingu Nordvelli przysyła budżet z każdym miesiącem w osobnej kolumnie. Chcemy zamienić kolumny miesięcy na wiersze, żeby budżet dało się filtrować po miesiącu i zestawiać ze sprzedażą.
To jest przekształcenie, którego brak najczęściej blokuje ludzi w budowie raportu, a jednocześnie mało kto o nim wie na starcie. Wyobraź sobie, że dział controllingu Nordvella przysyła budżet w wygodnej dla oka formie: jeden wiersz na sklep, a każdy miesiąc jako osobna kolumna. Dla człowieka czytelne, dla Power BI kompletnie nieużywalne, bo nie da się z tego zrobić wykresu sprzedaży w czasie ani porównania budżet kontra wykonanie, gdy fakty mają jedną kolumnę wartości, a budżet dwanaście.
Układ szeroki, tak zwany budżet w formie tabeli przestawnej, wygląda tak:
| SklepID | Styczeń | Luty | Marzec |
|---|---|---|---|
| 1 | 844562,38 | 541013,21 | 691399,82 |
| 2 | 605922,59 | 339708,48 | 423760,28 |
Przed unpivot: budżet w układzie szerokim, miesiące są kolumnami. Dodanie kolejnego miesiąca oznaczałoby dokładanie kolumny, a każda miara musiałaby ją znać. To się nie skaluje.
Naprawa jest zaskakująco prosta. Zaznacz kolumnę, która ma zostać (tu SklepID), kliknij prawym i wybierz Anuluj przestawienie innych kolumn. Power Query zamieni wszystkie pozostałe kolumny miesięcy na dwie: Atrybut (nazwa miesiąca) i Wartość (kwota). Wybieramy wariant "innych kolumn" celowo, bo jest odporny na przyszłość: gdy dojdzie kolejny miesiąc, transformacja go po prostu wciągnie, bo reguła brzmi "wszystko oprócz SklepID", a nie "te konkretne dwanaście kolumn".
Po unpivot ta sama tabela wygląda tak, i dopiero teraz nadaje się do modelu jako tabela faktów budżetu:
| SklepID | Atrybut (Miesiac) | Wartosc (Budzet) |
|---|---|---|
| 1 | Styczeń | 844562,38 |
| 1 | Luty | 541013,21 |
| 1 | Marzec | 691399,82 |
| 2 | Styczeń | 605922,59 |
Po unpivot: układ wąski. Jedna kolumna wartości i jedna miara SUM(FaktBudzet_szeroki[Wartość]) obsłuży dowolną liczbę miesięcy. Ten kształt danych Power BI kocha, bo pozwala agregować i filtrować w czasie.
Zapis tej operacji w języku M jest jednolinijkowy, a warto go znać, bo funkcja Table.UnpivotOtherColumns bierze listę kolumn do zachowania i nazwy dwóch nowych kolumn:
let
Zrodlo = FaktBudzet_szeroki,
Odwrocone = Table.UnpivotOtherColumns(
Zrodlo,
{"SklepID"},
"Atrybut",
"Wartość"
),
TypBudzet = Table.TransformColumnTypes(Odwrocone, {{"Wartość", type number}})
in
TypBudzetWskazówka: operacja odwrotna nazywa się Przestaw kolumnę (pivot) i zamienia wartości z jednej kolumny z powrotem na osobne kolumny. Używasz jej rzadziej, głównie do przygotowania danych pod prezentację, ale gdy w źródle zamiast miesięcy jako kolumn masz na przykład kategorie oceny satysfakcji rozbite po kolumnach, pivot i unpivot to Twoje dwa podstawowe narzędzia do zmiany kształtu tabeli.
Co chcemy osiągnąć. Sprzedaż Nordvelli trzeba pogrupować po marce i kategorii produktu, a tabela transakcji ma tylko identyfikator produktu. Do tego sprzedaż za kolejne lata przychodzi w osobnych tabelach. Chcemy dołożyć brakujące kolumny z tabeli produktów i skleić lata w jedną tabelę, wiedząc, która operacja robi które z tych zadań.
To dwie operacje, które ludzie mylą najczęściej, bo obie "łączą tabele". Różnica jest fundamentalna. Scalanie (Merge) łączy tabele w bok: dokłada kolumny z drugiej tabeli na podstawie wspólnego klucza, dokładnie jak złączenie w SQL. Dołączanie (Append) łączy tabele w pion: układa je jedna pod drugą, zwiększając liczbę wierszy, a kolumny muszą się zgadzać. Poniższa infografika pokazuje tę różnicę na jednym obrazku.
Realny przypadek Nordvella. Tabela FaktSprzedaz ma tylko ProduktID, nie ma nazwy ani kategorii produktu. Chcemy pogrupować sprzedaż po marce i kategorii, więc potrzebujemy dołożyć kolumny z DimProdukty. W pliku startowym nie ma jeszcze zapytania FaktSprzedaz, więc najpierw je dodaj: na karcie Narzędzia główne kliknij Nowe źródło, Excel, wskaż Nordvella_
let
Zrodlo = FaktSprzedaz,
Scalone = Table.NestedJoin(
Zrodlo, {"ProduktID"},
DimProdukty, {"ProduktID"},
"DaneProduktu", JoinKind.LeftOuter
),
Rozwiniete = Table.ExpandTableColumn(
Scalone, "DaneProduktu",
{"Nazwa", "Kategoria", "Marka"},
{"Nazwa", "Kategoria", "Marka"}
)
in
RozwinieteEfekt: FaktSprzedaz zyskuje trzy nowe kolumny, liczba wierszy się nie zmienia (dalej 108 675), a każdy wiersz sprzedaży wie już, jaki to produkt. Ważna uwaga wydajnościowa: w modelu gwiazdy, który zbudujemy w rozdziale o modelu danych, zazwyczaj nie scalasz wymiarów do faktów na stałe. Zamiast tego zostawiasz osobne tabele i łączysz je relacją, bo to daje mniejszy i szybszy model. Scalanie robisz wtedy, gdy naprawdę potrzebujesz kolumny obliczeniowej opartej na danych z dwóch tabel już na etapie ładowania.
Drugi realny przypadek. Załóżmy, że sprzedaż Nordvelli za 2025 i 2026 przyszła w dwóch osobnych arkuszach o identycznym układzie kolumn. Chcesz jedną tabelę faktów obejmującą oba lata. Do tego służy dołączanie. W pliku ćwiczeniowym sprzedaż obu lat leży w jednym arkuszu, więc najpierw przygotuj dwie osobne tabele. Kliknij prawym przyciskiem zapytanie FaktSprzedaz na liście zapytań i wybierz Odwołanie. Power Query doda zapytanie FaktSprzedaz (2). W panelu Ustawienia zapytania, w polu Nazwa, zmień jego nazwę na Sprzedaz2025 i zatwierdź klawiszem Enter.
= FaktSprzedaz, a w Zastosowanych krokach jest tylko Źródło. Każda zmiana w FaktSprzedaz, na przykład kolumny dołożone scalaniem, przejdzie automatycznie do odwołania.Teraz zawęź Sprzedaz2025 do jednego roku. Kliknij strzałkę w nagłówku kolumny DataID, wybierz Filtry liczb, a potem Między. W oknie Filtrowanie wierszy wpisz 20250101 w pierwszym polu i 20251231 w drugim, zostaw zaznaczone Oraz i kliknij OK.
Tak samo, przez Odwołanie do FaktSprzedaz, zbuduj Sprzedaz2026 z zakresem od 20260101 do 20261231. Teraz wchodzisz na Narzędzia główne, klikasz strzałkę przy Dołącz zapytania i wybierasz Dołącz zapytania jako nowe. Zostawiasz zaznaczone Dwie tabele, w polu Pierwsza tabela wskazujesz Sprzedaz2025, a w polu Druga tabela Sprzedaz2026.
Po kliknięciu OK Power Query ułoży obie tabele jedna pod drugą, dopasowując kolumny po nazwie, i doda nowe zapytanie Dołączanie1. Zmień jego nazwę na Sprzedaz2025_2026. Wszystkie trzy nowe zapytania to ćwiczenie, a nie nowe tabele do modelu, bo FaktSprzedaz ma już sprzedaż ze wszystkich lat. Kliknij każde z nich prawym przyciskiem na liście zapytań i odznacz Włącz ładowanie, żeby model nie dostał drugiej kopii tych samych wierszy.
Table.Combine({Sprzedaz2025, Sprzedaz2026}). Nazwy Sprzedaz2025, Sprzedaz2026 i Sprzedaz2025_2026 są zapisane kursywą, bo mają wyłączone ładowanie: zostają w edytorze, ale nie trafiają do modelu. Podgląd zaczyna się od pierwszych transakcji z 1 stycznia 2025 (DataID 20250101).Ten sam krok w kodzie M wygląda tak:
let
Polaczone = Table.Combine({Sprzedaz2025, Sprzedaz2026})
in
PolaczonePułapka dołączania: dopasowanie kolumn odbywa się po nazwie, nie po pozycji. Jeśli w jednym arkuszu kolumna nazywa się "WartoscNetto", a w drugim "Wartosc Netto" ze spacją, Power Query potraktuje je jako dwie różne kolumny i zamiast jednej scalonej kolumny dostaniesz dwie, każda w połowie wypełniona null. Zanim dołączysz, upewnij się, że nazwy i typy kolumn są identyczne w obu tabelach.
Krótkie zestawienie, kiedy sięgasz po którą operację, jako ściągawka do zapamiętania:
| Sytuacja Nordvella | Operacja |
|---|---|
| Brakuje kolumn (sprzedaż ma ProduktID, chcę Nazwę i Markę) | Scalanie (Merge) |
| Brakuje wierszy (sprzedaż 2025 i 2026 w dwóch arkuszach) | Dołączanie (Append) |
| Chcę dopisać nazwę miasta do zwrotów po SklepID | Scalanie (Merge) |
| Chcę zebrać ankiety satysfakcji z kilku plików w jedną tabelę | Dołączanie (Append) |
Co chcemy osiągnąć. Czyszczenie danych Nordvelli ma się powtarzać samo przy każdym odświeżeniu, a inna osoba w zespole ma umieć sprawdzić, co zrobiliśmy z danymi. Chcemy wykorzystać listę Zastosowane kroki jako taki zapis i nadać krokom nazwy, które mówią, co robią.
Wracamy do panelu, od którego zaczęliśmy. Zastosowane kroki to nie jest tylko wygodna lista cofania. To pełny, powtarzalny dziennik audytu Twojej pracy z danymi. Każdy krok ma nazwę, kolejność i parametry, a Power Query odtworzy tę sekwencję za każdym razem, gdy odświeżysz dane. Dzięki temu proces czyszczenia Nordvella, który raz zbudujesz, działa sam co miesiąc na nowej porcji sprzedaży, bez ręcznego powtarzania.
Na zrzutach wyżej kroki tabeli DimProdukty mają nazwy nadane automatycznie przez Power Query, na przykład Przycięto tekst czy Zamieniono wartość. Warto zmieniać je na krótsze i mówiące, co dany krok robi, przez prawy przycisk i Zmień nazwę. Po takich zmianach lista może wyglądać tak, jak w tym zestawieniu:
| Kolejność | Nazwa kroku | Co robi |
|---|---|---|
| 1 | Źródło | Otwiera plik Nordvella_ |
| 2 | Nawigacja | Wybiera z pliku arkusz DimProdukty |
| 3 | Podniesione nagłówki | Zamienia pierwszy wiersz na nazwy kolumn |
| 4 | Przycięta Nazwa | Usuwa spacje z brzegów kolumny Nazwa |
| 5 | Wyczyszczona Nazwa | Usuwa z kolumny Nazwa niewidoczne znaki sterujące |
| 6 | Usunięty symbol zł | Zamienia " zł" na pusty tekst w CenaNetto |
| 7 | Zmienione typy | Ustawia CenaNetto jako liczbę, DostepnyOd jako datę |
Na tym panelu wykonujesz kilka codziennych czynności, które warto opanować:
Gdy skończysz sprzątanie wszystkich zapytań tej lekcji, klikasz na wstążce Zamknij i zastosuj. Power Query wykona całą sekwencję kroków na pełnych danych i wczyta gotowe tabele do modelu. Od tej chwili każde kliknięcie Odśwież w raporcie powtórzy dokładnie ten sam proces na aktualnym pliku, a Ty nie dotykasz już Power Query, dopóki nie zmieni się struktura źródła. To jest właśnie ta różnica, o której mówiliśmy na wstępie: brudną robotę robisz raz, a maszyna powtarza ją zawsze.
Pułapka po anulowaniu przestawienia: w pliku startowym Power BI sam wykrył relację DimPracownicy[SklepID] wiele-do-jednego FaktBudzet_szeroki[SklepID], bo w układzie szerokim każdy SklepID występuje raz. Po anulowaniu przestawienia każdy sklep ma dwanaście wierszy, więc ładowanie przerwie się komunikatem, że kolumna „SklepID" w tabeli „FaktBudzet_szeroki" zawiera zduplikowaną wartość „1". Pozostałe tabele dostaną wtedy informację, że ładowanie anulowano z powodu błędu poprzedniej tabeli. Przyczyna leży w modelu, nie w zapytaniu: na karcie Modelowanie kliknij Zarządzanie relacjami, zaznacz tę relację, kliknij Usuń, potwierdź i kliknij Zastosuj zmiany. Dopiero wtedy wszystkie tabele lekcji wejdą do modelu.
Plik do pobrania: odtwórz wszystkie kroki tego rozdziału na tym samym pliku, na którym powstały zrzuty: Nordvella_
Masz już poukładane i wyczyszczone tabele. W następnym rozdziale zejdziemy o poziom niżej, do języka M, który kryje się za każdym z tych kroków, i pokażemy, jak pisać własne przekształcenia, których nie da się wyklikać z menu. A gdy dane będą gotowe, w rozdziale o modelu danych połączymy te dziewięć tabel relacjami w gwiazdę i zaczniemy liczyć miary.
Komentarze (0)
Brak komentarzy...