< návrat zpět
MS Excel
Téma: Power Query vlastní sloupec
Zaslal/a Dingo 21.1.2025 10:14
Z Pdf chci dostat tabulku s určitými sloupci, potřebuju pak měnit zdrojové PDF (jsou podobné) a mít soubor připravený tak, aby vždy generoval výslednou tabulku. K načtení se v PDF nabízí tabulky "Tablexxx" a "Page001", 002,003 podle počtu stran. V Table nejsou data celá, v Page ano. Můj záměr je připravit si PQ dotazpro každou stranu "Page" (max.4) a výsledek spojit do finální tabulky. Při menším počtu stran jen upravím to spojení.
Problém je, že sloupce v každém "Page" jsou různě posunuté, někdy je mezi prázdný sloupec, a tak ten, který potřebuji, se může posouvat až na čtyřech pozicích.
Každá strana má záhlaví s různým počtem řádků, které odebírám filtrem na položku "name", s tím už jsem se vypořádal a dostanu stav, který jsem nasimuloval v přiloženém souboru.
Kdyby sloupce odpovídaly pozicí na všech stranách, jen bych "ponechal" potřebné podle názvu pomocí zvýšeného záhlaví.
Ale to nefunguje, někde je navíc nadpis posunutý stranou od dat a musím výchozí sloupec přejmenovat a pod.. Jediné co mě napadlo je sloučit několik sloupců a podle výsledku (klíče) pak přidat vlastní sloupec s daty, ostatní odstranit.
ALE potřebuju přidat sloupec podle 1.řádku určitého sloupce, kde mám nadpisy. NE podle každé hodnoty v řádcích! Jako když v excelu použiju $A$1. A toho neumím dosáhnout.
To co jsem vygooglil a pokusil se použít, mi dává chybu. Toto jsem naznačil v přiloženém souboru.
Pro nějaké obecné řešení celého problému by to chtělo umět v PQ vyhledat hodnotu v celé tabulce, (je tam jedna, např. "Name"), abych věděl název sloupce, kde se slovo vyskytuje. Toto opakovat pro další hodnoty, vytvořit si tak množinu sloupců, ty ponechat, ostatní odebrat. Je něco takového proveditelné?
lubo(21.1.2025 13:56)#057180 Moc to nechápu.
add najít první řádek:
Funkce Table.FindText najde první řádek, na kterém se vyskytuje hledaný text.
Pokud potřebuji jeho pozici mohu:
Nejprve přidat index funkce - Table.AddIndexColumn
pak najít text (funkce vrátí record) a číslo řádku si přečíst
nebo mohu vyhledat pozici nalezeného řádku funkcí
Table.PositionOf. tady funkce vrátí pozici
Pak odstraním předchozí řádky.
(Jsou i jiné možnosti.)
Pak první řádek dám do hlavičky a pokud znám názvy sloupců si je vyberu funkcí Table.SelectColumns.
Pokud některé sloupce chybí, je tu parametr MissingField.UseNull.
Výsledkem je tabulka se sloupci ve správném pořadí.
citovat
Dingo(21.1.2025 15:38)#057181 Díky za snahu. Já ale vlastně hledám sloupec, tedy víc sloupců, ne řádek.
Jak jsem četl odpověď, nějak jsem si uvědomil, že jde převést sloupce na řádky. Něco jsem zkusil a povedlo se mi právě tímhle vyfiltrovat "hledané slovo" - tím získat název sloupce ve Zdroji, vrátit se ke Zdroji a přesně ten sloupec duplikovat, přejmenovat, hlavně pak můžu použít své nové jméno sloupce při odebírání ostatních. Pak už myslím bude vyhráno. Možná. Zatím mi to asi stačí, díky.
citovat
lubo(21.1.2025 17:01)#057182 let
Zdroj = Table.FromRecords(
{
[a = 0, b = "xxx", c = "xxx", d = "xxx",e = "xxx"],
[a = 1, b = "xxx", c = "xxx", d = "xxx",e = "xxx"],
[a = 3, b = "xxx", c = "xxx", d = "Name",e = "xxx"],
[a = 4, b = "xxx", c = "xxx", d = "xxx",e = "xxx"]
}),
#"Radek jako table" = Table.FindText(Zdroj, "Name"),
#"Radek jako record" = #"Radek jako table"{0},
#"Jméno sloupce" = Record.FieldNames(#"Radek jako record"){List.PositionOf(Record.FieldValues(#"Radek jako record"), "Name")}
in
#"Jméno sloupce"
vrátí d
nebo něco jako
let
Zdroj = Table.FromRecords(
{
[a = 0, b = "xxx", c = "xxx", d = "xxx",e = "xxx"],
[a = 1, b = "xxx", c = "xxx", d = "xxx",e = "xxx"],
[a = 3, b = "xxx", c = "xxx", d = "Name",e = "xxx"],
[a = 4, b = "abc", c = "xxx", d = "xxx",e = "xxx"]
}),
jména = {"Name", "abc"},
Sloupce = List.Accumulate(Table.ColumnNames(Zdroj), {}, (a, l) => if List.Count(List.Intersect({Table.Column(Zdroj, l ), jména})) > 0 then a & {l} else a)
in
Sloupce
vrátí {b, d}
citovat
Dingo(22.1.2025 11:29)#057183 lubo děkuji. Prošel jsem si uvedené postupy a nakonec se oba hodí, ale potřeboval bych ještě pomoc s konkrétním použitím již získaného jména sloupce, tam mé znalosti nestačí, prostým zkoušením se mi nedaří.
V přiloženém souboru jsou 2 dotazy, v tom prvním mám problém popsaný v poznámkách u kódu, tak kdyby někdo věděl ....
citovat
lubo(22.1.2025 13:27)#057184 // 1 odstranení záhlaví k Name
let
// úpravou rozsáhlé tabulky se dostanu k přibližně tomuto stavu
Zdroj = ...,
#"Přidané: Index2" = Table.AddIndexColumn(Zdroj, "Index", 0, 1, Int64.Type),
#"Radek jako table" = Table.FindText(#"Přidané: Index2", "Name"),
Vlastní1 = Table.Skip(Zdroj, #"Radek jako table"[Index]{0}),
#"Záhlaví se zvýšenou úrovní" = Table.PromoteHeaders(Vlastní1, [PromoteAllScalars=true]),
#"Odebrané sloupce" = Table.RemoveColumns(#"Záhlaví se zvýšenou úrovní",
List.Select(Table.ColumnNames(#"Změněný typ"), each Text.Start(_,6) = "Column"))
in
#"Odebrané sloupce"
// 2 redukce sloupců dle jména
let
// úpravou rozsáhlé tabulky se dostanu k přibližně tomuto stavu
Zdroj = ...,
#"Seznam jmen" = {"Rank", "St.Numb", "Name", "Start Time", "Finish Time"},
Sloupce = List.Accumulate(Table.ColumnNames(Zdroj), {}, (a, l) => if List.Count(List.Intersect({Table.Column(Zdroj, l ), #"Seznam jmen"})) > 0 then a & {l} else a),
#"Znovu Zdroj 1" = Table.SelectColumns(Zdroj, Sloupce),
#"Záhlaví se zvýšenou úrovní" = Table.PromoteHeaders(#"Znovu Zdroj 1", [PromoteAllScalars=true])
in
#"Záhlaví se zvýšenou úrovní"
Pozn. kód ... generuje chybu "Neimplementováno".
citovat
Dingo(23.1.2025 13:10)#057195 lubo, výborné, zase jsem se něco přiučil, děkuji. To dopisování kódu nad rámec pouhého klikání je pro mě peklo.
citovat