Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
Bonjour,
Voici ma structure :
1 table "dimension" CLIENT :
"N° client"
"Secteur"
"Nom"
"prénom"
....
1 table "dimension" PRODUIT :
"Ref"
"Désignation"
"groupe produit"
....
1 table "dimension" CALENDRIER
"date"
"mois"
"année"
....
puis,
1 table "de fait" FACTURE :
"N° client"
"date"
"Ref"
"Qte facture"
"Montant facture"
.....
1 table "de fait" AVOIR :
"N° client"
"date"
"Ref"
"Qte facture"
"Montant facture"
......
Mon objectif : c'est de calculer le CA net 'facture - avoir' en fonction d'une classification Client et/ou Produits et en fonction du temps.
Problème : En faisant cette structure qlikview me génère un cycle donc ça ne va pas
Merci d'avance pour vos remarques et analyses
Mathieu
Il vous faut enlever le QUALIFY * et le UNQUALIFY "KEY_*" puisque avec la méthode Link_Table, vous n'aurez plus de boucles.
De même, n renommer pas les champs :
REF en KEY_REF
et
[N° client] en KEY_client
Cela donne le code suivant:
// Idem Original
//---------------------------------------------------------------------------------------------//LET vDateMin = Num(MakeDate(2010,1,1));LET vDateMax = Num(MakeDate(2015,1,1));//Floor(YearEnd(AddMonths(Today(), 12)));LET vDateToday = Num(Today());
TempCalendar:LOAD$(vDateMin) + RowNo() - 1 AS DateNumber,Date($(vDateMin) + RowNo() - 1) AS TempDateAUTOGENERATE 1WHILE $(vDateMin)+IterNo()-1<= $(vDateMax);
MasterCalendar:LOADTempDate as KEY_date,Day(TempDate) AS Day,Month(TempDate) AS Month,Year(TempDate) AS Year,Today() as DayNowRESIDENT TempCalendar ORDER BY TempDate ASC;
DROP TABLE TempCalendar;
LET vDateMin = Num(MakeDate(2010,1,1));LET vDateMax = Num(MakeDate(2015,1,1));//Floor(YearEnd(AddMonths(Today(), 12)));LET vDateToday = Num(Today());
// Suppression des QUALIFY et UNQUALIFY
// Chargement initial sans renommage
CLIENT :LOAD [N° client] , // AS KEY_client,
ZoneFROM
C:\Users\xxxxxxxxx\Desktop\BdD.xls
(biff, embedded labels, table is client$);
PRODUIT :LOAD REF , // , as KEY_REF,
GROUPEFROM
C:\Users\xxxxxxxxx\Desktop\BdD.xls
(biff, embedded labels, table is produit$);
AVOIR :LOAD
//N°,
[N° client],
REF,
QTE,
DATEFROM
C:\Users\xxxxxxxxx\Desktop\BdD.xls
(biff, embedded labels, table is Avoir$);
FACTURE :LOAD
// N°,
[N° client],
REF,
QTE,
DATE FROM
C:\Users\xxxxxxxxx\Desktop\BdD.xls
(biff, embedded labels, table is Facture$);
/ /Création de la Link_Table => Code du premier post
// Elimination des doublons propres à FACTURE
tmp_Link_Table:
NoConcatenate
LOAD DISTINCT
[N° client] ,
date ,
ref
RESIDENT FACTURE ;
// ELimination des doublons propres à AVOIR
Concatenate( tmp_Link_Table )
LOAD DISTINCT
[N° client] ,
date ,
ref
RESIDENT AVOIR ;
// Elimination des doublons dus aux combinaisons
// présentes dans les deux tables de fait
Link_Table :
NoConcatenate
LOAD DISTINCT
*
RESIDENT tmp_Link_Table ;
DROP TABLE tmp_Link_Table ;
FOR EACH table IN 'FACTURE' , 'AVOIR' , 'Link_Table'
LEFT JOIN( $(table)
LOAD
// champs_de_jointure
[N° client] ,
date ,
ref
//clé additionnelle
[N° client] & '|&|' & date & '|&|' & ref as clé
RESIDENT $(table) ;
// On ne garde les champs problématiques que dans la Link_Table
IF '$(table)' <> 'Link_Table' THEN
DROP FIELDS [N° client] , date , ref FROM $(table) ;
ENDIF
NEXT table ;
Ce message a été modifié par: Richard Pressanti: Oubli d'une virgule
Il vous faut créer une table de liens (en anglais Link Table) centrale qui assurera la connexion avec vos deux tables de faits et vos tables de dimensions.
Concrétement, votre table de liens contiendra vos 3 champs problématiques qui devront donc être supprimés des tables de fait. Tout le problème est de récupérer toutes les combianaisins distinctes de vos deux tables de liens.
Le code suivant devrait fonctionner.
// Elimination des doublons propres à FACTURE
tmp_Link_Table:
NoConcatenate
LOAD DISTINCT
[N° client] ,
date ,
ref
RESIDENT FACTURE ;
// ELimination des doublons propres à AVOIR
Concatenate( tmp_Link_Table )
LOAD DISTINCT
[N° client] ,
date ,
ref
RESIDENT AVOIR ;
// Elimination des doublons dus aux combinaisons
// présentes dans les deux tables de fait
Link_Table :
NoConcatenate
LOAD DISTINCT
*
RESIDENT tmp_Link_Table ;
DROP TABLE tmp_Link_Table ;
FOR EACH table IN 'FACTURE' , 'AVOIR' , 'Link_Table'
LEFT JOIN( $(table) )
LOAD
// champs_de_jointure
[N° client] ,
date ,
ref ,
//clé additionnelle
[N° client] & '|&|' & date & '|&|' & ref as clé
RESIDENT $(table) ;
// On ne garde les champs problématiques que dans la Link_Table
IF '$(table)' <> 'Link_Table' THEN
DROP FIELDS [N° client] , date , ref FROM $(table) ;
ENDIF
NEXT table ;
Ce message a été modifié par: Richard Pressanti: Correction d'erreurs de frappe.
Ce message a été modifié par: Richard Pressanti: Ajout d'une parenthèse manquante
Ce message a été modifié par: Richard Pressanti: Ajout d'une virgule manquante
Bonjour,
Merci de votre retour et pour le code.
Ok pour passer par une table de lien. Passer par une concatenation de mes 2 tables de fait est également une solution?
Par rapport au code :
J'ai un message d'erreur au chargement des données :
Champ introuvable - <N°>
tmp_Link_Table:
NoConcatenate
LOAD DISTINCT
N°,
[N° client],
REF,
QTE,
DATE
RESIDENT FACTURE
Ci dessous le code que j'utilise :
//---------------------------------------------------------------------------------------------//LET vDateMin = Num(MakeDate(2010,1,1));LET vDateMax = Num(MakeDate(2015,1,1));//Floor(YearEnd(AddMonths(Today(), 12)));LET vDateToday = Num(Today());
TempCalendar:LOAD$(vDateMin) + RowNo() - 1 AS DateNumber,Date($(vDateMin) + RowNo() - 1) AS TempDateAUTOGENERATE 1WHILE $(vDateMin)+IterNo()-1<= $(vDateMax);
MasterCalendar:LOADTempDate as KEY_date,Day(TempDate) AS Day,Month(TempDate) AS Month,Year(TempDate) AS Year,Today() as DayNowRESIDENT TempCalendar ORDER BY TempDate ASC;
DROP TABLE TempCalendar;
LET vDateMin = Num(MakeDate(2010,1,1));LET vDateMax = Num(MakeDate(2015,1,1));//Floor(YearEnd(AddMonths(Today(), 12)));LET vDateToday = Num(Today());
//---------------------------------------------------------------------------------------------////STRUCTURATION//QUALIFY*; // Tous les champs sont préfixés par le nom de la table //UNQUALIFY "KEY_*"; // Tous les champs qui commencent par KEY_xxxx ne seront pas préfixés par le nom de la table ////---------------------------------------------------------------------------------------------//
CLIENT :LOAD [N° client] AS KEY_client,
ZoneFROM
C:\Users\xxxxxxxxx\Desktop\BdD.xls
(biff, embedded labels, table is client$);
PRODUIT :LOAD REF as KEY_REF,
GROUPEFROM
C:\Users\xxxxxxxxx\Desktop\BdD.xls
(biff, embedded labels, table is produit$);
AVOIR :LOAD N°,
[N° client],
REF,
QTE,
DATEFROM
C:\Users\xxxxxxxxx\Desktop\BdD.xls
(biff, embedded labels, table is Avoir$);
FACTURE :LOAD N°,
[N° client],
REF,
QTE,
DATE FROM
C:\Users\xxxxxxxxx\Desktop\BdD.xls
(biff, embedded labels, table is Facture$);
//---------------------------------------------------------------------------------------------//
tmp_Link_Table:
NoConcatenateLOAD DISTINCT
N°,
[N° client],
REF,
QTE,
DATE RESIDENT FACTURE ;
// ELimination des doublons propres à AVOIRConcatenate( tmp_Link_Table )LOAD DISTINCT
N°,
[N° client],
REF,
QTE,
DATERESIDENT AVOIR ;
// Elimination des doublons dus aux combinaisons
// présentes dans les deux tables de faitLink_Table :NoConcatenateLOAD DISTINCT
*RESIDENT tmp_Link_Table ;
DROP TABLE tmp_Link_Table ;
FOR EACH table IN 'FACTURE' , 'AVOIR' , 'Link_Table'
LEFT JOIN( $(table)
LOAD
// champs_de_jointure [N° client] ,
DATE ,
REF
//clé additionnelle [N° client] & '|&|' & DATE & '|&|' & REF as clé
RESIDENT $(table) ;
// On ne garde les champs problématiques que dans la Link_Table IF '$(table)' <> 'Link_Table' THEN
DROP FIELDS [N° client] , DATE , REF FROM $(table) ;
ENDIF
NEXT table ;
//---------------------------------------------------------------------------------------------//
MERCI D'AVANCE POUR VOTRE AIDRE PRECIEUSE
Mathieu
Il vous faut supprimmer la ligne "N° ," qui pose problème. En effet, ce champ n'existe pas et il vous faut utiliser
[N° client] comme indiqué dans le code fourni.
Aie, j'ai toujours un message d'erreur au chargement
Champ introuvable - <N° client>
tmp_Link_Table:
NoConcatenate
LOAD DISTINCT
[N° client],
REF,
DATE
RESIDENT FACTURE
Il vous faut enlever le QUALIFY * et le UNQUALIFY "KEY_*" puisque avec la méthode Link_Table, vous n'aurez plus de boucles.
De même, n renommer pas les champs :
REF en KEY_REF
et
[N° client] en KEY_client
Cela donne le code suivant:
// Idem Original
//---------------------------------------------------------------------------------------------//LET vDateMin = Num(MakeDate(2010,1,1));LET vDateMax = Num(MakeDate(2015,1,1));//Floor(YearEnd(AddMonths(Today(), 12)));LET vDateToday = Num(Today());
TempCalendar:LOAD$(vDateMin) + RowNo() - 1 AS DateNumber,Date($(vDateMin) + RowNo() - 1) AS TempDateAUTOGENERATE 1WHILE $(vDateMin)+IterNo()-1<= $(vDateMax);
MasterCalendar:LOADTempDate as KEY_date,Day(TempDate) AS Day,Month(TempDate) AS Month,Year(TempDate) AS Year,Today() as DayNowRESIDENT TempCalendar ORDER BY TempDate ASC;
DROP TABLE TempCalendar;
LET vDateMin = Num(MakeDate(2010,1,1));LET vDateMax = Num(MakeDate(2015,1,1));//Floor(YearEnd(AddMonths(Today(), 12)));LET vDateToday = Num(Today());
// Suppression des QUALIFY et UNQUALIFY
// Chargement initial sans renommage
CLIENT :LOAD [N° client] , // AS KEY_client,
ZoneFROM
C:\Users\xxxxxxxxx\Desktop\BdD.xls
(biff, embedded labels, table is client$);
PRODUIT :LOAD REF , // , as KEY_REF,
GROUPEFROM
C:\Users\xxxxxxxxx\Desktop\BdD.xls
(biff, embedded labels, table is produit$);
AVOIR :LOAD
//N°,
[N° client],
REF,
QTE,
DATEFROM
C:\Users\xxxxxxxxx\Desktop\BdD.xls
(biff, embedded labels, table is Avoir$);
FACTURE :LOAD
// N°,
[N° client],
REF,
QTE,
DATE FROM
C:\Users\xxxxxxxxx\Desktop\BdD.xls
(biff, embedded labels, table is Facture$);
/ /Création de la Link_Table => Code du premier post
// Elimination des doublons propres à FACTURE
tmp_Link_Table:
NoConcatenate
LOAD DISTINCT
[N° client] ,
date ,
ref
RESIDENT FACTURE ;
// ELimination des doublons propres à AVOIR
Concatenate( tmp_Link_Table )
LOAD DISTINCT
[N° client] ,
date ,
ref
RESIDENT AVOIR ;
// Elimination des doublons dus aux combinaisons
// présentes dans les deux tables de fait
Link_Table :
NoConcatenate
LOAD DISTINCT
*
RESIDENT tmp_Link_Table ;
DROP TABLE tmp_Link_Table ;
FOR EACH table IN 'FACTURE' , 'AVOIR' , 'Link_Table'
LEFT JOIN( $(table)
LOAD
// champs_de_jointure
[N° client] ,
date ,
ref
//clé additionnelle
[N° client] & '|&|' & date & '|&|' & ref as clé
RESIDENT $(table) ;
// On ne garde les champs problématiques que dans la Link_Table
IF '$(table)' <> 'Link_Table' THEN
DROP FIELDS [N° client] , date , ref FROM $(table) ;
ENDIF
NEXT table ;
Ce message a été modifié par: Richard Pressanti: Oubli d'une virgule
On avance :
Les 3 dimensions sont bien liées avec la link_table. Dans la link_table j'ai bien les 3 champs problématiques
Le problème maintenant : la link_table n'a pas de jointure avec les 2 tables de fait
Lors du chargement des données, j'ai les 3 messages d'erreurs suivant :
Erreur de ligne de script :
LEFT JOIN( FACTURE
LOAD
[N° client] ,
DATE ,
REF
[N° client] & '|&|' & DATE & '|&|' & REF as clé
RESIDENT FACTURE
************************************************************************************
Erreur de ligne de script :
LEFT JOIN( AVOIR
LOAD
[N° client] ,
DATE ,
REF
[N° client] & '|&|' & DATE & '|&|' & REF as clé
RESIDENT AVOIR
************************************************************************************
Erreur de ligne de script :
LEFT JOIN( Link_Table
LOAD
[N° client] ,
DATE ,
REF
[N° client] & '|&|' & DATE & '|&|' & REF as clé
RESIDENT Link_Table
************************************************************************************
Au niveau du script, il semble que Qlikview n'aime pas tellement le code suivant :
//clé additionnelle
[N° client] & '|&|' & DATE & '|&|' & REF as clé
RESIDENT $(table)
Merci pour votre aide
Mathieu
Mea culpa ! J'ai oublié une parenthèse:
Il faut écrire :
LEFT JOIN( $(table) )
Oui en effet.. J'aurais pu le voir
Il manquait la petite virgule après REF .... et du coup, les données se chargent bien.
Ci dessous le résultat :
C'est parfait ! Merci beaucoup de voir aide
Je viens de dupliquer le code dans mon environnement de production
Je m'aperçois d'un problème. Le chargement des données est ok. Le problème apparait dans le résultat des données exploitées.
J'exploite les données via un tableau dans QV avec comme dimensions : ANNEE et MOIS et comme expressions : sum (Montant_Facture)
Pour certains mois, le résultat n'est pas juste car :
Pour une même date et pour les mêmes ref un même client peut passer 2 commandes
Par ex :
- CDE 1 - date : 16/04/2013 - REF A : 1 200 / REF B : 1 800 / REF C : 1 152
- CDE 2 - date : 16/04/2013 - REF A : 1 200 / REF B : 1 800 / REF C : 1 152 / REF D : 1 152 / REF C : 648 / REF ......
Du coup, le montant Facture de la cde1 est pris en compte une fois ET une deuxième fois avec le montant Facture de la cde2
Faut 'il agir dans le script via la clé ?
Ou faut'il agir dans mon expression en mettant quelque chose comme DISTINCT ?
Merci d'avance