Skip to main content
Announcements
Join us at Qlik Connect for 3 magical days of learning, networking,and inspiration! REGISTER TODAY and save!
cancel
Showing results for 
Search instead for 
Did you mean: 
HoollooW
Contributor
Contributor

Mapping conditionnel selon somme des mapping des lignes précédentes

Bonjour, 

Dans le cadre de la construction d'une application, j'ai besoin de procéder à un mapping de valeurs "conditionné" à la somme des valeurs générées par les mappings appliqués sur lignes précédentes d'une table. 

En détail pour le contexte, nous avons un premier logiciel de saisie des temps alimenté par nos collaborateurs dont la structure de l'export est ainsi faites :

Date_OriUser_OriCustomer_OriContract_OriItem_OriQuantity_OriLabel_Ori
02/11/2020MTE0364099P800.5Exemple libellé
02/11/2020LBH0288001P012Saisie temps
02/11/2020MTE0288001P01A2Saisie temps
02/11/2020HAF0079701P012Saisie temps

 

Chaque mois, cette donnée est exporté dans un CRM qui en reprends la structure exacte, mais avec les spécificités suivantes :

  • Les codes utilisateurs sont tous substitués par une codification unique "OC1" (il y a donc perte du détail)
  • Certaines valeurs peuvent éventuellement être modifiées (code client, contrat ou item uniquement) pour corrections d'anomalies, mais ces corrections ne sont pas retranscrites dans l'outil d'origine.

La table finale après import dans le CRM et correction peut ainsi devenir :

Date_CrmUser_CrmCustomer_CrmContract_CrmItem_CrmQuantity_CrmLabel_Crm
02/11/2020OC10364099P800.5Exemple libellé
02/11/2020OC10288001P012Saisie temps
02/11/2020OC10288001P012Saisie temps
02/11/2020OC10288001P012Saisie temps

 

Pour mon application Qlik Sense, j'ai besoin d'extraire ces temps et la seule donnée fiable (car corrigée) est celle provenant du CRM. Cependant cette dernière n'ayant pas le détail des utilisateurs propriétaire des lignes, j'ai besoin de faire un croisement avec les données d'origine pour en retrouver le détenteur initial. 

Pour ce croisement, j'applique plusieurs mapping successif sur la base d'une concaténation de champs faisant office de clef d'identification en débutant par une recherche d'une égalité exacte entre ces clefs, puis à défaut de concordance trouvée, en appliquant plusieurs mapping tronqués d'un ou de plusieurs champs :

MappingIdentique:

MAPPING LOAD 

Date_Ori & '|' & Customer_Ori & '|' & Contract_Ori & '|' Item_Ori & '|' & Quantity_Ori & '|' & Label_Ori AS KEY,

User_Ori

RESIDENT OriginalDatabase;

MappingWithoutContract:

MAPPING LOAD 

Date_Ori & '|' & Customer_Ori & '|' Item_Ori & '|' & Quantity_Ori & '|' & Label_Ori AS KEY,

User_Ori

RESIDENT OriginalDatabase;

[...]

