Masterkalender
Masterkalender är ett återanvändbart masterkalenderskript som kan hantera flera kalenderbehov. Den kan bland annat hantera följand scenarion.
- Ett datumfält en kalender
- Ett datumfält flera kalendrar (Eg. kalenderår och bokföringsår)
- Flera datumfält flera kalendrar
- Flera datumfält en kalender.
Masterkalenderskriptet består av tre SUB-funktioner som du kan läsa mer om nedan.
SUB kalender SUB kalenderfrånfält SUB kalenderlänk
SUB kalender
Innhåller koden för själva kalendern. Skapar en masterkalender med hjälp av 2-4 parametrar.
Parametrar
- [obligatorisk] Första datum i kalendern.
- [obligatorisk] Sista datum i kalendern
- [valfri] Nyckelfältnamn i kalendern.
- [valfri] Kalender-prefix
Exempler på anrop
/* 1. Skapa en kalender med default nyckelfält*/
CALL kalender('2020-01-01', '2021-12-31')
/* 2. Skapa en kalender med nyckelfält som heter '%DateID'*/
CALL kalender('2020-01-01', '2021-12-31', '%DateID')
/* 3. Skapa en Kalender där kalenderfälten har prefixet 'Leverans-'.*/
CALL kalender('2020-01-01', '2021-12-31', '', 'Leverans-')
Alla dessa anrop skapar en kalender som innehåller följande fält, med undantag av anrop 3 där alla kalenderfältnamnm har prefixet leverans-.
Fält | Kommentar |
---|---|
Datum | Formaterad som angett i systemvariabeln DateFormat . |
Veckodag | Veckodag, första veckodag styrs av systemvariabel FirstWeekDay. |
Vecka | Veckonummer, presenteras med veckonummer där januari är årets första månad, men sorteras utifrån vad som är årets första månad via systemvariabeln FirstMonthOfYear. Fältet påverkas också av systemvariablerna FirstWeekDay, BrokenWeeks och ReferenceDay. |
År | Formaterad som YYYY, fast med numersikt värde satt till årets första dag. Årets indelning styrs av systemvariabeln FirstMonthOfYear |
Månad | Formaterad som angett i systemvariabeln MonthNames . |
År-månad | Formaterad som angett i variabeln vL.kalender.aarmaanadformat . |
Kvartal | ‘Q1’, ‘Q2’, ‘Q3’ eller ‘Q4’ |
År-kvartal | Formaterad som ‘YYYY Q1’, ‘YYYY Q2’, ‘YYYY Q3’ eller ‘YYYY Q4’ och med kvartalets första datum som numeriskt värde. |
Historik/Framtid | Har värdet ‘Historik’ för alla historiska datum och ‘Framtid’ för alla framtida datum. Brytpunkten är per default Today() , men kan overridas med variabeln vL.kalender.idag . |
SUB kalenderfrånfält
Ett förenklad anropssätt för att skapa en kalender utifrån ett redan inläst kalenderfält. Funktionen hittar minsta och största värdet i angett kalenderfät och anropar SUB kalender med de värdena.
- [obligatorisk] Kalendernyckelfält. Det fält som det ska kopplas en kalender på.
- [valfri] Källa som innehåller pinpointar kalenderfältets källa.
- [valfri] Kalender-prefix
SUB kalenderlänk
Metod för att koppla flera datumfält i en tabell till en och samma masterkalender.
Masterkalender.qvs
Klistra in scriptet nedan i en qvs fil eller direkt i ditt applikationsskript för att använda de tre SUB som beskrivits ovan.
///$tab sublib.kalender
SUB sublib.kalender (_minKalenderdatum, _maxKalenderdatum, _kalendernyckelfält, _calendarPrefix)
/**
Skapa kalender från ett angett min- och max-datum
@version 2021-07-30
@Param 1 Obligatoriskt. [Minsta kalenderdatum] Det datum där kalendern ska börja.
@Param 2 Obligatoriskt. Det datum kalendern sk sluta
@Param 3 Valfri. Namn på nyckelfält som inehåller heltalsrepresentationen av kalenderdagen.
@Param 4 Valfri. Ett prefix som identifierer både kalendertabell och fältnamn. Default är <blank>
@variable IN vL.sublib.kalender.årmånadformat Det format som År-månad-fältet ska presenteras i. Default='YYYY MMM'.
@variable IN vL.sublib.kalender.tabellnamn Namn på kalendertabell. Evt. prefix angett som @param 4 tillkommer i slutgiltig tabellnam.
@variable IN vL.sublib.kalender.idag Brytpunkt mellan historik och framtid. Default=today().
*/
/*
* Konfigurering av kalenderparametrar
*/
LET vL.sublib.kalender.årmånadformat = if(len('$(vL.sublib.kalender.årmånadformat)')=0, 'YYYY MMM', vL.sublib.kalender.årmånadformat);
LET vL.sublib.kalender.tabellnamn = if(len('$(vL.sublib.kalender.tabellnamn)')=0, 'Kalender', vL.sublib.kalender.tabellnamn);
LET vL.sublib.kalender.idag= ;
LET FirstMonthOfYear= if(len('$(FirstMonthOfYear)')=0, 1, FirstMonthOfYear);
LET ReferenceDay= if(len('$(ReferenceDay)')=0, 1, ReferenceDay);
LET BrokenWeeks= if(len('$(BrokenWeeks)')=0, 1, BrokenWeeks);
LET FirstWeekDay= if(len('$(FirstWeekDay)')=0, 1, FirstWeekDay);
/*
* Stadfäster nyckelfält i kalendern.
* Använder @param3 _kalendernyckelfält, om ej definierat så används fältnamnet [%datum] .
*/
IF len(_kalendernyckelfält)>0 then
SET _kalendernyckelfält = $(_kalendernyckelfält);
ELSE
SET _kalendernyckelfält = %datum;
ENDIF
/*
* Skapar kalendertabell
*/
[$(_calendarPrefix)$(vL.sublib.kalender.tabellnamn)]:
NOCONCATENATE LOAD
num( temporärdatum) as [$(_kalendernyckelfält)] ,
Date(temporärdatum) as [$(_calendarPrefix)Datum],
weekday(temporärdatum, $(FirstWeekDay)) as [$(_calendarPrefix)Veckodag],
YearName(temporärdatum,0,$(FirstMonthOfYear)) as [$(_calendarPrefix)År],
dual(week([temporärdatum],$(FirstWeekDay) ,$(BrokenWeeks),$(ReferenceDay)),
week(addmonths(temporärdatum,1-$(FirstMonthOfYear)),$(FirstWeekDay) ,$(BrokenWeeks),$(ReferenceDay))
) as [$(_calendarPrefix)Vecka],
DUAL(Month(temporärdatum) ,
num(Month(MonthName(temporärdatum, +1- $(FirstMonthOfYear))))
) as [$(_calendarPrefix)Månad],
dual(date(MonthName(temporärdatum), '$(vL.sublib.kalender.årmånadformat)'),
MonthStart(temporärdatum)) as [$(_calendarPrefix)År-månad],
'Q'&Num(Ceil(Num(Month(temporärdatum))/3)) as [$(_calendarPrefix)Kvartal],
Dual('Q'&Ceil(month(temporärdatum)/3) & ' ' &Year(temporärdatum),
num(QuarterStart(temporärdatum)) ) as [$(_calendarPrefix)År-kvartal],
if(temporärdatum > (if(len('$(vL.sublib.kalender.idag)')=0, today(), date('$(vL.sublib.kalender.idag)'))), 'Framtid', 'Historik') as [Historik/Framtid]
;
LOAD
Date('$(_minKalenderdatum)') + RecNo()-1 AS temporärdatum
AUTOGENERATE
Date('$(_maxKalenderdatum)') - Date('$(_minKalenderdatum)') + 1;
SET vL.SetModifier.CleanCalender = År, Månad, Datum, [År-månad],Veckodag,Vecka,Kvartal,[År-kvartal], [Historik/Framtid];
// Year To Date Modifier
Let vL.SetModifier.YTD =
replace(
'$(vL.SetModifier.CleanCalender),
År=P({<$(vL.SetModifier.CleanCalender), Datum={''$1''}>}År),
Datum = {"<=¤(=Date(''$1''))"}',
'¤', '$');
// Month 2 Date
Let vL.SetModifier.Months2Date =
Replace(
'$(vL.SetModifier.CleanCalender),
Datum={">=¤(=date(rangemin(monthstart(''$1'',alt($2,0)),date(''$1''))))<=¤(=date(rangemax(monthend(''$1'',alt($2,0)),date(''$1''))))"}',
'¤','$');
//Rensar upp lokala variabler
LET vL.sublib.kalender.årmånadformat =;
LET vL.sublib.kalender.tabellnamn =;
LET _maxKalenderdatum=;
LET _minKalenderdatum=;
ENDSUB //Kalender
SUB sublib.kalenderfrånfält (vL.sublib.kalender.nyckelfält, _källa, _calendarPrefix)
// Ta reda på om minmax ska hämtas från specifik resident-tabell, qvd eller textfil.
IF len('$(_källa)')=0 THEN
SET vL.sublib.kalender.minmaxkälla = ";LOAD FieldValue('$(vL.sublib.kalender.nyckelfält)', recno()) as [$(vL.sublib.kalender.nyckelfält)]
AUTOGENERATE FieldValueCount('$(vL.sublib.kalender.nyckelfält)')";
kalender.minmaxtabell:
LOAD
max([$(vL.sublib.kalender.nyckelfält)])+0 as tempKalender.maxdatum,
min([$(vL.sublib.kalender.nyckelfält)])+0 as tempKalender.mindatum ;
LOAD
FieldValue('$(vL.sublib.kalender.nyckelfält)', recno()) as [$(vL.sublib.kalender.nyckelfält)]
AUTOGENERATE FieldValueCount('$(vL.sublib.kalender.nyckelfält)');
ELSEIF index('$(_källa)', '.') = 0 THEN
SET vL.sublib.kalender.minmaxkälla = 'RESIDENT $(_källa)';
kalender.minmaxtabell:
LOAD
max([$(vL.sublib.kalender.nyckelfält)])+0 as tempKalender.maxdatum,
min([$(vL.sublib.kalender.nyckelfält)])+0 as tempKalender.mindatum
RESIDENT $(_källa);
ELSEIF '.qvd' = lower(right('$(_källa)', 4)) THEN
SET vL.sublib.kalender.minmaxkälla = 'FROM $(_källa) (qvd)';
kalender.minmaxtabell:
LOAD
max([$(vL.sublib.kalender.nyckelfält)])+0 as tempKalender.maxdatum,
min([$(vL.sublib.kalender.nyckelfält)])+0 as tempKalender.mindatum
FROM $(_källa) (qvd);
ELSE
SET vL.sublib.kalender.minmaxkälla = 'FROM $(_källa)'; // Antar text fil
kalender.minmaxtabell:
LOAD
max([$(vL.sublib.kalender.nyckelfält)])+0 as tempKalender.maxdatum,
min([$(vL.sublib.kalender.nyckelfält)])+0 as tempKalender.mindatum
FROM $(_källa);
ENDIF
LET vL.sublib.kalender.minmaxkälla =;
// Byter ut europeisk decimalseperator ',' så att qlikview förstår att det är ett värde.
LET _maxKalenderdatum = replace(peek('tempKalender.maxdatum'), ',', '.');
LET _minKalenderdatum = replace(peek('tempKalender.mindatum'), ',', '.');
DROP table kalender.minmaxtabell;
CALL sublib.kalender( '$(_minKalenderdatum)','$(_maxKalenderdatum)','$(vL.sublib.kalender.nyckelfält)', _calendarPrefix )
LET _maxKalenderdatum=;
LET _minKalenderdatum=;
ENDSUB
SUB sublib.kalenderlänk(vL.sublib.kalender.faktatabell, vL.sublib.kalender.datumfält, vL.sublib.kalender.datumnyckel, vL.sublib.kalender.linkID)
/**
Skapar länkkalender med fälten,
[Fält som ska kopplas mot Fakta] - @Param 4
[Typ av datum] - fälten som skickas in i @Param 2 ex ([Fält 1], [Fält 2], [Fält 3]
[Länkfält till kalender] - @Param 3
@syntax CALL sublib.kalenderlänk(vL.sublib.kalender.faktatabell, vL.sublib.kalender.datumfält, vL.sublib.kalender.datumnyckel, _RowId)
@Syntax CALL sublib.kalenderlänk('Fact','[Date (Booking)], [Date (Start)]','%DateKey','TransactionID');
@Param 1 Tabell som innehåller fakta/transaktionsmängd, exempel "Fact"
@Param 2 Kommaseparerad lista med fält som skall tas från Fact/Transaction för att generera upp länkkalender.
Fältnamnen blir värden i "Kalender", exempel "Date1, Date2, Date3".
@Param 3 Fältnamn som skall kopplas mot masterkalender - exempel, "%DateKey"
@Param 4 Fältnamn som skall kopplas mot fakta/transaktionsmängd, exempel "TransactionID"
*/
[Kalenderlänk]:
CROSSTABLE([Kalender], $(vL.sublib.kalender.datumnyckel), 1)
LOAD DISTINCT
$(vL.sublib.kalender.linkID),
$(vL.sublib.kalender.datumfält)
RESIDENT
[$(vL.sublib.kalender.faktatabell)]
;
ENDSUB
Du kan hämta hem en Qlik Sense applikation som demonstrerar denna sub från Github veglar/qliksense-sublib/releases
Hittar du fel eller ser förbättringsmöjligheter i koden så lägg gärna ett ärende här: https://github.com/veglar/qliksense-sublib/issues