Dlaczego puste wiersze i ukryte nagłówki psują import danych
Typowe objawy źle wczytanych nagłówków i pustych wierszy
Pierwszy sygnał, że coś jest nie tak z importem danych w Power Query, to dziwnie wyglądające kolumny: nazwy typu Column1, Column2, przesunięte dane lub nagłówki, które trafiły do pierwszego wiersza danych. Do tego dochodzą błędy typów danych – tam, gdzie miały być liczby, pojawiają się błędy lub teksty, a sumy w Power BI lub tabelach przestawnych nie zgadzają się z oczekiwaniami.
Jeżeli raport opiera się na imporcie z Excela, CSV lub innego systemu, problemy najczęściej wynikają z kilku wierszy „śmieci” na początku pliku. Widać je jako:
- tytuł raportu nad tabelą (np. „Raport sprzedaży za miesiąc X”),
- puste wiersze rozdzielające sekcje lub poprawiające wygląd arkusza,
- dodatkowe nagłówki powtarzające się co kilkadziesiąt wierszy,
- stopki lub informacje o generowaniu raportu (data, użytkownik, system).
Power Query nie rozumie koncepcji „formatowania raportu”. Odczytuje po prostu kolejne wiersze i kolumny. Jeśli pierwsze wiersze nie są prawdziwymi nagłówkami tabeli danych, mechanizm Użyj pierwszego wiersza jako nagłówków ustawi je jako nazwy kolumn, a właściwe nagłówki przesunie w dół. Stąd prosta droga do przesuniętych kolumn i błędów.
Skąd się biorą puste wiersze i „ukryte” nagłówki
Większość źródeł błędów to efekt działań ludzi oraz sposobu generowania raportów. Arkusze Excel przygotowane do „ładnego wydruku” zawierają:
- kilka pustych wierszy na górze dla logotypu lub tytułu,
- pogrubione nagłówki wizualne, które wcale nie są nagłówkami tabeli,
- komentarze typu „Dane w tysiącach złotych” wpisane w osobnych wierszach,
- linie oddzielające sekcje, np. wstawione myślniki lub kreski.
Eksporty z systemów ERP czy CRM również potrafią dodać wiersze „ozdobne”: informacje o użytkowniku, czasie generowania, nazwie filtra czy wersji systemu. Dla człowieka te linie są zrozumiałe. Dla Power Query – to po prostu dodatkowe wiersze tekstu na początku, które mogą zostać promowane do nagłówków lub wciągnięte jako dane.
„Ukryte nagłówki” to sytuacja, gdy faktyczna tabela danych ma nagłówek w innym miejscu niż 1. wiersz arkusza. Na przykład:
- nagłówki są w wierszu 5., a powyżej znajdują się tytuł, daty, komentarze,
- w raporcie jest kilka sekcji, każda ze swoim nagłówkiem, rozdzielone pustymi liniami,
- prawdziwe nazwy kolumn stoją nad kolorowym wierszem z podpisem typu „Tabela danych – zestawienie szczegółowe”.
Konsekwencje błędów przy dalszej analizie
Problemy z pustymi wierszami i nagłówkami rzadko wybuchają od razu. Często raporty działają „jakoś”, ale liczby przestają się zgadzać dopiero w Power BI, tabelach przestawnych lub dashboardach. Typowe konsekwencje:
- sumy i średnie liczone są tylko dla części danych, bo część wierszy ma błędny typ (np. tekst zamiast liczby),
- filtry raportu nie działają, bo zamiast „Region” pojawia się nagłówek z tytułem raportu,
- miary w DAX zwracają błędy z powodu kolumn typu „Any” z mieszanymi wartościami,
- dane grupują się pod dziwnymi etykietami, bo nazwy kolumn są inne w każdym imporcie.
Najgroźniejsza sytuacja to błędy, które są niewidoczne na pierwszy rzut oka. Na przykład jedna kolumna liczbowa ma w pierwszym wierszu tekst „Suma”, który po promocji do nagłówków ląduje jako nazwa kolumny. Wszystko wygląda poprawnie, ale w tle typ danych jest tekstowy, a wyliczenia działają błędnie lub są niepełne.
Prawdziwie puste wiersze kontra wiersze z niewidocznymi znakami
Z punktu widzenia Power Query istnieje istotna różnica między:
- wierszem, w którym komórki zawierają null (brak wartości),
- wierszem, w którym wpisano spację, myślnik, kropkę lub znak końca linii.
W Excelu oba wiersze wyglądają na puste, ale po imporcie do Power Query pierwszy będzie zawierał null, a drugi – konkretne znaki. Dlatego proste filtrowanie „Usuń puste” może nie wykryć wierszy, gdzie wpisano np. pojedynczy myślnik jako wizualny separator.
Dodatkowe zamieszanie wprowadzają znaki niewidoczne gołym okiem: spacje niełamliwe, tabulatory, znaki końca akapitu wklejone z innych systemów. Dla użytkownika raportu to „puste miejsce”, a dla Power Query – znak tekstowy. Jeśli reguły czyszczenia danych nie biorą tego pod uwagę, puste wiersze będą wciąż przenikać do modelu danych.
Jak Power Query widzi dane – baza do zrozumienia problemu
Domyślne zachowanie przy imporcie z Excela
Podczas importu z Excela Power Query oferuje kilka dróg:
- importowanie arkusza jako zakresu,
- importowanie tabeli (obiekt Excel Table),
- importowanie określonego zakresu nazw.
Przy imporcie arkusza Power Query zazwyczaj tworzy krok Promoted Headers (odpowiednik „Użyj pierwszego wiersza jako nagłówków”). Zakłada, że pierwszy wiersz zakresu to nagłówki. Jeżeli jednak nad tabelą znajdują się puste linie lub tytuły raportu, ten krok ustawia je jako nazwy kolumn.
Import tabeli Excel (Ctrl+T w arkuszu) jest zwykle bezpieczniejszy – nagłówki tabeli są jasno określone i znajdują się w pierwszym wierszu zakresu tabeli, nie arkusza. Wiele problemów z ukrytymi nagłówkami rozwiązuje już samo przekształcenie surowego arkusza w tabelę po stronie Excela.
Zakres vs tabela w Excelu a nagłówki w Power Query
Różnica między zakresem a tabelą jest kluczowa. Dla Power Query:
- Zakres – to po prostu prostokąt komórek. Power Query nie wie, które wiersze są nagłówkami, a które danymi. Domyślnie użyje pierwszego wiersza jako nagłówków, ale może to być błędne.
- Tabela – ma zdefiniowany nagłówek (pierwszy wiersz tabeli). Power Query importuje ją wraz z prawidłowymi nazwami kolumn, bez potrzeby zgadywania.
Jeżeli użytkownik otrzymuje pliki z systemów zewnętrznych, nie zawsze ma wpływ na ich strukturę. Mimo to, tam gdzie to możliwe, warto ustalać ze źródłem danych, aby dane trafiały do tabeli, a nie „luźnego” zakresu z dekoracyjnymi wierszami.
Jak Power Query traktuje null, zera, spacje i inne znaki
W Power Query null to specjalna wartość oznaczająca brak danych. Nie jest to to samo, co pusty ciąg znaków („”) ani spacja („ ”). Różnice:
- null – brak wartości, często widoczny jako „null” w podglądzie,
- „” – pusty tekst, formalnie nadal wartość tekstowa,
- „ ” – spacja, niewidoczna w podglądzie, ale nadal znak.
Proste filtrowanie „Usuń puste” w kolumnach tekstowych często usuwa null, ale nie pozbywa się spacji ani znaków specjalnych. W efekcie część wierszy, które wyglądają na puste, pozostaje w danych. Do wykrywania takich przypadków przydają się funkcje Text.Trim i Text.Length, o których więcej w dalszych krokach transformacji.
Różnica między podglądem danych a rzeczywistą zawartością
Podgląd danych w Excelu bywa mylący. Użytkownik widzi pustą komórkę, bo:
- czcionka jest biała na białym tle,
- kolumna jest bardzo wąska i tekst się nie mieści,
- komórka zawiera spacje lub inne niewidoczne znaki.
Power Query nie zwraca uwagi na formatowanie. Odczytuje surową wartość komórki. Dlatego w Power Query można zobaczyć „nagłe” teksty tam, gdzie w Excelu zdawało się, że nic nie ma. To ważne przy wykrywaniu ukrytych nagłówków i pustych wierszy, bo nie można opierać się wyłącznie na gołym widoku arkusza.
Bezpośrednio w edytorze Power Query można kliknąć komórkę i podejrzeć jej zawartość w dolnym panelu. Dzięki temu łatwo rozpoznać, czy w komórce jest rzeczywiście null, czy np. pojedyncza spacja albo myślnik.

