Ugrás a fő tartalomra

Power Bi alapok: M nyelven naptár tábla létrehozás

 Power Bi alapok: M nyelv naptár tábla létrehozás



Általános elv a tábla létrehozásra

  1. Kezdeti adatok létrehozása

    • Használhatunk listákat (List.Numbers, List.Dates) vagy közvetlen adatforrásokat (Excel, SQL, stb.).

    • A fenti példában egy számlistát generálunk (List.Numbers), amely a dátumokat számként reprezentálja.

  2. Lista transzformálása táblává

    • List.Transform segítségével az egyes elemeket átalakíthatjuk (pl. számokat dátummá).

    • Table.FromList függvénnyel a lista táblává alakítható.

  3. Oszlopok hozzáadása

    • A Table.AddColumn függvény iterál a táblán, és minden egyes sorhoz egy új számított értéket rendel.

    • Ilyenek például az év (Date.Year), hónap (Date.Month), hét napja (Date.DayOfWeek).

  4. Dátumformázások és kombinációk

    • A hónap és nap szövegként történő megjelenítése (Date.ToText).

    • Az év és hónap egyedi azonosító formában (YYYY-MM), ami az időalapú jelentésekhez kiváló.


Műveleti összefüggések és sorrend

Az egymásra épülő műveletek miatt a függvények sorrendje kulcsfontosságú. Például:

✅ Helyes sorrend:

  1. Adatok generálása (List.Numbers)

  2. Lista átalakítása dátumokká (List.Transform)

  3. Táblázattá konvertálás (Table.FromList)

  4. Oszlopok hozzáadása (év, hónap, hét napja)

  5. Szöveges és numerikus oszlopok kombinációja

❌ Helytelen sorrend:

  • Ha a Date.Year függvényt a lista formázása előtt alkalmazzuk, az hibát eredményezhet.

  • Ha egy szövegformázási lépés korábban történik, adatvesztés vagy konverziós hiba fordulhat elő.


