Skip to main content
Announcements
Have questions about Qlik Connect? Join us live on April 10th, at 11 AM ET: SIGN UP NOW
cancel
Showing results for 
Search instead for 
Did you mean: 
chris987
Contributor III
Contributor III

Date jour et date position

Bonjour,

Je suis confronté à une colle, j’ai des ventes par jour, et par mois, et je souhaiterai pouvoir sortir un tableau avec les ventes et les jours sur un mois.

La partie compliquée est que je souhaite obtenir un affichage avec non pas le jour(date), mais sa position dans le mois, et là je ne trouve pas.

 

 

Sauriez-vous m’aider ?

Par avance merci

 

Cordialement

Christophe

 

Labels (1)
1 Solution

Accepted Solutions
chris987
Contributor III
Contributor III
Author

Bonjour à tous et merci pour vos réponses, j'ai réussi à obtenir le résultat souhaité.

Pour les personnes qui, comme moi ont ce problème, voici ma solution (elle est sans doute optimisable, mais cela fonctionne).

L'idée : générer un calendrier classique, avec un champ supplémentaire 'IsWorked'  basé sur un calcul de la position des jours dans le mois en excluant les week-end et jours fériés (voir images dans la question).

Let vMinDate=num('01/01/2014');
Let vMaxDate=num('31/12/2015');

TMP1:
LOAD
date($(vMinDate) + rowno() - 1) AS D,
year($(vMinDate) + rowno() - 1) AS Y,
month($(vMinDate) + rowno() - 1) AS M,
Date(monthstart($(vMinDate) + rowno() - 1), 'MMM-YYYY') AS MY,
Date(monthstart($(vMinDate) + rowno() - 1), 'YYYY-MM') AS MY2,
day($(vMinDate) + rowno() - 1) AS DD,
num(weekday(date($(vMinDate) + rowno() - 1))) as NumJour,
if(num(weekday(date($(vMinDate) + rowno() - 1)))<5,1,0) as IsWorkedTmp
AUTOGENERATE (vMaxDate - vMinDate) + 1;

// Holidays ----------------------------------------------------------
LET NewYr = '';
LET WorkDay = '';
LET UnitDay = '';
LET NationalDay ='';
LET Assomption = '';
LET Armistice = '';
LET AllSaints = '';
LET Xmas = '';
LET vLPaques= '';
LET vAscen = '';
LET vPentec = '';


