Se vi siete occupati di Controllo di Gestione, avrete sicuramente incontrato il problema della "competenza", e della necessità di ripartire dei valori riferiti ad un periodo, sui corrispondenti mesi.
Qualche esempio ? il canone periodico di un affitto, un abbonamento, un contratto di assistenza.... il pagamento avviene ad una certa data, ma copre un periodo, ed in genere c'è il bisogno di suddividere il costo sui mesi.
La cosa può sembrare un tantino complicata se il perido è identificato da due date (inizio e fine) che con coincidono con l'inizio e la fine del mese.
Quella che propongo, è una soluzione basata sulla funzione while.
Supponiamo che i dati siano un budget; ogni riga è identificata da un Codice, un Periodo ed un Importo, del tipo:
Budget:
Load * inline [
BDGcodice, BDGinizio, BDGfine, BDGimporto
A, 15/01/2008, 02/02/2008, 100
B, 03/01/2008, 03/02/2008, 100
C, 15/09/2008, 02/02/2009, 100
];Lo script per generare una tabella con l'importo (BDGimporto) suddiviso per mese è:
BudgetRipartito:
Load
BDGcodice
,BDGinizioPeriodo
,BDGfinePeriodo
,BDGimporto * (BDGfinePeriodo - BDGinizioPeriodo + 1)
/ (BDGfine - BDGinizio + 1)
as BDGimportoPeriodo;
Load
*
,if(iterNo()=1
,BDGinizio
,addMonths(makeDate(year(BDGinizio),month(BDGinizio)),iterNo()-1)
) as BDGinizioPeriodo
,if(iterNo()=BDGnumMesi
,BDGfine
,addMonths(makeDate(year(BDGinizio),month(BDGinizio)),iterNo())-1
) as BDGfinePeriodo
while iterNo() <= BDGnumMesi;
Load
*
,BDGmeseFine - BDGmeseInizio + 1 as BDGnumMesi;
Load
BDGimporto
,BDGcodice
,BDGinizio
,BDGfine
,year(BDGinizio)*12 + Month(BDGinizio) as BDGmeseInizio
,year(BDGfine)*12 + Month(BDGfine) as BDGmeseFine
resident Budget;
Qualche spiegazione potrebbe essere utile:
Beh, le load sono scritte in cascata: QlikView passa il risultato di quella più "bassa" a quella immediatamente superiore. Io trovo questa tecnica più facile da leggere rispetto alla "nidificazione" delle funzioni, ma forse è questione di gusti. Invece mi sembra una tecnica molto utile per "perdere" dei campi che all'inizio servono e poi non servono più... invece di crearli e poi farne la drop, con questa tecnica è sufficiente non citarli nelle load superiore, cioè quella che - finalmente - inserisce i dati nella tabella in memoria.
Poi forse avrete notato il mio vezzo di mettere la virgola all'inizio della riga successiva.. potrei tenervi ore sul significato della cosa, ma ve lo risparmio; prendetelo per quello che è.. un vezzo.
Finalmente arriviamo alla funzione WHILE; prima di tutto contiamo il numero di mesi che sono "toccati" dal periodo. A questo punto, se abbiamo in INPUT un record, in OUTPUT ne dovremo avere uno per ciascun mese "toccato". La funzione WHILE permette di ripetere la scrittura del record più volte. Ovviamente bisogna "contare" a che punto siamo arrivati, e questo lo fa la funzione iterNo(), che appunto "conta" le ripetizioni fatte.
Il resto è semplice matematica con le date.... però funziona !
