AXOPEN

Planisware : comment optimiser le parcours d’une classe avec la relation inverse ?

Problématique

Il est fréquent en script Planisware (OJS) d’avoir à rechercher des éléments dans une classe donnée (affectations, tâches, dépenses etc…). La performance de cette recherche dépend principalement de deux facteurs :

  • La volumétrie totale des objets de la classe parcourue
  • La manière dont les objets de la classe sont parcourus

Pour optimiser ce deuxième point, Planisware met à disposition un outil permettant de parcourir des ensembles d’objets restreints : les relations inverses.

Cette méthode permet de ne parcourir que les objets en relation avec un objet donné, et de la sorte, optimiser grandement les temps de parcours.

Dans la suite de cet article, nous allons présenter les différents types de relations inverses qu’il est possible de rencontrer dans Planisware

1. Les relations natives Planisware

Pour illustrer comment fonctionne le parcours de relation inverse native Planisware, nous allons nous baser sur l’exemple de la relation activité-affectations (N affectations pour 1 activité). Dans ce cas particulier, la relation est native du noyau Planisware (chaque affectation possède un lien vers une activité). On pourra alors utiliser l’instruction « fromobject » permettant de limiter le parcours des objets à ceux liés à mon activité de départ.

Côté script cela se traduit de la manière suivante :

var o_activity = "OpxActivity".get("ID_ACTIVITY");

fromobject(o_activity)
{
   for(var o_allocation in OpxAllocation)
   {
    …
   }
}

Ici la boucle sur les affectations n’itèrera que sur les affectations liées à mon activité dont l’identifiant est ID_ACTIVITY. Dans application possédant des milliers de projets et des millions d’affectations utiliser ce type de parcours est indispensable.

Dans ce cas le parcours des affectations est optimisé par les règles heuristiques de l’instruction « fromobject ».

On peut utiliser cette même méthode pour la recherche d’objets (affectations, activités…) dans un projet donné.

2. Cas de relations non natives

On parle de relation non native lorsque la relation entre 2 objets est issue du paramétrage Processes standard ou de paramétrage spécifique à une application donnée. Cela se traduit par la définition d’un champ attribut relation dans le modèle de données Planisware.

Par exemple la table des « Issues » dans Processes (_IS_PT_WF_ISSUE) possède un lien vers la classe activité via le champ _IS_RA_ISSUE_ACTIVITY. Si l’on souhaite parcourir les « Issues » d’une activité donnée, le fromobject n’est pas recommandé (il est possible qu’il ne fonctionne pas : exemple de régression sur ce point entre la version 5.3.2.9 et la 5.3.2.10).

Pour plus de sécurité il est préférable d’opter pour le mécanisme des relations inverse qui est préconisé comme étant la meilleure pratique par l’éditeur.

Voici un exemple de script utilisant la relation inverse dans le cas du parcours des Issues :

var o_activity = "OpxActivity".get("ID_ACTIVITY");

for(var o_issue in o_activity.get(r._IS_RA_ISSUE_ACTIVITY._IS_PT_WF_ISSUE))
{
 …
}

Dans ce cas on spécifie a Planisware de ne parcourir que les Issues liées à mon activité de départ via le champ _IS_RA_ISSUE_ACTIVITY.

On peut illustrer la recherche par l’illustration suivante :

Recherche via relation inverse

Recherche via relation inverse

Grâce à cette syntaxe Planisware parcourt uniquement les lignes surlignées en bleu.

Une syntaxe fonctionnement équivalente serait la suivante mais les performances seraient très dégradées.

var o_activity = "OpxActivity".get("ID_ACTIVITY"); 

for(var o_issue in Opx_IS_PT_WF_ISSUE where o_issue._IS_RA_ISSUE_ACTIVITY==o_activity)
{ 
 … 
}

Dans cette syntaxe non optimisée Planisware parcourt toutes les lignes puis sélectionne celles surlignées en bleu.

Pour généraliser la syntaxe de rechche via relation inverse est donc la suivante :

for (var o_linked_object in o_origin_object.get(r.<ID_CHAMP_RELATION>.<CLASSE_DES_OBJETS_PARCOURUS>)

Cette syntaxe est à ce jour la meilleure manière d’optimiser ce type de parcours.

3. Relation inverse et fromobject

Il est important de noter que la syntaxe d’une relation inverse utilise l’instruction « get ». Cette instruction bypasse les restrictions comme le fromobject. Par exemple si je fais un fromobject sur un projet et que j’implémente ensuite une boucle de relation inverse sur les affectations d’une ressource donnée, Planisware va renvoyer l’ensemble des affectations de la ressource et pas seulement celles contenues dans mon projet de départ.

Dans ce cas il faudra impérativement rajouter une clause « where » dans la boucle de recherche pour la restreindre aux objets contenus dans le projet souhaité.

A noter que dans un tel cas on pourra se poser la question de la condition la plus restrictive (entre le fromobject et la relation inverse) pour optimiser le traitement.

 

PS : Merci à Laurent pour sa relecture attentive !