Masterkalender

Masterkalender är ett återanvändbart masterkalenderskript som kan hantera flera kalenderbehov. Den kan bland annat hantera följand scenarion.

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

  1. [obligatorisk] Första datum i kalendern.
  2. [obligatorisk] Sista datum i kalendern
  3. [valfri] Nyckelfältnamn i kalendern.
  4. [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.

  1. [obligatorisk] Kalendernyckelfält. Det fält som det ska kopplas en kalender på.
  2. [valfri] Källa som innehåller pinpointar kalenderfältets källa.
  3. [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