FOX, le language de script de SAP BPC Embedded / Integrated Planning

fox, le langage de script de BPC embedded

Les formules dans SAP BPC Embedded / Integrated Planning

La nouvelle version de SAP BPC, SAP BPC Embedded, s’appuie sur BW-Integrated Planning pour la modélisation et les fonctions de calcul, et sur Planning Application Kit dans HANA pour l’exécution rapide « in-memory » de l’essentiel des traitements.

Avec SAP BPC Embedded, le Script Logic de BPC « standard » est remplacé par les formules FOX (Formula Extension), qui présentent l’avantage d’une certaine simplicité et de la puissance du calcul. FOX a déjà fait ses preuves depuis de nombreuses années car il a été créé lors de la première version du module de prévision intégré à BW, SEM-BPS, en 2001. Il est utilisé chez de nombreux clients pour répondre à des besoins liés au budget ou à des problématiques non couvertes par des solutions standards.

Avec le FOX, il est possible de répondre à des demandes de fonctions spécifiques sans avoir recours à un développement ABAP. Les fonctions de base sont déjà intégrées, comme la lecture des données, l’agrégation, les boucles, etc. Il s’adresse tout de même principalement à l’IT.

Au dela du FOX, il existe des fonctions pré-définies et paramétrables dans BPC Embedded / Integrated Planning, telles que la copie de données, la suppression, la distribution ou la revalorisation, mais le FOX permet de couvrir tous les autres besoins. Dans le cas ou la formule est trop complexe à créer en FOX, il est aussi possible, dans BPC  Embedded / IP, de créer ses propres fonctions en ABAP OO.

Techniquement, une formule FOX est compilée en programme ABAP, basé sur des modules fonctions prédéfinies. Ainsi, si une formule FOX donne un résultat erroné  il est toujours possible d’entrer en mode « debug » pour analyser le programme ABAP généré, pas à pas.

Périmètre de données et données de référence

Comme pour toutes les fonctions de BPC Embedded / Integrated Planning, les formules FOX vont s’appuyer sur un niveau d’agrégation. Il s’agit d’une sélection de dimensions qui forme le périmètre de données agrégé, qui sera enregistré dans le cube à l’issue du calcul. Les dimensions qui ne sont pas présentes dans le niveau seront placées automatiquement sur la valeur « non affectée».

Il faut distinguer à ce stade le périmètre des données qui seront écrites (qui sont évidemment lues au départ de la fonction pour effectuer au final le calcul du delta), et qui sont bloquées pendant le traitement, et les données de référence en lecture seule.

Les premières sont identifiées grâce aux filtres placés dans le niveau, soit « en dur », soit par des variables. Les secondes sont déduites automatiquement du script lui-même, ou explicitement dans la toute dernière version (grâce à KEEP et ENHANCE), à partir de données de cube ou de DSO. Dans certains cas, il est nécessaire d’élargir les filtres du niveau pour collecter certaines données utiles qui ne peuvent pas l’être automatiquement par interprétation de la formule.

Après exécution de la formule, les données ainsi générées sont comparées aux données lues initialement afin de produire un delta. C’est ce delta qui est envoyé dans l’infocube lors de la sauvegarde. Dans le cas d’une écriture dans un DSO, c’est la méthode « after-image » qui est employée.

Par exemple, si l’on souhaite copier des données de l’année 2016 vers 2017, le filtre sera placé sur l’année « 2017 » et les données de référence seront déduites du script sur « 2016 ».

Les données à modifier et les opérandes

En première étape, il faut indiquer quelles sont les données qui seront modifiées, c’est à dire les dimensions qui figureront comme « coordonnées » utilisables dans la formule. Dans notre exemple, puisque rien d’autre ne changera que l’année, on indiquera simplement l’année (0FISCYEAR) comme dimension à modifier.