//France
FOR Y=peek('Y', 0, 'TMP1') TO peek('Y', -1, 'TMP1')
     LET NewYr=NewYr & ',' & chr(39) & makedate($(Y), 1, 1) & chr(39);     // Jour de l'an (fixe)
     LET WorkDay=WorkDay & ',' & chr(39) & makedate($(Y), 5, 1) & chr(39);      // 1er mai (fixe)
     LET UnitDay=UnitDay & ',' & chr(39) & makedate($(Y), 5, 😎 & chr(39);     // 8 mai 1945  (fixe)
     LET NationalDay=NationalDay & ',' & chr(39) & makedate($(Y), 5, 😎 & chr(39);  // 14 juillet  (fixe)
     LET Assomption=Assomption & chr(39) & makedate($(Y), 8, 15) & chr(39);   // Assomption  (fixe)
     LET Armistice=Armistice & ',' & chr(39) & makedate($(Y), 5, 😎 & chr(39);    // Armistice 11/11  (fixe)
     LET AllSaints=AllSaints & ',' & chr(39) & makedate($(Y), 11, 1) & chr(39);     // Toussaint  (fixe)
     LET Xmas=Xmas & ',' & chr(39) & makedate($(Y), 12, 25) & chr(39);     // Noël  (fixe)
     LET vLPaques=vLPaques & ',' & chr(39) & Date(Round(makedate($(Y),4,day(Minute($(Y)/38)/2+55))/7)*7-6+1) & chr(39);  // Lundi de Paques  (Variable)
     LET vAscen=vAscen & ',' & chr(39) & Date(Round(makedate($(Y),4,day(Minute($(Y)/38)/2+55))/7)*7-6+39) & chr(39);     // Ascenssion  (Variable)
     LET vPentec=vPentec & ',' & chr(39) & Date(Round(makedate($(Y),4,day(Minute($(Y)/38)/2+55))/7)*7-6+50) & chr(39);   // Pentecote selon les entreprises  (Variable)

NEXT

// All Holidays in one variable to use in networkdays() and similar functions
LET H = mid(NewYr & WorkDay & UnitDay & NationalDay & Assomption & Armistice & AllSaints & Xmas & vLPaques & vAscen & vPentec, 2);


// Holiday fields, if needed -----------------------------
JOIN (TMP1) LOAD DISTINCT
     D,
     if(match(date(D, 'DD/MM/YYYY'), $(H)), 1, 0) as IsHoliday
RESIDENT TMP1;


// End of Holidays section ----------------------------------------------
LET Y = null();
LET NewYr = '';
LET WorkDay = '';
LET UnitDay = '';
LET NationalDay ='';
LET Assomption = '';
LET Armistice = '';
LET AllSaints = '';
LET Xmas = '';
LET vLPaques= '';
LET vAscen = '';
LET vPentec = '';

TMP1b:
LOAD  *,
  if(IsWorkedTmp=1 and IsHoliday=0,1,0) as IsWorked
Resident TMP1;
Drop Table TMP1;

TMP2:
LOAD  *,
  if(DD=1 and IsWorked=1 ,1,if(DD=1 and IsWorked=0 ,0,rangesum(IsWorked,Peek(Position)))) as Position
Resident TMP1b;

Calendar:
NOCONCATENATE LOAD D,Y,M,DD,MY,MY2,NumJour,IsWorked,if(IsWorked,Position,0) as Position
Resident TMP2;

DROP TABLES TMP2, TMP1b;

Calendrier:
LOAD
D AS link_Date,
D AS Date,
DD as NoJour,
Position,
NumJour,
IsWorked,
Y AS Year,
M AS Month,
MY AS MonthYear,
MY2 AS YearMonth

RESIDENT Calendar;
DROP TABLES Calendar;

Encore merci et bonne journée.

View solution in original post

8 Replies
Not applicable

Bonjour,

1- Je pense que la solution passe par une modification du script. Il faudrait ajouter un champ MonthDayPosition dans une des tables de ton modèle, idéalement la table calendrier si tu en as une.

2- Pour le calcul de ce nouveau champ ça dépend de ce que tu veux faire :

- la position est-elle basée sur les jours où il y a eu des ventes ?

- la position est-elle basée sur les jours ouvrés ?

- ...

Cordialement,

Xavier.

chris987
Contributor III
Contributor III
Author

Bonjour Xavier, et merci pour ta première réponse.

En fait, La position est basée sur les jours ouvrés, car en théorie je n'ai pas de vente effectuées sur les week-end et congés.

J'ai un calendrier basique qui reprend tous les jours de l'année, et je ne vois pas comment créer ce fameux champ MonthDayPosition.

Aurais-tu un bout de script à me proposer ?

Merci

Christophe

cje
Employee
Employee

Bonjour,

Au regard de ce que je comprends, votre logique de numérotation des positions du jour dans le mois élimine les dimanches, les jours fériés et les jours pour lesquels le CA est 0 sur l’année de référence. La solution passe par une table calendrier qui contiendra un flag permettant d’éliminer les dimanches (weekday(madate)=’dim.’ ou num(weekday(madate)) =6 ) et jours fériés spécifiques.

Ensuite on traite les données en rajoutant un numéro d’ordre avec un test sur le flag.

Ci-jointe une petite appli permettant d’approcher la solution. Jeu de données fictives.

Cdt

Christophe Jouve

Principal Solution Architect

Direct: +33 1 55 62 65 54

Mobile: +33 6 76 24 22 47

Email: Christophe.Jouve@qlik.com

Qlik

France Headquarters Office,93 avenue Charles de Gaulle

92200 Neuilly sur Seine

qlik.com<http://www.qlik.com/>

Téléchargez gratuitement QlikView

http://www.qlikview.com/fr/explore/experience/free-download

<http://www.qlik.com/us/explore/products/sense/desktop?SourceID1=Corporate_Email_Signature>

The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

brunobertels
Master
Master

Bonjour

Voici peut être une approche , mais très basique

A partir d'une table simple comme celle ci ci dessous qui reprend votre modèle :

On peut ajouter dans le script la fonction autonumber comme ceci :

LOAD

if(sales>0,autonumber("date"))as ID,

    "date",

    sales

FROM [lib://Help Test/autonumber.xls]

(biff, embedded labels, table is Feuil1$);

ce qui permet d'avoir ceci en tableau :

Et ceci en enlevant les valeurs nulles :

Bruno

benleroy
Partner - Contributor II
Partner - Contributor II

Bonjour Christophe,

Je pense comme pour les autres réponses qu'il créer la dimension position lors du chargement des données.

Pour cela j'utilise la fonction rowNo() et le tri (order by)

J'arrive à créer la dimension souhaitée mais en plusieurs étapes, peut-être peut-on optimiser cela.

J'ai mis le code en pièce jointe. (basé sur les premières valeurs de l'exemple fourni)

Bonne continuation.

Benoît

chris987
Contributor III
Contributor III
Author

Bonjour Christophe

Pour le moment je me suis arrêté là :

Let vMinDate=num('01/01/2014');
Let vMaxDate=num('31/12/2015');

DateIsland:
LOAD
date($(vMinDate) + rowno() - 1) AS D,
year($(vMinDate) + rowno() - 1) AS Y,
month($(vMinDate) + rowno() - 1) AS M,
day($(vMinDate) + rowno() - 1) AS DD,
num(weekday(date($(vMinDate) + rowno() - 1))) as NumJour
AUTOGENERATE (vMaxDate - vMinDate) + 1;
 
data2015:
load D, RowNo() as NumRow Resident DateIsland where NumJour<5;


Et cela me donne ceci (hors colonne souhait)

 

DMYDDNumJourNumRowSouhait
28/01/2014janv.20142812020
29/01/2014janv.20142922121
30/01/2014janv.20143032222
31/01/2014janv.20143142323
01/02/2014févr.201415
02/02/2014févr.201426
03/02/2014févr.201430241
04/02/2014févr.201441252
05/02/2014févr.201452263
06/02/2014févr.201463274
07/02/2014févr.201474285


Y a t'il y moyen lorsque je change de mois et d'année, le compteur (Numrow) reparte à 1 comme dans la colonne Souhait ?

Merci à tous pour votre aide et vos premières réponses.

Christophe

Not applicable

Bonjour Christophe,

Ci-joint une solution basée sur ton script avec calcul de la position à l'ai des fonction RangeSum et Peek (j'avais planché sur un sujet similaire ici : increment field on dimension changes).

Il faudrait voir à changer le Calcul de IsWorked dans la table TMP1 pour inclure les jours fériés, normalement le reste suivra tout seul.

Let vMinDate=num('01/01/2015');
Let vMaxDate=num('31/12/2015');

TMP1:
LOAD
date($(vMinDate) + rowno() - 1) AS D,
year($(vMinDate) + rowno() - 1) AS Y,
month($(vMinDate) + rowno() - 1) AS M,
day($(vMinDate) + rowno() - 1) AS DD,
num(weekday(date($(vMinDate) + rowno() - 1))) as NumJour,
if(num(weekday(date($(vMinDate) + rowno() - 1)))<5,1,0) as IsWorked
AUTOGENERATE (vMaxDate - vMinDate) + 1;
 
TMP2:
LOAD
*,
if(DD=1 and IsWorked=1,1,if(DD=1 and IsWorked=0,0,rangesum(IsWorked,Peek(Position)))) as Position
Resident TMP1;

Calendrier:
NOCONCATENATE LOAD D,Y,M,DD,NumJour,IsWorked,if(IsWorked,Position,0) as Position
Resident TMP2;


DROP TABLES TMP1, TMP2;

chris987
Contributor III
Contributor III
Author

Bonjour à tous et merci pour vos réponses, j'ai réussi à obtenir le résultat souhaité.

Pour les personnes qui, comme moi ont ce problème, voici ma solution (elle est sans doute optimisable, mais cela fonctionne).

L'idée : générer un calendrier classique, avec un champ supplémentaire 'IsWorked'  basé sur un calcul de la position des jours dans le mois en excluant les week-end et jours fériés (voir images dans la question).

Let vMinDate=num('01/01/2014');
Let vMaxDate=num('31/12/2015');

TMP1:
LOAD
date($(vMinDate) + rowno() - 1) AS D,
year($(vMinDate) + rowno() - 1) AS Y,
month($(vMinDate) + rowno() - 1) AS M,
Date(monthstart($(vMinDate) + rowno() - 1), 'MMM-YYYY') AS MY,
Date(monthstart($(vMinDate) + rowno() - 1), 'YYYY-MM') AS MY2,
day($(vMinDate) + rowno() - 1) AS DD,
num(weekday(date($(vMinDate) + rowno() - 1))) as NumJour,
if(num(weekday(date($(vMinDate) + rowno() - 1)))<5,1,0) as IsWorkedTmp
AUTOGENERATE (vMaxDate - vMinDate) + 1;

// Holidays ----------------------------------------------------------
LET NewYr = '';
LET WorkDay = '';
LET UnitDay = '';
LET NationalDay ='';
LET Assomption = '';
LET Armistice = '';
LET AllSaints = '';
LET Xmas = '';
LET vLPaques= '';
LET vAscen = '';
LET vPentec = '';


//France
FOR Y=peek('Y', 0, 'TMP1') TO peek('Y', -1, 'TMP1')
     LET NewYr=NewYr & ',' & chr(39) & makedate($(Y), 1, 1) & chr(39);     // Jour de l'an (fixe)
     LET WorkDay=WorkDay & ',' & chr(39) & makedate($(Y), 5, 1) & chr(39);      // 1er mai (fixe)
     LET UnitDay=UnitDay & ',' & chr(39) & makedate($(Y), 5, 😎 & chr(39);     // 8 mai 1945  (fixe)
     LET NationalDay=NationalDay & ',' & chr(39) & makedate($(Y), 5, 😎 & chr(39);  // 14 juillet  (fixe)
     LET Assomption=Assomption & chr(39) & makedate($(Y), 8, 15) & chr(39);   // Assomption  (fixe)
     LET Armistice=Armistice & ',' & chr(39) & makedate($(Y), 5, 😎 & chr(39);    // Armistice 11/11  (fixe)
     LET AllSaints=AllSaints & ',' & chr(39) & makedate($(Y), 11, 1) & chr(39);     // Toussaint  (fixe)
     LET Xmas=Xmas & ',' & chr(39) & makedate($(Y), 12, 25) & chr(39);     // Noël  (fixe)
     LET vLPaques=vLPaques & ',' & chr(39) & Date(Round(makedate($(Y),4,day(Minute($(Y)/38)/2+55))/7)*7-6+1) & chr(39);  // Lundi de Paques  (Variable)
     LET vAscen=vAscen & ',' & chr(39) & Date(Round(makedate($(Y),4,day(Minute($(Y)/38)/2+55))/7)*7-6+39) & chr(39);     // Ascenssion  (Variable)
     LET vPentec=vPentec & ',' & chr(39) & Date(Round(makedate($(Y),4,day(Minute($(Y)/38)/2+55))/7)*7-6+50) & chr(39);   // Pentecote selon les entreprises  (Variable)

NEXT

// All Holidays in one variable to use in networkdays() and similar functions
LET H = mid(NewYr & WorkDay & UnitDay & NationalDay & Assomption & Armistice & AllSaints & Xmas & vLPaques & vAscen & vPentec, 2);


// Holiday fields, if needed -----------------------------
JOIN (TMP1) LOAD DISTINCT
     D,
     if(match(date(D, 'DD/MM/YYYY'), $(H)), 1, 0) as IsHoliday
RESIDENT TMP1;


// End of Holidays section ----------------------------------------------
LET Y = null();
LET NewYr = '';
LET WorkDay = '';
LET UnitDay = '';
LET NationalDay ='';
LET Assomption = '';
LET Armistice = '';
LET AllSaints = '';
LET Xmas = '';
LET vLPaques= '';
LET vAscen = '';
LET vPentec = '';

TMP1b:
LOAD  *,
  if(IsWorkedTmp=1 and IsHoliday=0,1,0) as IsWorked
Resident TMP1;
Drop Table TMP1;

TMP2:
LOAD  *,
  if(DD=1 and IsWorked=1 ,1,if(DD=1 and IsWorked=0 ,0,rangesum(IsWorked,Peek(Position)))) as Position
Resident TMP1b;

Calendar:
NOCONCATENATE LOAD D,Y,M,DD,MY,MY2,NumJour,IsWorked,if(IsWorked,Position,0) as Position
Resident TMP2;

DROP TABLES TMP2, TMP1b;

Calendrier:
LOAD
D AS link_Date,
D AS Date,
DD as NoJour,
Position,
NumJour,
IsWorked,
Y AS Year,
M AS Month,
MY AS MonthYear,
MY2 AS YearMonth

RESIDENT Calendar;
DROP TABLES Calendar;

Encore merci et bonne journée.