Power Query specialitásai és a legjobb megoldás elvei

  1. Egymásra épülő műveletek (Step-by-Step logika)

    • Minden lépés egy előző állapotot módosít, így az adattranszformáció olvasható marad.

    • Az in utasítás a végső értéket adja vissza.

  2. Listák hatékony kezelése

    • A Power Query M nyelv listaalapú, így az egyes elemeket közvetlenül átalakíthatjuk.

    • Példa: List.Transform(DaysInRange, each #date(StartYear, 1, 1) + _)

  3. Elkerülendő hibák

    • Ha egy oszlophoz helytelen adattípust adunk (type text helyett Int64.Type), az összes művelet hibás lehet.

    • A dátumoknál ügyelni kell arra, hogy időzónákat ne változtassunk meg szükségtelenül.

  4. Optimalizációs elvek

    • Késői konverzió: a számokat érdemes az utolsó pillanatban dátummá alakítani, hogy a számítási teljesítmény jobb maradjon.

    • Minimalista adatkészlet: csak a szükséges oszlopokat hozzuk létre (pl. YearMonth kombinálja az évet és hónapot, így nem szükséges külön mezők létrehozása).


Összegzés és ajánlott gyakorlatok

📌 Használj listaalapú számításokat, mert gyorsabbak és rugalmasabbak.
📌 Kövess logikus lépésenkénti adattranszformációt, az összefüggések átláthatósága érdekében.
📌 Tartsd az adattípusokat konzisztensen, és ügyelj a dátumformátumokra.
📌 Optimalizálj: csak azokat az oszlopokat használd, amelyek szükségesek az elemzéshez.












 Naptár generálás

Ez a Power Query M kód egy dátumtáblát hoz létre 2010. január 1. és 2030. december 31. között. 

A következő oszlopokat tartalmazza:

  • Date (dátum)
  • Year (év)
  • Month (hónap száma)
  • Day (nap száma)
  • Weekday (hét napja szám szerint, hétfő = 1)
  • WeekdayName (hét napja név szerint)
  • MonthName (hónap neve)
  • Quarter (negyedév száma)
  • YearMonth (ÉÉÉÉ-HH formátumú azonosító)



A Power Query M kód, amely egy naptár táblát generál 2010-től 2030-ig Power BI-ban:


---- 1. dátum lista alapján

let
    StartDate = #date(2010, 1, 1),
    EndDate = #date(2030, 12, 31),
    DateList = List.Dates(StartDate, Number.From(EndDate - StartDate) + 1, #duration(1, 0, 0, 0)),
    TableFromList = Table.FromList(DateList, Splitter.SplitByNothing(), {"Date"}, null, ExtraValues.Error),
    AddYear = Table.AddColumn(TableFromList, "Year", each Date.Year([Date]), Int64.Type),
    AddMonth = Table.AddColumn(AddYear, "Month", each Date.Month([Date]), Int64.Type),
    AddDay = Table.AddColumn(AddMonth, "Day", each Date.Day([Date]), Int64.Type),
    AddWeekday = Table.AddColumn(AddDay, "Weekday", each Date.DayOfWeek([Date]) + 1, Int64.Type),
    AddWeekdayName = Table.AddColumn(AddWeekday, "WeekdayName", each Date.ToText([Date], "dddd"), type text),
    AddMonthName = Table.AddColumn(AddWeekdayName, "MonthName", each Date.ToText([Date], "MMMM"), type text),
    AddQuarter = Table.AddColumn(AddMonthName, "Quarter", each Date.QuarterOfYear([Date]), Int64.Type),
    AddYearMonth = Table.AddColumn(AddQuarter, "YearMonth", each Text.PadStart(Text.From([Year]), 4, "0") & "-" & Text.PadStart(Text.From([Month]), 2, "0"), type text)
in
    AddYearMonth


 
---- 2. számlista alapján

let
    StartYear = 2010,
    EndYear = 2030,
    DaysInRange = List.Numbers(0, Number.From(#date(EndYear, 12, 31) - #date(StartYear, 1, 1)) + 1, 1),
    DateList = List.Transform(DaysInRange, each #date(StartYear, 1, 1) + _),
    TableFromList = Table.FromList(DateList, Splitter.SplitByNothing(), {"Date"}, null, ExtraValues.Error),
    AddYear = Table.AddColumn(TableFromList, "Year", each Date.Year([Date]), Int64.Type),
    AddMonth = Table.AddColumn(AddYear, "Month", each Date.Month([Date]), Int64.Type),
    AddDay = Table.AddColumn(AddMonth, "Day", each Date.Day([Date]), Int64.Type),
    AddWeekday = Table.AddColumn(AddDay, "Weekday", each Date.DayOfWeek([Date]) + 1, Int64.Type),
    AddWeekdayName = Table.AddColumn(AddWeekday, "WeekdayName", each Date.ToText([Date], "dddd"), type text),
    AddMonthName = Table.AddColumn(AddWeekdayName, "MonthName", each Date.ToText([Date], "MMMM"), type text),
    AddQuarter = Table.AddColumn(AddMonthName, "Quarter", each Date.QuarterOfYear([Date]), Int64.Type),
    AddYearMonth = Table.AddColumn(AddQuarter, "YearMonth", each Text.PadStart(Text.From([Year]), 4, "0") & "-" & Text.PadStart(Text.From([Month]), 2, "0"), type text)
in
    AddYearMonth


Ez a verzió egy számlistát hoz létre, amelyet az #date(2010,1,1) dátumtól kezdve számol. Minden egyes számhoz egy napot adunk hozzá, így generálva a teljes dátumtartományt.



Speciális változó használat


A _ (underscore vagy aláhúzás) egy speciális változó Power Query M nyelvben, amely a jelenlegi iterált elemre utal egy függvényen vagy lekérdezésen belül. Főként listák és táblázatok egyes sorainak feldolgozásakor használjuk.


Hogyan működik az _ változó?

Amikor egy iteratív függvényt hívunk meg, például List.Transform vagy Table.AddColumn, a _ változó az aktuális elemként viselkedik, amelyen a művelet végrehajtásra kerül.

🔹 Egyszerű példa List.Transform esetén:

---m

let Numbers = {1, 2, 3, 4, 5}, SquaredNumbers = List.Transform(Numbers, each _ * _) in SquaredNumbers

Eredmény: {1, 4, 9, 16, 25}
➡ Az _ változó itt az aktuális listaelemre utal, és minden elem négyzetét veszi.


Példa dátumgenerálásra _ használatával

A következő kód List.Numbers segítségével számlistát generál, majd _ változót használ a dátumok létrehozására:

---m

let StartDate = #date(2020, 1, 1), DaysList = List.Numbers(0, 10), DateList = List.Transform(DaysList, each StartDate + _) in DateList

Eredmény:
{#date(2020,1,1), #date(2020,1,2), ..., #date(2020,1,10)}


➡ Az _ változó itt az aktuális számot jelöli a listában, amelyet hozzáadunk a kezdődátumhoz.


Használat Table.AddColumn esetén

A táblázatkezelésnél _ segít egy adott sor oszlopértékeit manipulálni.

---m

let SourceTable = #table({"Number"}, {{1}, {2}, {3}, {4}}), TableWithSquares = Table.AddColumn(SourceTable, "Squared", each _[Number] * _[Number]) in TableWithSquares

Eredmény:

NumberSquared
11
24
39
416

➡ _ az aktuális sort képviseli, és [Number] segítségével elérjük az adott oszlop értékét.


Mikor NEM használható az _?

  1. Összetett függvényekben, ahol az aktuális elem egy táblázat vagy rekord.

    • Ha egy táblázatot kell módosítanod, inkább explicit változónevet használj.

    Rossz példa:

    ---m

    Table.AddColumn(MyTable, "NewCol", each Table.AddColumn(_, "Extra", each [Value] * 2))

    Jó példa:

    ---m

    Table.AddColumn(MyTable, "NewCol", each Table.AddColumn(_[TableColumn], "Extra", each [Value] * 2))
  2. Amikor egy függvényen belül több szintű műveletet végzünk.

    • Ebben az esetben nevezzünk meg egy lokális változót (CurrentRow).


Összegzés és best practice

✅ Használható egyszerű transzformációkhoz, mint List.Transform vagy Table.AddColumn.
✅ Olvashatóbbá teszi az egyszerű függvényeket, ahol csak egy aktuális elem van.
✅ Kombinálható más függvényekkel (Date, Text, Number műveletekkel).

⚠ Kerüld összetett adatszerkezetek esetén (pl. táblázatoknál), ahol explicitebb változónévre van szükség.



Minta

A DateTime.FromText(_) függvényhívás a Power Query M nyelvben az _ változót (az aktuális elemet) alakítja át egy dátum-idő (DateTime) formátummá.


Hogyan működik?

Ha ezt egy iterációs függvényen belül használjuk (pl. List.Transform vagy Table.AddColumn), akkor _ az aktuális elemet képviseli, és a DateTime.FromText(_) megpróbálja azt átalakítani dátummá.

🔹 Példa listával:

---m

let TextDates = {"2024-03-31 12:00:00", "2025-01-01 08:30:15"}, DateTimeList = List.Transform(TextDates, each DateTime.FromText(_)) in DateTimeList

Eredmény:
{#datetime(2024,3,31,12,0,0), #datetime(2025,1,1,8,30,15)}

➡ A List.Transform végigmegy a TextDates listán, és minden elemnél _ az aktuális szöveges dátum. Ezután a DateTime.FromText(_) alakítja át valódi datetime formátummá.


🔹 Példa táblázattal:

Ha egy oszlop szöveges dátumokat tartalmaz ("2024-03-31 12:00:00" formátumban), akkor egy új oszlopot így hozhatunk létre:

---m

let SourceTable = #table({"TextDate"}, {{"2024-03-31 12:00:00"}, {"2025-01-01 08:30:15"}}), ConvertedTable = Table.AddColumn(SourceTable, "ConvertedDateTime", each DateTime.FromText(_[TextDate]), type datetime) in ConvertedTable

Eredmény:

TextDateConvertedDateTime
"2024-03-31 12:00:00"2024-03-31 12:00:00
"2025-01-01 08:30:15"2025-01-01 08:30:15

➡ _ itt az aktuális sor, ezért [TextDate]-et kell használni az oszlop értékének eléréséhez!


Hibalehetőségek

⚠ Hibát dob, ha az érték nem megfelelő dátumformátumú.

  • Pl. "31-03-2024 12:00:00" hibás lehet, ha nincs megfelelő lokalizációs beállítás.

  • Érdemes használni az ellenőrzést:

    ---m

    try DateTime.FromText(_) otherwise null

⚠ Ha _ egy teljes sor, akkor [OszlopNév] szükséges.

  • Rossz: Table.AddColumn(MyTable, "NewCol", each DateTime.FromText(_))

  • Jó:       Table.AddColumn(MyTable, "NewCol", each DateTime.FromText(_[TextDate]))


Összegzés

✅ A DateTime.FromText(_) egy szöveges dátumot alakít át DateTime típusúvá.
✅ Iterációs függvényekben _ az aktuális elemként viselkedik.
✅ Táblázatok esetén _ egy teljes sorra mutathat, ezért oszlopnév kell (_[ColumnName]).
✅ Hibakezelést érdemes beépíteni, ha az adatok nem biztosan megfelelő formátumúak.









Megjegyzések