Pour écrire ou lire une donnée dans une formule FOX la syntaxe sera toujours représentée par {Key figure, Dimension 1, Dimension 2, Dimension 3, etc…}. Les dimensions sont appelées les opérandes, elles permettent d’aller lire ou écrire n’importe quelle donnée dans le « paquet » envoyé à la formule. Dans notre exemple on aura donc la formule suivante : {0amount, 2017} = {0amount, 2016}.

Techniquement, le système sélectionne des « paquets » de données (dans une table temporaire en mémoire) représentant chaque combinaison de caractéristiques sélectionnée par le niveau (Client, Produit, Période, etc) excepté celles qui sont sélectionnées comme données à modifier (Année). Au sein de ce paquet et il va ensuite exécuter la formule. Dans notre exemple, si le niveau est défini avec les dimensions Produit et Client, il lancera la formule pour chaque combinaison Client x Produit figurant dans la sélection.

Si par erreur on a sélectionné le Produit comme donnée à modifier, FOX sélectionnera des paquets de données pour chaque client, et dans chaque paquet il sera nécessaire de passer par chaque produit dans la formule, grâce à une boucle FOREACH par exemple.

Le choix des dimensions « à modifier » est donc important car il définit la façon dont le système sélectionnera les « paquets » de données et la façon dont on  pourra adresser directement les données de ce « paquet ».

Pour finir sur ce sujet, FOX permet également d’appliquer une sélection directe sur une valeur de dimension qui n’existe pas dans les dimensions à modifier. La syntaxe serait par exemple {0amount ; 2006 | 0Material = 3434} pour lire uniquement les données du produit « 3434 ».

Les fonctions des formules FOX

En premier lieu, une formule peut utiliser des variables locales définies sur la base des dimensions ou de types de données classiques. Ces variables, déclarées en début de formule pourront être utilisées dans les conditions, les boucles, etc. La syntaxe est : Data <variable> Type <infoobjet> ou un type générique.

Les variables globales, qui peuvent être aussi utilisées dans les filtres du niveau, sont accessibles dans la formule FOX. Elles permettent d’utiliser des paramètres ou une liste de valeurs renseignés en amont par l’utilisateur ou par un programme ABAP

  • Varv : lecture de la valeur de la variable
  • Varc : lecture du nombre de valeurs dans un variable
  • Vari : lecture d’une des valeurs de la variable selon son numéro d’index

 Les fonctions suivantes permettent d’aller lire des valeurs de caractéristiques ou d’attributs. Elles sont particulièrement utiles par exemple pour appliquer un calcul en fonction d’une classification. Par exemple, la classification d’un client permet de déterminer les conditions de vente, et par conséquent la période d’encaissement consécutive à une vente.

  • Atrv : lire la valeur d’un attribut d’un infoobject
  • Atrvt : lire la valeur d’un attribut dépendant du temps
  • Objv : lire la valeur d’un infoobject figurant dans le « paquet » qui est traité

De nombreuses fonctions de boucles sont proposées, pour passer en revue des ensembles de données selon des critères différents.

  • Foreach <variables>… Endfor: permet de passer par chaque combinaison des caractéristiques, représentées par les variables, figurant dans le paquet
  • Foreach <variables> in Refdata…Endfor : permet de passer par chaque combinaison des caractéristiques, représentées par les variables, figurant dans les données de référence
  • Foreach <variables> in Selection…Endfor : permet de passer par chaque combinaison des caractéristiques, représentées par les variables, figurant dans la sélection
  • Foreach <variables> in Variable…Endfor : permet de passer par chaque combinaison des caractéristiques représentées par les variables, figurant dans une variable globale
  • Do…exit….enddo : boucle avec sortie conditionnelle
  • Do n Times…enddo : boucle sur un nombre d’occurences préféfinies

L’utilisation inappropriée des Foreach imbriqués peut conduire à des temps de réponse très long ou infini.

Nous allons également trouver toute une collection de fonctions diverses :

  • Mathématiques (Round, ABS, Trunc, etc)
  • Comparaison (>, <>, =, etc) et conditions (IF…Endif)
  • Chaines de caractère (Concat, Replace, Strlen…) et dates (TMVL)
  • Affichage de message (Message)
  • Appel à un module function ABAP (Call function) ou une fonction dans la formule (FORM)
  • Création de table temporaire avec TABLE