et ainsi de suite sur plusieurs combinaisons possibles par taux de certitudes (je vous passe le détail, j'ai environ 20 tables de mapping successifs pour évaluer toutes les combinaisons de corrections envisageables). Puis lors du chargement de la table extraite du CRM, l'application de ce mapping est ainsi fait :

Crm:

LOAD

Date_Crm, 

APPLYMAP('MappingIdentique', Date_Crm & '|' & Customer_Crm & '|' & Contract_Crm & '|' Item_Crm & '|' & Quantity_Crm & '|' & Label_Crm, APPLYMAP('MappingWithoutContract', Date_Crm & '|' & Customer_Crm & '|' Item_Crm & '|' & Quantity_Crm & '|' & Label_Crm, [... 20 mapping successifs appliqués par taux décroissant de certitude ... ], 'Error Mapping') AS User_Crm

Customer_Crm, 

Contract_Crm, 

Contract_Crm, 

Item_Crm, 

Quantity_Crm, 

Label_Crm

RESIDENT CrmDatabase;

 

En soit, cette méthodologie même si imparfaites en terme de fiabilité reste relativement fonctionnelle dans la majorité des cas. Cependant, je me retrouve avec un problème d'application de ce mapping dans le cas ou ma clef n'est pas unique, ce qui arrive spécifiquement dans le cas de figure où mes collaborateurs saisissent exactement la même ligne d'activité (même date / code client / code contrat / code item / quantité & libellé). Dans le cas de figure ci dessus, un tel mapping au final donnerait le résultat suivant :

Date_CrmUser_CrmCustomer_CrmContract_CrmItem_CrmQuantity_CrmLabel_Crm
02/11/2020MTE0364099P800.5Exemple libellé
02/11/2020LBH0288001P012Saisie temps
02/11/2020LBH0288001P012Saisie temps
02/11/2020LBH0288001P012Saisie temps

 

Mes trois dernières lignes étant identiques après concaténation des champs, et le mapping s'appliquant sur la première occurrence trouvée, je me retrouve à attribuer un propriétaire de ligne erroné.

 

Mon idée initialement était de construire une table intermédiaire qui soit la somme des temps par utilisateurs et par jours, et de "tester" cette table à la volée de l'application des mapping. 

Si le collaborateur par les application de valeurs sur les lignes précédentes voit son quota d'heure du jour atteins, ce n'est plus lui que je veux charger mais le collaborateur d'après (soit la nième occurrence du Applymap()), et ainsi de suite. 

Dans mon cas de figure, arrivée au chargement de ma troisième ligne, mon utilisateur LBH s'étant déjà vu attribuer son quota d'heure, ce ne peut plus être lui qui soit le détenteur des lignes à venir. 

 

Cela étant dit, entre mon idée et sa matérialisation, il y a un léger gap 😂

La seule alternative qui me vienne en tête passe par des boucles, des tables temporaires par utilisateurs et des RangeSum() (entre autres choses...) mais avec plusieurs millions de lignes à traiter, je sais que l'optimisation du temps de traitement ne sera pas au rendez vous...

 

Une âme charitable et expérimentée aurait elle un début de piste / alternative / idée lumineuse à me proposer ? 

Au besoin je peux construire un export simplifié (et nettoyé) de mon cas de figure pour mieux illustrer mon propos (car je doutes que mon pavé ci dessus soit si compréhensible 😋).

D'avance merci.  

 

Labels (4)
2 Replies
brunobertels
Master
Master

Bonjour 

Tu as posé ta question dans le forum en anglais ..pas sur que tu aies beaucoup de réponse.  J'ai lu ta longue demande et en effet c'est complexe pour "retrouver tes petits". 

Toutefois si la base CRM est dans le même ordre de chargement que ta base d'origine , j'essaierai d'ajouter un champ "numéro de ligne" dans la base d'origine et dans la base  CRM au chargement avec Rowno() ou Recno()  ainsi tu aurais un ID unique et fiable entre tes deux bases et tu pourrais t'en servir comme clé pour un applymap ? 

Mais c'est peut être bien plus compliqué que cela....

HoollooW
Contributor
Contributor
Author

Bonjour et merci beaucoup pour ton temps et ton retour, 

C'est une piste que j'ai exploré et qui aurait pu être fonctionnelle, mais malheureusement ce jeu d'import / exports entre les deux outils génère parfois des blocages temporaires de lignes (le temps qu'une correction soit apportée) et donc un décalage de ligne. Les X premières lignes jusqu'au premier blocage sont dans un ordre identique, mais dès le premier blocage rencontré (et pour tous les suivants), ces lignes une fois corrigées sont positionnées en dernière place. Cela peut représenter 1% de retraitement sur des batch de 50 000 lignes mensuelles, ce qui est entraine assez rapidement un décalage difficile à détricoter... 

En fait dans cette approche comme dans mon optique initiale, ce qui m'aurait permis d'avancer serait l'utilisation d'une variable que je réactualiserais au chargement de chaque de ligne dans mon script, mais hormis le faire via une boucle Row by Row, je ne vois pas comment actualiser une variable au sein d'un même Load.