Ręczne rozpoznawanie pustych wierszy i ukrytych nagłówków w przykładowym pliku
Scenariusz: raport z nagłówkiem w 5. wierszu
Wyobraźmy sobie typowy raport z systemu sprzedażowego. W arkuszu Excel użytkownik widzi:
- wiersz 1: „Raport sprzedaży – II kwartał”,
- wiersz 2: pusty,
- wiersz 3: „Wygenerowano dnia: …”,
- wiersz 4: pusty,
- wiersz 5: prawdziwe nagłówki danych: „Data”, „Region”, „Klient”, „Kwota”.
Power Query importując arkusz, utworzy tabelę, w której wiersz 1 trafi do pierwszego wiersza danych. Jeśli automatycznie włączy się krok Promoted Headers, nazwami kolumn staną się teksty z wiersza 1, a prawdziwe nagłówki z wiersza 5 zsuną się o kilka pozycji w dół jako zwykły wiersz danych. W efekcie model będzie działał na błędnych nagłówkach, a próba ustawienia typów danych na liczby może powodować błędy.
Analiza pierwszych wierszy w edytorze Power Query
Po wczytaniu arkusza dobrym nawykiem jest dokładne przejrzenie pierwszych kilku wierszy w edytorze. Warto sprawdzić:
- który wiersz zawiera faktyczne nazwy kolumn (takie jak „Data”, „Kwota”, „ID”),
- czy przed nim znajdują się jakiekolwiek wartości tekstowe lub puste wiersze,
- czy wiersz nagłówkowy jest jednorodny – wszystkie kolumny zawierają teksty, a nie liczby.
Jeśli w pierwszych wierszach pojawiają się tytuły, daty generowania raportu lub inne elementy ozdobne, trzeba założyć, że domyślne Promote Headers zadziała niewłaściwie. Zamiast akceptować ten krok, lepiej go usunąć i samodzielnie zdecydować, który wiersz ma zostać promowany do nagłówków.
Wiersze, które „udają” puste, ale zawierają znaki
Częsty problem to wiersze, które wizualnie wydają się puste, ale w rzeczywistości zawierają spacje lub znaki specjalne. Przykład:
- wiersz 2: w kolumnie A wstawiono pojedynczy myślnik „-” jako separator tytułu od reszty danych,
- wiersz 4: w kilku kolumnach są spacje, bo ktoś coś kiedyś wpisał i skasował, zostawiając przerwę.
W Power Query takie wiersze nie zostaną uznane za całkowicie puste. Próba usuwania „pustych wierszy” oparta jedynie na wartości null nie zadziała. Konieczne jest czyszczenie tekstu poprzez Text.Trim i sprawdzanie długości po przycięciu. Dopiero wtedy można skutecznie odsiać wiersze, które zawierają wyłącznie białe znaki lub znaki ozdobne.
Najpierw zrozum strukturę, potem automatyzuj
Przy pierwszym kontakcie z nowym raportem naturalna jest chęć od razu pisać skrypty M lub budować złożone transformacje. W praktyce lepsze efekty daje spokojne rozpoznanie struktury wejścia:
- ile wierszy nad nagłówkiem jest zawsze,
- czy nagłówki zawsze mają te same teksty,
- czy wiersze ozdobne mają stałe frazy, które można wykryć (np. „Raport sprzedaży” lub „Wygenerowano dnia”),
- czy raport bywa eksportowany w różnych układach, np. z dodatkowymi wierszami filtra.
Dopiero mając tę wiedzę, można tworzyć reguły, które będą stabilne przy kolejnych importach. Inaczej każdy nowy plik będzie wymagał ręcznego poprawiania kroków w Power Query, a cała automatyzacja straci sens.
Metody usuwania pustych wierszy – od prostych filtrów po warunki M
Proste filtrowanie w interfejsie: usuwanie null w kluczowej kolumnie
Najprostszą metodą czyszczenia pustych wierszy w Power Query jest użycie filtrów w interfejsie. Jeśli istnieje kolumna, która zawsze powinna być wypełniona dla poprawnych rekordów (np. ID, Data, Numer zamówienia), można:
Filtrowanie bezpośrednio w podglądzie
W oknie edytora Power Query, na nagłówku wybranej kolumny, można rozwinąć filtr i odznaczyć pozycję (null). To wystarczy, by pozbyć się rekordów bez wartości w tej kolumnie. Dobrze sprawdza się to przy raportach, w których:
- puste wiersze występują wyłącznie nad lub pod właściwą tabelą,
- kolumna kluczowa jest wypełniona dla każdego prawidłowego rekordu.
Dla prostych plików to często jedyny potrzebny krok. Wystarczy, że wiesz, że np. kolumna „Data” nigdy nie jest pusta dla prawidłowego wiersza. W bardziej niestabilnych raportach to dopiero początek – dalsze czyszczenie zwykle trzeba oprzeć o kilka kolumn jednocześnie.
Usuwanie wierszy, gdy wszystkie kolumny są puste (null)
Drugi prosty wariant to usunięcie wierszy, w których wszystkie kolumny mają wartość null. Można to zrobić z poziomu interfejsu:
- Zaznacz wszystkie kolumny (Ctrl+A w podglądzie tabeli).
- Kliknij prawym przyciskiem nagłówek dowolnej z zaznaczonych kolumn.
- Wybierz Usuń wiersze > Usuń puste wiersze.
Ten krok działa wyłącznie na wiersze całkowicie puste – jeśli w jednej z kolumn znajduje się spacja, myślnik albo inny znak, wiersz nie zostanie usunięty. W wielu organizacyjnych szablonach raportów to i tak daje dużą poprawę jakości, bo eliminuje ciągi pustych linii między blokami danych.
Gdy interfejs nie wystarcza: kolumna pomocnicza z warunkiem M
W bardziej złożonych raportach same filtry na jednej kolumnie nie rozwiązują problemu. Pomaga wtedy utworzenie kolumny warunkowej, która określi, czy dany wiersz należy uznać za pusty. Dzięki temu:
- logika „pustości” jest opisana w jednym miejscu,
- można ją łatwo rozwinąć lub poprawić przy kolejnych plikach,
- pozbywanie się wierszy jest kwestią prostego filtra „Zachowaj wartość = Prawda/Fałsz”.
Można to zrobić z interfejsu (Dodaj kolumnę > Kolumna niestandardowa) lub dopisać krok w M. Przykładowa logika:
- jeśli wszystkie istotne kolumny są null lub po przycięciu spacji mają długość zero, wiersz jest „pusty”,
- w przeciwnym razie traktujemy go jako właściwy rekord danych.
Kolumna z oceną „pustości” z użyciem Text.Trim i Text.Length
Praktycznym podejściem, znacznie skuteczniejszym niż gołe filtrowanie null, jest zbudowanie kolumny logicznej, która sprawdza kilka kolumn jednocześnie. Przykład prostego kodu M dla raportu z kolumnami „Data”, „Region”, „Klient”, „Kwota”:
= Table.AddColumn(
#"Poprzedni krok",
"WierszPusty",
each
let
dataTxt = if [Data] is null then "" else Text.Trim(Text.From([Data])),
regionTxt = if [Region] is null then "" else Text.Trim(Text.From([Region])),
klientTxt = if [Klient] is null then "" else Text.Trim(Text.From([Klient])),
kwotaTxt = if [Kwota] is null then "" else Text.Trim(Text.From([Kwota]))
in
Text.Length(dataTxt) = 0 and
Text.Length(regionTxt) = 0 and
Text.Length(klientTxt) = 0 and
Text.Length(kwotaTxt) = 0,
type logical
)W ten sposób:
- wszystkie wartości są zamieniane na tekst,
- Text.Trim usuwa spacje z początku i końca,
- Text.Length bada długość po przycięciu.
Wiersze z samymi spacjami, tabulatorami czy myślnikiem ostatecznie też można potraktować jako „puste” – wystarczy rozszerzyć warunek, np. wcześniej zamieniając myślniki na pusty tekst. Po dodaniu kolumny „WierszPusty” najłatwiej filtrować:
- rozwiń filtr na nagłówku „WierszPusty”,
- odznacz true (lub zaznacz false – zależnie od potrzeb),
- usuń pomocniczą kolumnę, jeśli nie jest znajom potrzebna dalej.
Rozszerzanie warunku o konkretne „śmieciowe” wzorce
W plikach, które ktoś ręcznie „upiększał”, często pojawiają się powtarzalne wzorce: linie z ciągiem „====” w jednej komórce, linie z napisem „Koniec raportu”, pojedyncze myślniki. Dla takich przypadków można ulepszyć warunek, dodając czyszczenie znaków specjalnych:
let
czyscTekst = (t as nullable text) as text =>
let
base = if t is null then "" else Text.Trim(t),
bezMinus = if base = "-" then "" else base,
bezRownych = if Text.Contains(bezMinus, "====") then "" else bezMinus
in
bezRownych
in
Table.AddColumn(
#"Poprzedni krok",
"WierszPusty",
each
let
kol1 = czyscTekst(Text.From([Kolumna1])),
kol2 = czyscTekst(Text.From([Kolumna2]))
in
Text.Length(kol1) = 0 and Text.Length(kol2) = 0,
type logical
)Co ważne, taka funkcja czyszcząca może być przenoszona między projektami – gdy raz ją przygotujesz, kolejne raporty o podobnej strukturze da się obsłużyć praktycznie kopiuj–wklej.
Usuwanie pustych wierszy od góry i od dołu tabeli
Zdarza się, że raport ma poprawne dane w środku, ale:
- na górze kilka–kilkanaście wierszy opisowych,
- na dole podsumowania, stopki, podpisy i dodatkowe tabele.
Jeśli nagłówki są zawsze w stałym wierszu, najprościej jest użyć Remove Top Rows i Remove Bottom Rows (z menu „Usuń wiersze”). Kiedy ich liczba się zmienia, lepiej posłużyć się regułą:
- szukamy pierwszego wystąpienia konkretnego tekstu (np. „Data” w kolumnie A),
- obcinamy wszystko, co jest powyżej,
- podobnie odcinamy dane od dołu, szukając tekstu „Koniec danych” czy innego przewidywalnego znacznika.
Przykład dla obcięcia wierszy powyżej nagłówka „Data” w pierwszej kolumnie:
let
ZNaglowkiem =
let
idx = List.PositionOf(#"Poprzedni krok"[Column1], "Data"),
// jeżeli nie znaleziono, nie obcinamy
startIndex = if idx < 0 then 0 else idx
in
Table.Skip(#"Poprzedni krok", startIndex)
in
ZNaglowkiemTakie podejście jest dużo odporniejsze na drobne zmiany – jeśli w pliku pojawi się dodatkowy wiersz opisu nad tabelą, logika nadal zadziała, bo szuka nazwy kolumny, a nie sztywnej liczby wierszy.
Połączenie filtrów: najpierw techniczne cięcie, potem „pustość”
Dobrą praktyką jest łączenie dwóch etapów:
- technicze cięcie – usunięcie z góry/dołu oczywiście zbędnych bloków (np. za pomocą
Table.SkipiTable.FirstNlub filtrów na charakterystycznych tekstach), - precyzyjne oczyszczanie – użycie kolumny „WierszPusty” opartej o Text.Trim i Text.Length do wyłapania reszty śmieciowych linii.
Takie dwustopniowe podejście obniża ryzyko, że przypadkiem usuniemy linie, które wizualnie wydawały się ozdobne, ale w niektórych wersjach raportu zawierają już sensowne dane.

Wykrywanie i promowanie właściwego wiersza do nagłówków
Dlaczego nie ufać automatycznemu Promote Headers
Domyślny krok Promoted Headers wstawiany przez Power Query bywa zdradliwy. Jeśli zostanie zastosowany zbyt wcześnie:
- „Raport sprzedaży – II kwartał” stanie się nazwą kolumny zamiast „Data” czy „Region”,
- prawdziwe nagłówki wylądują w pierwszym wierszu danych i zaczną mieszać się z rekordami,
- ustawienie typów danych będzie generować błędy lub „konwertować” nagłówki na null.
Ryzyko konflików i niespójnych danych rośnie szczególnie wtedy, gdy później łączysz kilka takich plików w jedną tabelę. Lepiej świadomie zadecydować, w którym momencie i który wiersz ma stać się nagłówkami.
Najpierw przycięcie, potem ręczny Promote Headers
Bezpieczny schemat pracy często wygląda tak:
- Wczytanie arkusza bez automatycznego promowania nagłówków (w Source odznaczyć „Użyj pierwszego wiersza jako nagłówków”, albo usunąć krok Promoted Headers).
- Usunięcie pustych/ozdobnych wierszy z góry i dołu oraz rozpoznanie właściwego wiersza nagłówków.
- Dopiero wtedy wykonanie kroku Użyj pierwszego wiersza jako nagłówków (lub
Table.PromoteHeadersw M).
Dzięki temu nie powstają „dziwne” nazwy kolumn, a ryzyko utraty nagłówków zamienionych na dane spada praktycznie do zera.
Identyfikacja wiersza nagłówkowego na podstawie wzorca tekstów
W praktyce wiersz z nagłówkami odróżnia się od pozostałych tym, że:
- zawiera same teksty (brak liczb czy dat),
- ma sensowne, powtarzalne nazwy („Data”, „Kwota”, „ID klienta”),
- powyżej niego pojawiają się pojedyncze teksty opisowe lub puste wiersze.
Jedna ze skutecznych technik to utworzenie kolumny pomocniczej, która dla każdego wiersza sprawdzi:
- czy wszystkie kolumny są tekstowe po konwersji,
- czy lista wartości z wiersza pokrywa się (choćby częściowo) z oczekiwanymi nazwami nagłówków.
Przykładowy wzorzec w M dla raportu z kolumnami: „Data”, „Region”, „Klient”, „Kwota”:
let
oczekiwaneNaglowki = {"Data", "Region", "Klient", "Kwota"},
DodajFlageNaglowka = Table.AddColumn(
#"Poprzedni krok",
"CzyNaglowek",
each
let
// zbierz wartości z całego wiersza jako listę tekstów
wartosci = List.Transform(Record.ToList(_), each if _ is null then "" else Text.Trim(Text.From(_))),
// policz, ile z nich pasuje do oczekiwanych nagłówków
trafienia = List.Count(List.Intersect({wartosci, oczekiwaneNaglowki}))
in
trafienia = List.Count(oczekiwaneNaglowki),
type logical
)
in
DodajFlageNaglowkaPo zastosowaniu takiego kroku wystarczy odszukać wiersz, w którym „CzyNaglowek” = true. To jest kandydat na nagłówki. Następnie można:
- przyciąć dane tak, aby ten wiersz był pierwszy,
- zastosować Table.PromoteHeaders.
Przycinanie tabeli do wiersza z nagłówkiem znalezionym algorytmicznie
Mając flagę „CzyNaglowek”, obcięcie tabeli od tego wiersza w dół jest stosunkowo proste:
let
// znajdź indeks pierwszego wiersza z CzyNaglowek = true
indeksNaglowka = List.PositionOf(#"DodajFlageNaglowka"[CzyNaglowek], true),
// jeżeli nie znaleziono, zostaw tabelę bez zmian
PrzyciętaTabela =
if indeksNaglowka < 0 then
#"DodajFlageNaglowka"
else
Table.Skip(#"DodajFlageNaglowka", indeksNaglowka),
// usuń kolumnę pomocniczą
BezFlagi = Table.RemoveColumns(PrzyciętaTabela, {"CzyNaglowek"}),
// promuj pierwszy wiersz jako nagłówki
ZNaglowkami = Table.PromoteHeaders(BezFlagi, [PromoteAllScalars = true])
in
ZNaglowkami
Taki schemat bywa wystarczająco stabilny nawet przy raportach z wieloma wersjami językowymi – o ile nazwy nagłówków na danym języku są stałe. Jeśli czasem dochodzi nowa kolumna, wystarczy dopisać ją do listy oczekiwaneNaglowki.
Wybieranie nagłówka na podstawie typu danych w kolumnach
Nie zawsze znamy nazwy kolumn z góry. Wtedy można podejść od innej strony: posłużyć się typami danych. Często:
- wiersze nagłówkowe – zawierają wyłącznie tekst,
- wiersze danych – zawierają liczby, daty, puste pola.
Można więc znaleźć pierwszy wiersz, w którym wszystkie komórki są tekstowe po konwersji. Przykład:
Szukanie wiersza nagłówków po „tekstowości” komórek
Gdy nazwy kolumn nie są z góry znane, ale tabela ma dość przewidywalną strukturę, dobrym tropem jest „tekstowość” wiersza. Zwykle:
- nagłówki – to krótkie napisy, bez liczb, dat i kwot,
- dane – mieszanka liczb, dat, pustych pól i czasem dłuższych opisów.
Można więc sprawdzić dla każdego wiersza, czy wszystkie jego pola „bezpiecznie” da się potraktować jak tekst (po konwersji) i nie przypominają typowych liczb czy dat. Prosty przykład:
let
DodajFlageTekstowyWiersz = Table.AddColumn(
#"Poprzedni krok",
"CzyWszystkoTekst",
each
let
wartosci = Record.ToList(_),
teksty = List.Transform(
wartosci,
(v) =>
let
t = if v is null then "" else Text.Trim(Text.From(v))
in
t
),
// sprawdź, czy w komórkach nie ma "czystych" liczb
czyJestLiczba =
List.AnyTrue(
List.Transform(
teksty,
(t) =>
let
n = Number.FromText(t)
in
n is number
)
),
// analogicznie można dodać test na daty, jeśli trzeba
czyNaglowekKandydat = not czyJestLiczba
in
czyNaglowekKandydat,
type logical
)
in
DodajFlageTekstowyWierszTego typu logikę dobrze jest połączyć z prostym ograniczeniem zakresu – np. patrzeć tylko na pierwsze 20–30 wierszy, bo tam zwykle leżą nagłówki i wstawki opisowe:
let
PierwszeWiersze = Table.FirstN(#"Poprzedni krok", 30),
// ...tu dodajemy kolumnę CzyWszystkoTekst jak wyżej...
IndeksNaglowka =
List.PositionOf(PierwszeWiersze[CzyWszystkoTekst], true),
TabelaPrzycięta =
if IndeksNaglowka < 0 then
#"Poprzedni krok"
else
Table.Skip(#"Poprzedni krok", IndeksNaglowka),
BezFlagi = Table.RemoveColumns(TabelaPrzycięta, {"CzyWszystkoTekst"}),
ZNaglowkami = Table.PromoteHeaders(BezFlagi, [PromoteAllScalars = true])
in
ZNaglowkamiJeśli w raporcie są wiersze opisowe (np. „Raport sprzedaży działu X”), ale zawierają cyfry, wtedy najczęściej odpadną w tym teście, a przejdzie dopiero właściwy nagłówek z samymi słowami.
Łączenie kryteriów: tekst + znane fragmenty nazw kolumn
Praktyka pokazuje, że najbardziej odporne rozwiązania łączą kilka prostych kryteriów, zamiast opierać się na jednym „triku”. Przykładowo, gdy raport przychodzi z zewnętrznego systemu, ale każdy kraj ma inne brzmienie nazw kolumn, można szukać:
- wiersza o „tekstowym” charakterze,
- zawierającego choć jeden z rozpoznawalnych fragmentów („Data”, „Date”, „Datum”).
Przykładowy kod M:
let
wzorceNaglowkow = {"Data", "Date", "Datum"},
DodajFlageZlozona = Table.AddColumn(
#"Poprzedni krok",
"CzyNaglowekZlozony",
each
let
wartosci = Record.ToList(_),
teksty = List.Transform(
wartosci,
(v) => if v is null then "" else Text.Trim(Text.From(v))
),
// kryterium 1: brak "czystych" liczb
czyJestLiczba =
List.AnyTrue(
List.Transform(
teksty,
(t) =>
let n = Number.FromText(t)
in n is number
)
),
// kryterium 2: czy któryś z tekstów zawiera którykolwiek z wzorców
czyZawieraWzorzec =
List.AnyTrue(
List.Transform(
teksty,
(t) =>
List.AnyTrue(
List.Transform(
wzorceNaglowkow,
(w) => Text.Contains(t, w, Comparer.OrdinalIgnoreCase)
)
)
)
)
in
(not czyJestLiczba) and czyZawieraWzorzec,
type logical
)
in
DodajFlageZlozona
Następny krok jest analogiczny: odszukać pierwszy wiersz z flagą CzyNaglowekZlozony = true, przyciąć tabelę, a potem promować nagłówki.
Co zrobić, gdy nagłówki są wielopoziomowe
Raporty finansowe i budżetowe często mają nagłówki rozbite na 2–3 wiersze: u góry rok, niżej kwartały lub miesiące, jeszcze niżej szczegółowe etykiety. Taki układ po imporcie do Power Query staje się trudny w obróbce:
- pierwszy rząd ma część informacji („2025”),
- drugi rząd ma kolejną („Q1”, „Q2”),
- w danych potrzebna jest jedna etykieta np. „2025-Q1”.
Typowy scenariusz to złączenie kilku pierwszych wierszy w jeden zestaw nagłówków jeszcze przed ich promocją. Prosty wzorzec:
- na chwilę oznaczyć 2–3 pierwsze wiersze jako „sekcję nagłówków”,
- przekształcić je w jedną listę tekstów na kolumnę – sklejając zawartość z rozdzielaczem,
- zastąpić pierwszy wiersz wynikiem tego sklejenia, pozostałe usunąć,
- promować scalony wiersz jako nagłówki.
Przykład dla dwóch pierwszych wierszy nagłówkowych:
let
// zakładamy, że dwa pierwsze wiersze to "poziomy" nagłówka
HeaderRows = Table.FirstN(#"Poprzedni krok", 2),
DataRows = Table.Skip(#"Poprzedni krok", 2),
// transpozycja, aby połączyć wartości pionowo dla każdej kolumny
HeaderTransposed = Table.Transpose(HeaderRows),
ZLaczonymNaglowkiem = Table.TransformColumns(
HeaderTransposed,
{
"Column1",
(lista) =>
Text.Combine(
List.Transform(
lista,
(v) => if v is null then "" else Text.Trim(Text.From(v))
),
" - "
),
type text
}
),
// wracamy do pierwotnego układu
HeaderCombined = Table.Transpose(ZLaczonymNaglowkiem),
// łączymy sklejony nagłówek z właściwymi danymi
TabelaZNowymNaglowkiem = Table.Combine({HeaderCombined, DataRows}),
ZPromowanymiNaglowkami = Table.PromoteHeaders(TabelaZNowymNaglowkiem, [PromoteAllScalars = true])
in
ZPromowanymiNaglowkamiJeśli kilka komórek w nagłówkach jest pustych, po sklejeniu mogą powstać etykiety typu „2025 – ”. Wtedy wygodnie jest dodać jeszcze krok czyszczący: usunąć zbędne spacje i myślniki na końcu lub początku tekstu.
Ukryte nagłówki i elementy ozdobne w raportach Excela
Dlaczego „ładny” raport w Excelu bywa pułapką dla Power Query
Raporty przygotowywane z myślą o wydruku lub wysłaniu w PDF często są bogate w ozdobniki:
- wstawione ręcznie tytuły, logotypy, bloki opisowe,
- pogrubione wiersze „Razem” w środku tabeli,
- puste wiersze dodane tylko po to, by rozsunąć sekcje.
Power Query widzi jednak tylko surowe komórki i ich zawartość – nie interesuje go ani pogrubienie, ani kolor, ani linie siatki. To oznacza, że:
- linia „RAZEM” nie różni się niczym od zwykłego wiersza z tekstem,
- puste wiersze „dla oddechu” stają się zwykłymi rekordami z wartościami null,
- osobne tabele na tym samym arkuszu zlewają się w jedną, jeśli import jest „po całym arkuszu”.
Stąd bierze się wiele niespodzianek: podwójne sumy, powielone nagłówki w środku danych, pozornie „losowo” obcięte wyniki. Domyślne ustawienia Power Query nie są przygotowane na estetyczne eksperymenty w arkuszu.
Jak Power Query traktuje ukryte wiersze i kolumny
Częstym źródłem zaskoczenia są wiersze i kolumny ukryte w Excelu. Użytkownik ich nie widzi, więc zakłada, że nie będą miały znaczenia; Power Query zwykle importuje je jednak tak samo jak te widoczne.
To zachowanie różni się w zależności od sposobu wczytania danych:
- Zdefiniowana tabela (Ctrl+T) – PQ pobiera tylko zakres tabeli; jeśli wiersze są ukryte, ale wchodzą w skład tabeli, zostaną wczytane.
- Cały arkusz (np. „Excel.Workbook” na plik) – PQ widzi pełny prostokąt używanego obszaru arkusza, w tym wiersze ukryte i obszary „poza kadrem”.
Jeśli ukryte wiersze zawierają stare nagłówki, testowe dane lub nieaktualne sekcje raportu, bez dodatkowego filtrowania trafią do modelu – i zaczną mieszać się z właściwą tabelą.
Namierzanie ukrytych nagłówków po powtarzających się nazwach kolumn
Szczególnie dokuczliwe są sytuacje, gdy na jednym arkuszu występuje kilka tabel o podobnych nagłówkach. Po imporcie wygląda to jak jedna długa tabela z powtarzającymi się blokami:
- nagłówki,
- dane,
- nagłówki,
- dane,
- itd.
W takim przypadku można wyłapać „nagłówki wtórne” na podstawie powtórzenia się znanych nazw kolumn w środku danych. Jedna z prostszych metod:
- po promocji nagłówków, znaleźć wiersze, w których wszystkie teksty odpowiadają nazwom kolumn,
- oznaczyć je jako „WierszNaglowkaPowtorzony”,
- następnie je usunąć lub potraktować jako granicę sekcji do dalszego dzielenia tabeli.
Przykład kodu po już wykonanym Table.PromoteHeaders:
let
nazwyKolumn = Table.ColumnNames(#"Poprzedni krok"),
DodajFlagePowtorzonyNaglowek = Table.AddColumn(
#"Poprzedni krok",
"CzyPowtorzonyNaglowek",
each
let
wartosci = List.Transform(
Record.ToList(_),
(v) => if v is null then "" else Text.Trim(Text.From(v))
),
czyWszystkoNazwyKolumn =
List.Count(
List.Difference(
wartosci,
nazwyKolumn
)
) = 0
in
czyWszystkoNazwyKolumn,
type logical
),
BezPowtorzonychNaglowkow =
Table.SelectRows(
DodajFlagePowtorzonyNaglowek,
each [CzyPowtorzonyNaglowek] = false
),
Wynik = Table.RemoveColumns(BezPowtorzonychNaglowkow, {"CzyPowtorzonyNaglowek"})
in
WynikTakie podejście wygodnie czyści raporty miesięczne, w których dla każdego regionu zrobiono osobną mini–tabelę o identycznych nagłówkach, a następnie ustawiono je jedna pod drugą na tym samym arkuszu.
Filtrowanie wierszy „RAZEM” i podobnych sum częściowych
Sumy częściowe typu „RAZEM region”, „Subtotal”, „SUMA ogółem” potrafią zafałszować analizy, jeśli wpadną do modelu razem z detalami. Z zewnątrz wyglądają jak zwykły tekst, więc nie ma prostego przełącznika „ignoruj sumy”.
Najbezpieczniej jest zbudować prostą listę słów–kluczy i filtrować po niej, przy okazji stosując delikatną logikę, by nie usuwać rzeczy zbyt agresywnie. Przykład:
let
slowaSum = {"RAZEM", "Razem", "SUMA", "Subtotal"},
DodajCzySuma = Table.AddColumn(
#"Poprzedni krok",
"CzySuma",
each
let
wartosci = List.Transform(
Record.ToList(_),
(v) => if v is null then "" else Text.Trim(Text.From(v))
),
calyTekst = Text.Upper(Text.Combine(wartosci, " ")),
czyZawiera =
List.AnyTrue(
List.Transform(
slowaSum,
(s) => Text.Contains(calyTekst, Text.Upper(s))
)
)
in
czyZawiera,
type logical
),
TylkoDetale = Table.SelectRows(DodajCzySuma, each [CzySuma] = false),
Wynik = Table.RemoveColumns(TylkoDetale, {"CzySuma"})
in
WynikJeśli pojawia się obawa, że część klientów czy produktów może mieć w nazwie słowo „Razem”, można doprecyzować warunek – np. odrzucać tylko te wiersze, które mają puste pola liczebne, a jednocześnie zawierają słowo–klucz w kolumnie opisowej.
Rozpoznawanie i wycinanie dodatkowych tabelek na dole raportu
Na końcu raportów często lądują „bonusowe” zestawienia: małe tabelki porównawcze, notatki, legenda kolorów. Dla Power Query to po prostu kolejne wiersze z danymi – o zupełnie innym układzie niż główna tabela.
Skuteczne podejście to odróżnienie „prawdziwych” wierszy na podstawie:
- liczby niepustych kolumn,
- kombinacji typów danych (np. typowy wiersz sprzedażowy: data + liczba + tekst),
- obecności wartości w kluczowej kolumnie (np. ID klienta nigdy nie jest puste).
Najczęściej zadawane pytania (FAQ)
Jak rozpoznać, że mam źle wczytane nagłówki w Power Query?
Najczęstszy sygnał to nazwy kolumn typu Column1, Column2 albo bardzo długie, dziwne nazwy zawierające tytuł raportu czy datę eksportu. Często widać też, że prawdziwe nagłówki siedzą w pierwszym wierszu danych zamiast w wierszu nagłówków.
Inny objaw to błędne typy danych: w kolumnie, która powinna być liczbą, pojawia się tekst, a po zmianie typu wyskakują błędy. W efekcie sumy i średnie nie zgadzają się z danymi w Excelu lub w systemie źródłowym.
Dlaczego w Power Query widzę „puste” wiersze, których nie mogę usunąć filtrem null?
Te wiersze zwykle nie są naprawdę puste. Zawierają spacje, myślniki, kropki albo inne niewidoczne znaki. Excel pokazuje je jak puste, ale Power Query widzi tam tekst. Filtrowanie po null usuwa wyłącznie komórki z prawdziwym brakiem wartości.
Aby je wykryć, można dla danej kolumny użyć kombinacji Text.Trim (obcięcie spacji) i Text.Length (sprawdzenie długości tekstu). Wiersze, w których po przycięciu długość wynosi 0, to faktycznie „puste” rekordy do usunięcia.
Jak usunąć puste wiersze i „separatory” (myślniki, kreski) po imporcie w Power Query?
Najprostsze podejście to zbudowanie filtra na kolumnie, która zawsze powinna mieć dane (np. numer dokumentu, datę, produkt). Można:
- odfiltrować wartości null oraz puste teksty po zastosowaniu Text.Trim,
- wykluczyć konkretne „ozdobne” wartości, jak „———”, „Suma”, „Raport sprzedaży…”.
Jeśli „śmieci” występują w wielu kolumnach, lepiej dodać pomocniczą kolumnę, która sprawdza kilka pól naraz (np. czy wszystkie są puste po przycięciu) i na tej podstawie odfiltrować całe wiersze.
Jak znaleźć prawdziwy wiersz nagłówków, gdy w Excelu jest kilka wierszy tytułów i komentarzy?
W praktyce dobrze działa prosta obserwacja: prawdziwy nagłówek to zwykle pierwszy wiersz, w którym większość kolumn jest niepusta i wygląda jak nazwy pól (krótkie słowa typu „Data”, „Region”, „Kwota”). Wiersze powyżej często zawierają długie zdania, daty generowania raportu, nazwę firmy czy sekcji.
W Power Query można więc najpierw NIE używać automatycznej promocji nagłówków, tylko odfiltrować wiersze „śmieciowe”, a dopiero potem krok „Użyj pierwszego wiersza jako nagłówków” zastosować ręcznie do tego właściwego wiersza.
Czym różni się import arkusza Excela jako „arkusz” od importu tabeli i jaki ma to wpływ na nagłówki?
Przy imporcie całego arkusza Power Query traktuje go jak zwykły zakres komórek. Zakłada, że pierwszy wiersz to nagłówki, co jest problematyczne, jeśli nad tabelą są tytuły, logotypy i puste linie. Wtedy nagłówkiem staje się właśnie ten „bałagan”.
Gdy importujesz obiekt Tabela (Ctrl+T w Excelu), Power Query zna jej prawdziwy nagłówek i nie musi zgadywać. Dzięki temu unikasz problemu z ukrytymi nagłówkami i większością pustych wierszy na górze, bo tabela z definicji zaczyna się bezpośrednio od wiersza nagłówków.
Co zrobić, jeśli nie mam wpływu na strukturę pliku z systemu (ERP/CRM), a import ciągle się „rozsypuje”?
W takiej sytuacji pomaga zbudowanie w Power Query stałego „bloku czyszczącego”: kilku kroków, które zawsze robią to samo – usuwają pierwsze X wierszy, filtrują określone frazy (np. nazwy sekcji, podpisy, stopki), a na końcu promują nagłówki z właściwego wiersza. Raz skonfigurowany schemat będzie działał przy kolejnych plikach o podobnym układzie.
Jeżeli raport ma kilka sekcji z różnymi nagłówkami, czasem trzeba najpierw odfiltrować wiersze należące do niepotrzebnych sekcji (np. „Podsumowanie”), a zostawić tylko tę część raportu, z której budujesz model danych.
Dlaczego moje sumy w Power BI/Excelu są zaniżone po imporcie, mimo że widać wszystkie wiersze?
Najczęściej część wierszy ma błędny typ danych. Na przykład w kolumnie kwot pierwszy wiersz zawiera tekst „Suma” i po promocji do nagłówków cała kolumna staje się tekstowa. Funkcje agregujące omijają te wartości lub zwracają błędy, co zaniża wynik.
Warto sprawdzić, czy nagłówki są poprawne, a w kolumnach liczbowych nie ma tekstów typu „Suma”, „Razem” czy „brak danych”. Po wyczyszczeniu takich wartości i wymuszeniu typu liczbowego sumy i średnie wracają do oczekiwanego poziomu.
Najważniejsze wnioski
- Puste wiersze, tytuły raportów i dodatkowe linie tekstu nad tabelą sprawiają, że Power Query błędnie rozpoznaje nagłówki – dane przesuwają się w kolumnach, a nazwy typu Column1 ukrywają prawdziwą strukturę tabeli.
- „Ukryte nagłówki” pojawiają się, gdy właściwe nazwy kolumn znajdują się niżej w arkuszu (np. w wierszu 5.), a powyżej stoją tytuły, komentarze i separatory – Power Query zaciąga je jak zwykłe dane i traktuje pierwszy napotkany wiersz jak nagłówki.
- Skutki źle wczytanych nagłówków i pustych wierszy widać dopiero w analizie: część danych nie wchodzi do sum i średnich, filtry działają na złych polach (np. tytuł raportu zamiast „Region”), a miary DAX opierają się na kolumnach o pomieszanych typach.
- Szczególnie niebezpieczne są „niewinne” teksty w pierwszym wierszu kolumny (np. „Suma”), które po promocji stają się nazwą kolumny – wszystko wygląda poprawnie, ale cały słupek ma wtedy typ tekstowy, przez co obliczenia są zafałszowane lub niepełne.
- Power Query odróżnia prawdziwie puste wiersze (null) od wierszy ze znakami (spacja, myślnik, kropka, niewidoczne znaki z innych systemów) – w Excelu oba wyglądają tak samo, lecz przy czyszczeniu „Usuń puste” te drugie spokojnie przechodzą dalej.
- Wiele „pustych” lub ozdobnych linii wynika z potrzeb użytkownika (ładny wydruk, komentarze, sekcje raportu), jednak dla Power Query to normalne dane tekstowe, które łatwo stają się nagłówkami albo wierszami zakłócającymi model.






