Vodič za razvijalce

Glavni koledar in časovne primerjave v Qliku

Letos proti lani, od začetka leta (YTD), prejšnji mesec in drsečih 12 mesecev — z enim dobrim koledarjem in nekaj preverjenimi izrazi.

Skoraj vsaka poslovna aplikacija mora odgovoriti na vprašanje »kako nam gre v primerjavi z lani?«. V Qliku za to potrebujete dvoje: glavni koledar v podatkovnem modelu in nekaj izrazov s set analysis. Ta vodič pokaže oboje.

Zakaj glavni koledar

Tabela dejstev ima datum le za dneve, ko se je kaj zgodilo. Glavni koledar (master calendar) je ločena tabela z vsakim dnem v obdobju in vsemi izpeljanimi polji: letom, četrtletjem, mesecem, tednom. Prednosti:

  • izpeljana polja izračunate enkrat, v skripti, in ne v vsakem grafu,
  • v časovnih grafih ni »lukenj« za mesece brez prodaje,
  • dodate lahko polja za primerjave (zaporedna številka meseca, zastavice), ki izraze močno poenostavijo.

Koledar, pripravljen za primerjave

Osnovno različico koledarja smo zgradili v vodiču Nalaganje podatkov. Tu je razširjena, s polji, ki jih bomo potrebovali za primerjave:

// Razpon datumov iz tabele dejstev
TmpRazpon:
LOAD
    Min(Datum) as MinDatum,
    Max(Datum) as MaxDatum
RESIDENT Prodaja;

LET vMin = Num(YearStart(Peek('MinDatum', 0, 'TmpRazpon')));
LET vMax = Num(YearEnd(Peek('MaxDatum', 0, 'TmpRazpon')));
DROP TABLE TmpRazpon;

Koledar:
LOAD
    Datum,
    Year(Datum)                               as Leto,
    'Q' & Ceil(Month(Datum) / 3)              as Cetrtletje,
    Month(Datum)                              as Mesec,
    Date(MonthStart(Datum), 'MMM YYYY')       as LetoMesec,
    Week(Datum)                               as Teden,
    WeekDay(Datum)                            as DanVTednu,
    Day(Datum)                                as DanVMesecu,
    // zaporedna številka meseca: brez težav prek meje leta
    (Year(Datum) - 1) * 12 + Month(Datum)     as MesecZap,
    // zastavice glede na datum nalaganja (1 = da)
    -InYearToDate(Datum, Today(), 0)          as LetosYTD,
    -InYearToDate(Datum, Today(), -1)         as LaniYTD;
LOAD
    Date($(vMin) + IterNo() - 1)              as Datum
AUTOGENERATE 1
WHILE $(vMin) + IterNo() - 1 <= $(vMax);

Nekaj podrobnosti:

  • Koledar raztegnemo na cela leta (YearStart do YearEnd), da imajo grafi po mesecih vedno vseh 12 mesecev.
  • Month() vrne dvojno vrednost (dual): prikaže se kot »jan«, »feb« …, razvršča in računa pa se kot 1, 2 … Zato se meseci v grafih uredijo pravilno.
  • MesecZap je ključ za primerjave med meseci: januar 2026 in december 2025 sta zaporedni števili, ne glede na mejo leta.
  • InYearToDate() vrne −1 (resnično) ali 0, zato pred njo stoji minus. Zastavici veljata glede na dan nalaganja — aplikacija se mora osvežiti vsak dan.
  • Oblika 'MMM YYYY' in imena dni sledijo nastavitvam okolja na začetku skripte (SET MonthNames=…, SET DayNames=…).

Letos proti lani po mesecih

Najpogostejši graf: stolpci za letos in lani, po mesecih. Kot dimenzijo uporabite Mesec (brez leta!), meri pa sta:

// Letos (zadnje izbrano leto)
Sum( {<Leto = {$(=Max(Leto))}>} Prodaja )

// Lani
Sum( {<Leto = {$(=Max(Leto) - 1)}>} Prodaja )

Ker je dimenzija samo mesec, se letošnji in lanski marec znajdeta v istem stolpcu. Če bi kot dimenzijo uporabili LetoMesec, bi bila lanska vrednost pri letošnjih mesecih prazna — set analysis se namreč izračuna enkrat za cel graf, ne za vsako vrstico.

Vzorčni podatki, izbor Leto = 2025, 2026. Zgoraj pravilno — dimenzija Mesec, stolpca za isti mesec stojita skupaj. Spodaj ista dva izraza z dimenzijo LetoMesec: vsak mesec ima le eno vrednost in primerjave ni. Oktober 2026 še ni zaključen.

Od začetka leta (YTD)

Različica A: glede na izbore

YTD do zadnjega datuma v trenutnih izborih in isto obdobje lani. Izbore v poljih koledarja počistimo, ker obdobje določimo sami:

// YTD letos
Sum( {<Datum = {">=$(=Date(YearStart(Max(Datum))))<=$(=Date(Max(Datum)))"},
       Leto =, Cetrtletje =, Mesec =, LetoMesec =, Teden =>} Prodaja )

// YTD lani (do istega dne)
Sum( {<Datum = {">=$(=Date(YearStart(Max(Datum), -1)))<=$(=Date(AddYears(Max(Datum), -1)))"},
       Leto =, Cetrtletje =, Mesec =, LetoMesec =, Teden =>} Prodaja )