Exemple commenté

Dans cet exemple, on va valoriser les quantités de vente, saisies mois par mois, par client et par produit. Les prix de vente sont quant à eux saisis uniquement par année et par produit. Il y aura donc dans le paquet deux jeux de données renseignés à des niveaux de détail différents.

Dans les dimensions à modifier on choisit uniquement le client et la période. On n’a pas sélectionné l’article car il est commun aux deux jeux de données et n’est donc pas requis pour les distinguer. Dans chaque « paquet » envoyé à la formule FOX, on trouvera donc les quantités et les prix pour un même article et une même année.

DATA CLIENT TYPE 0CUSTOMER.
DATA PERIODE TYPE 0PERIOD.
DATA ARTICLE TYPE 0MATERIAL.

IF {PRIX,#,#} = 0.

   ARTICLE = OBJV( ).
MESSAGE I001(/SEM/003) WITH ARTICLE.

ELSE.

   FOREACH PERIODE, CLIENT.

      IF {QUANTITE,PERIODE,CLIENT} > 0.

      {CA,PERIODE,CLIENT} = {QUANTITE,PERIODE,CLIENT} * {PRIX,#,#}.

      ENDIF.

   ENDFOR.

ENDIF.

Déclaration de la variable locale pour le client
Déclaration de la variable locale pour la période
Déclaration de la variable locale pour l’article

Le prix est lu sans période ni client. S’il n’y a pas de prix….
….on va lire la valeur de la dimension article en cours de traitement et l’on affiche un message d’information.

Mais s’il y a effectivement un prix..
…on passe par chaque combinaison période/client du paquet
…pour laquelle une quantité existe.

 Le chiffre d’affaires est égal à la quantité pour les mêmes dimensions, multiplié par le prix.

Fin du test sur l’existence d’une quantité positive.

Fin de la boucle sur les combinaisons Période/Client

Fin du test sur l’existence d’un prix.

Comme on peut le voir sur cet exemple, avec une bonne définition du niveau et des dimensions à modifier, on peut facilement croiser des données hétérogènes et procéder à des calculs qu’il aurait été complexe de réaliser intégralement en ABAP.

A lire également

– Bien concevoir une application SAP BPC Embedded / Integrated Planning
– SAP BPC Embedded : les nouveautés FOX dans SAP BW 7.5

– Le point sur SAP Analysis Office 2.1
– SAP Cloud for Analytics dans l’univers SAP BI & EPM

– Piloter les performances : l’essentiel en 5 minutes
Processus budgétaire : transformer un mal nécessaire en instrument de pilotage efficace.

Ecrit par Laurent Allais, le 31 mars 2016

About the Author

Laurent Allais
Laurent ALLAIS est expert en solutions d'élaboration budgétaire, business intelligence et pilotage des performances (EPM - FP&A), avec plus de 25 ans d'expérience dans ce domaine. Il intervient dans la mise en oeuvre de Workday Adaptive Planning, leader mondial des solutions cloud EPM et Financial Planning & Analysis. Après avoir fondé Artens et dirigé l'activité SAP BI-EPM de Viséo, il fonde Alsight en 2012, premier spécialiste d'Adaptive Planning en France. Alsight a rejoint Génération Conseil en 2019 dont il a dirigé l'activité Adaptive Planning pendant 4 ans, avant de rejoindre comme associé la société Adapt1Solution, désormais première société de conseil française spécialisée sur Workday Adaptive Planning. Il est intervenu chez plus de 60 clients autour des projets BI et EPM (FP&A), dont Renault, PSA, AGF, Embraer, Airbus, UCPA, ClubMed, Mega International, Pernod-Ricard, Euronext, Infovista, Véolia, Lizéo, Elitechgroup, Roquette, Pimkie, Chanel, L'Oréal, etc... Contact : Laurent.allais@expandbi.com