Pozor: Max(Datum) gleda koledar Ker koledar sega do konca leta, Max(Datum) brez izborov vrne 31. 12. in ne zadnjega dne s prodajo. Če želite YTD »do danes«, uporabite Today() namesto Max(Datum) ali različico B.

Različica B: z zastavicami iz skripte

Preprostejši in hitrejši izrazi, ki veljajo glede na dan nalaganja:

Sum( {<LetosYTD = {1}, Leto =, Cetrtletje =, Mesec =, LetoMesec =, Teden =, Datum =>} Prodaja )
Sum( {<LaniYTD  = {1}, Leto =, Cetrtletje =, Mesec =, LetoMesec =, Teden =, Datum =>} Prodaja )

Za KPI-je na prvem listu (»letos do danes proti lani do istega dne«) je to najzanesljivejša rešitev.

Vzorčni podatki, nalaganje 22. 10. 2026. KPI-ji uporabljajo zastavici LetosYTD in LaniYTD, zato je lanski YTD izračunan do 22. 10. 2025 — ne do konca oktobra. Rast: Sum({<LetosYTD={1}, …>} Prodaja) / Sum({<LaniYTD={1}, …>} Prodaja) - 1.

Prejšnji mesec in drsečih 12 mesecev

Tu pride do izraza polje MesecZap. Ker so meseci oštevilčeni zaporedno, je prejšnji mesec vedno številka − 1, tudi v januarju:

// Zadnji izbrani mesec
Sum( {<MesecZap = {$(=Max(MesecZap))}, Leto =, Cetrtletje =, Mesec =, LetoMesec =>} Prodaja )

// Mesec pred tem
Sum( {<MesecZap = {$(=Max(MesecZap) - 1)}, Leto =, Cetrtletje =, Mesec =, LetoMesec =>} Prodaja )

// Isti mesec lani
Sum( {<MesecZap = {$(=Max(MesecZap) - 12)}, Leto =, Cetrtletje =, Mesec =, LetoMesec =>} Prodaja )

// Drsečih 12 mesecev (zadnji izbrani + 11 prejšnjih)
Sum( {<MesecZap = {">=$(=Max(MesecZap) - 11)<=$(=Max(MesecZap))"},
       Leto =, Cetrtletje =, Mesec =, LetoMesec =>} Prodaja )

Uporabnik izbere npr. mar 2026 v polju LetoMesec in vse štiri mere se prilagodijo. Ker iščemo po številskem polju, ni težav z obliko datuma.

Preizkusite: izberite mesec v filtru ali kliknite na točko v grafu. Poudarjeni so izbrani mesec (zeleno), prejšnji mesec (modro) in isti mesec lani (sivo), senca pa označuje drsečih 12 mesecev. Ko izbor počistite, se pokaže past iz naslednjega odstavka — Max(MesecZap) postane december 2026.

Brez izbora je Max(MesecZap) december zadnjega leta v koledarju, saj koledar sega do konca leta. Za KPI-je »zadnji zaključeni mesec« zato uporabite izračun iz današnjega datuma, npr. $(=(Year(Today()) - 1) * 12 + Month(Today()) - 1), ali pa v skripti dodajte zastavico, kot pri YTD.

Poslovno leto, ki se ne začne januarja

Če se poslovno leto začne npr. 1. julija, dodajte v koledar:

Year(Datum) + If(Month(Datum) >= 7, 1, 0)                as PoslovnoLeto,
Mod(Month(Datum) - 7, 12) + 1                           as MesecPoslovnegaLeta,

Julij 2026 je tako 1. mesec poslovnega leta 2027 (če poslovno leto poimenujete po letu, v katerem se konča). Funkcije YearStart, YearEnd in InYearToDate sprejmejo tudi dodaten argument s prvim mesecem leta, npr. InYearToDate(Datum, Today(), 0, 7).

Izrazi v spremenljivkah

Ko imate deset mer z enakim set izrazom, ga shranite v spremenljivko. Najlažje v urejevalniku spremenljivk v aplikaciji, npr. vSetPrejsnjiMesec z vsebino:

MesecZap = {$(=Max(MesecZap) - 1)}, Leto =, Cetrtletje =, Mesec =, LetoMesec =

in mero zapišete kot:

Sum( {<$(vSetPrejsnjiMesec)>} Prodaja )
Spremenljivke v skripti Če spremenljivko z izrazom $(=…) definirate v skripti s SET, Qlik razširitev z dolarjem izvede že med nalaganjem. To se rešuje z nadomestnim znakom (npr. @ namesto $) in funkcijo Replace(). Za začetek je urejevalnik spremenljivk preprostejši.

Pogoste napake

  • Dimenzija LetoMesec v grafu letos/lani — lanska mera je pri letošnjih mesecih prazna. Uporabite Mesec.
  • Pozabljeno čiščenje polj koledarja — če uporabnik izbere mesec, filter po Datum pa določa celo leto, velja presek. V set izrazu počistite vsa polja koledarja, ki jih uporabnik lahko izbere.
  • Neosvežena aplikacija — zastavice in Today() v skripti veljajo za dan nalaganja.
  • Več datumov v dejstvih — datum naročila in datum dobave potrebujeta vsak svoj koledar (ali skupni koledar s tipom datuma). En koledar za oba ustvari krožno referenco; več v vodiču Podatkovni model.