Faire des calculs avec Envision

Faire des calculs










Accueil » Ressources » Ici

Envision permet de faire tous les calculs faisables avec Excel. À cet égard, la syntaxe est similaire celle des formules Excel. Envision fait une large place aux calculs vectoriels. Ces derniers sont utilisés pour traiter un nombre important de valeurs en une fois, plutôt que de les traiter une à une. Les tables et vecteurs sont décrits de façon détaillée dans cette section, ce qui devrait vous aider à faire vos premiers calculs avec Envision.

Afin de suivre les explications ci-dessous plus facilement, l’utilisateur fera bien de mettre en place l'échantillon de données. Nous n’avons pas encore détaillé les fonctionnalités de chargement de données, mais, nos exemples indiquent les lignes à insérer en début de script.

Tables et vecteurs

Le modèle de données d’Envision repose sur des tables et des vecteurs. Une table dans Envision est similaire, dans l’esprit, aux tables des bases de données relationnelles. Du point de vue d’Excel, une table est une feuille de calcul bien mise en forme où la première ligne contient les en-têtes des colonnes et où les (nombreuses) lignes suivantes contiennent les données correctement alignées sur chaque en-tête. Dans un script Envision, les tables ont également un nom, qui est généralement celui du fichier tabulaire sous-jacent. Les vecteurs sont associés aux colonnes de la table et portent également un nom. Envision utilise le terme « vecteur » plutôt que « colonne » pour souligner que les opérations peuvent être effectuées sur toutes les valeurs du vecteur en une fois, c’est-à-dire sur toutes les lignes de la table d’origine.

Illustrons notre propos avec quelques lignes de script qui peuvent être appliquées à l’échantillon de données. Ci-dessous, pour chaque commande, nous calculons le taux de taxe, c’est-à-dire le ratio entre le montant des taxes et le montant hors taxe facturé au client.

read "/sample/Lokad_Items.tsv"
read "/sample/Lokad_Orders.tsv" as O
read "/sample/Lokad_PurchaseOrders.tsv" as PO

O. TaxRate = O. TaxAmount / Orders. NetAmount

Ici O fait référence à la table des commandes (Orders), qui contient tout l’historique des ventes, chaque transaction étant représentée par un nombre de lignes égal au nombre d’articles dans la transaction. La variable O. TaxAmount fait référence au vecteur associé avec la colonne intitulée TaxAmount au sein de la table O. Notez la syntaxe qui consiste à utiliser un point (.) entre le nom de la table et celui du vecteur car elle est utilisée fréquemment avec Envision.

L’opération qui utilise le signe égal = est appelée une affectation : le calcul a lieu sur la droite du signe = et son résultat est affecté à la variable sur la gauche du signe. Dans l’exemple ci-dessus, c’est une division qui a lieu à droite du signe égal. Puisque ni O. TaxAmount ni O. NetAmount n’est défini ailleurs dans le script, Envision essaye de charger ces données directement depuis les données d’entrée. Puisque la table O de l’échantillon de données contient les deux colonnes NetAmount et TaxAmount, le script peut s’exécuter. Sur la gauche du signe égal se trouve O. TaxRate, variable à laquelle est affecté le résultat du calcul, le taux de taxe. Une affectation est l’équivalent logique de l’ajout d’une colonne dans Excel, colonne dont le nom est celui de la variable de l’affection, TaxRate dans ce cas.

Dans les extraits de code suivants, pour plus de concision, nous omettons les lignes read "/sample/Lokad_XYZ.tsv”, puisque celles-ci doivent systématiquement être placées en début de script.

La syntaxe des calculs Envision est similaire celle des formules Excel. Dans le script ci-dessous, une série de calculs est effectuée pour illustrer cette syntaxe.

O.A = 42
O.B = 5 * (1 + O.A)
O.C = (O.A + O.B) * (1 + O.A)

Ce script définit trois vecteurs A, B et C, qui sont tous rattachés à la table O. La première ligne est une affectation simple : la valeur 42 est affectée à O.A. Comme O.A est un vecteur, chacune de ses lignes reçoit la valeur 42. Une large place est accordée aux vecteurs dans Envision et la plupart des opérations sur les vecteurs agissent sur toutes leurs lignes en une fois.

O n’est pas la seule table disponible dans l’échantillon de données. Ce dernier contient également une table appelée PO, sur laquelle des opérations similaires peuvent être effectuées.

PO.A = 42
PO.B = 5 * (1 + PO.A)
PO.C = PO.A + PO.B

Maintenant que nous avons introduit une seconde table, la question suivante se pose : est-il possible d’effectuer des opérations entre plusieurs tables avec Envision ? La réponse est oui, mais cela nécessite quelques efforts supplémentaires. Voyons par exemple le script suivant :

O.A = 1
PO. A = O.A + 1 // INCORRECT !

Puisque il n’y a aucune raison pour que les tables O et PO soient alignées — elles ne contiennent même pas le même nombre de lignes — la sémantique d’une opération telle que décrite ci-dessus serait très floue. Une telle opération est invalide avec Envision, si vous essayez d’exécuter un tel script, l’exécution échoue et un message d’erreur s’affiche.

Il est toutefois possible de combiner des données de plusieurs tables avec Envision, nous le détaillons dans la section suivante.

La table spéciale « article »

Les tables utilisées dans Envision ont toutes un nom, à une importante exception près : la table « article » (item). Dans le commerce, nous avons observé que, dans la grande majorité des calculs, une table domine les autres : la liste des produits / variantes / SKU… selon le contexte. Donc, à la différence d’une base de données relationnelle dans laquelle toutes les tables sont au même niveau, dans Envision la table « article » est traitée différemment, ce qui facile le traitement de la plupart des scénarios rencontrés dans le secteur du commerce.

À un moment ou à un autre, tout distributeur, grand ou petit, liste ses produits dans un tableau, un produit par ligne, avec un certain nombre de colonnes qui fournissent des informations supplémentaires sur les produits, leur catégorie (information statistique) ou le total des ventes sur les 5 dernières semaines (information dynamique) par exemple. Selon la situation, les lignes sont associées aux produits ou aux SKU, ou n’importe quelle autre représentation fine des articles vendus. Un tel tableau consolidé est très pratique dans de nombreux cas : identification de stock mort, mise à jour des prix, identification des meilleures ventes, etc. En tant que distributeur, vous avez sûrement manipulé un tel tableau à de nombreuses occasions.

Nous avons donc réalisé que les tableaux de ce type sont omniprésents dans la distribution et avons décidé d’intégrer cette caractéristique à notre technologie. Envision est conçu pour intégrer profondément cette pratique si répandue dans le secteur du commerce.

Revenons à l’échantillon de données. Ce dernier contient une liste d’article. Si nous voulions calculer la valeur en stock pour chaque article, avec une table nommée Items qui contient les articles, il faudrait utiliser la commande suivante :

Items.Stock = Items.StockOnHand + Items.StockOnOrder
Items.StockValue = Items.TotalStock * BuyPrice

Cependant, pour la table « article », et pour cette table uniquement, le nom peut ne pas être mentionné, ce qui donne :

Stock = StockOnHand + StockOnOrder
StockValue = Stock * BuyPrice

Le préfixe Items. n’est pas utilisé et, par convention, toute variable dont le nom ne contient pas de point (.) fait référence implicitement à un vecteur de la table « article » (items). Puisque les calculs impliquant des articles sont si fréquents dans le domaine commercial, cette convention facilite la lecture et la compréhension des scripts Envision.

Les tableaux d'« articles » sont largement utilisés principalement parce que la plupart des données d’historique des entreprises du domaine commercial peuvent être facilement représentées comme une liste d’événements, qui sont tous rattachés à un article. Par exemple, l’historique des ventes peut être contenu — au minimum — dans un tableau de trois colonnes : l’identifiant de l’article, la date et la quantité achetée. De la même façon l’historique des achats peut être représenté avec ces trois colonnes plus, idéalement, une quatrième avec la date de réception en vue de suivre les délais de réapprovisionnement. Les retours client peuvent également être représentés avec les colonnes identifiant d’article, date, quantité et, idéalement, identifiant client afin d’être en mesure d’analyser le comportement de clients réguliers.

La liste continue. Le commerce consiste à manipuler des flux : flux de marchandises, des fournisseurs vers les clients, et flux d’argent, des clients vers les fournisseurs. Tous ces flux peuvent être décomposés en lignes, qui sont toutes rattachées à un article spécifique. Ainsi, dans le domaine commercial, ce sont des tables qui recensent surtout des articles qui sont manipulées et c’est exactement ce qu’Envision reflète.

Une seule colonne est obligatoire dans la table « article », elle doit contenir les identifiants des articles et doit être intitulée « Id », selon la convention utilisée par Envision. Nous avons vu précédemment qu’il n’est pas possible de combiner les tables O et PO car ces dernières ne sont pas alignées. La colonne « Id », que l’on trouve dans la table « article » ainsi que dans toutes les autres tables, joue le rôle d’une passerelle qui permet de telles combinaisons.

Prenons un exemple en calculant les recettes générées par chaque article, à partir de l’historique des ventes, et les dépenses associées à chaque produit, à partir de l’historique des achats, avec le script ci-dessous.

CashIn = sum (O. NetAmount)
CashOut = sum (PO. NetAmount)
CashFlow = CashIn - CashOut

Vous pouvez constater que la table « article » est utilisée à gauche dans les affectations et qu'à droite de ces dernières d'autres tables sont mentionnées, au moins sur les lignes 1 et 2. Il est légitime d'utiliser simultanément des tables différentes dans ce cas grâce à l'utilisation de l'agrégateur sum() (somme). Ce dernier ne sera pas détaillé dans ce document, comme son nom l'indique cet agrégateur calcule la somme de tous les NetAmount de chaque article. La correspondance entre les articles et les commandes est fait de façon transparente car la table O contient également une colonne « Id ».

Dans le script ci-dessus, le calcul est décomposé en trois lignes pour plus de lisibilité mais il peut être effectué par la commande suivante également, où les variables intermédiaires ne sont pas nommées :

CashFlow = sum(O.NetAmount) - sum(PO.NetAmount)

En plus de la somme, tous les agrégateurs classiques sont disponibles dans Envision : moyenne, minimum, maximum, médiane… Ces agrégateurs offrent la possibilité d'apporter un complément d'information à la table des articles avec des attributs descriptifs qui peuvent être très utiles lorsqu'il s'agit de faire face aux difficultés rencontrés dans le domaine commercial. Il est donc possible de créer un nouveau vecteur dans la table « article », en mettant à profit une autre table et un agrégateur, mais il est également possible de faire l'inverse et d'utiliser un vecteur de la table « article » dans un calcul associé à une autre table.

Recalculons par exemple la TVA associée à chaque ligne de la table des ventes. Pour simplifier, considérons que la TVA est un taux constant de 20 %. Les commandes associées pourraient être les suivantes :

VatRate = 0.2 // hypothesis
F = VatRate / (1 - VatRate)
O.Vat = O.NetAmount * F

Le vecteur VatRate est aligné sur la table O puisque chacune des lignes de cette table est reliée à un seul article. De façon plus explicite, on pourrait donc écrire :

VatRate = 0.2 // hypothesis
O.VatRate = VatRate
O.F = O.VatRate / (1 - O.VatRate)
O.Vat = O.NetAmount * O.F

Dans cet exemple, les vecteurs F sont créés simplement pour illustrer la décomposition du calcul.

Par ailleurs, notez qu'il est possible de charger des tables arbitraires dans Envision, même si ces dernières ne contiennent pas de colonne « Id ». Mais ces scénarios avancés sont hors de propos dans le présent article.

Le statut spécifique des dates

La table « article » est un cas particulier dans Envision car, comme nous l'avons vu, beaucoup d'opérations fondamentales dans le domaine du commerce tournent autour de la notion même d'« article ». Ces opérations sont généralement reliées à une date spécifique : chaque ligne de l'historique des ventes contient une date, tout comme l'historique des achats, et toutes les données qualifiées d'historiques. À cause de l'importance des données historiques dans le secteur du commerce, dans lequel presque toutes les activités d'une entreprise peuvent être décrites avec une liste d'entrées datées qui représentent les mouvements de stock ou les paiements, Envision a également créé un cas particulier très « commercial » pour les dates.

Toutes les tables peuvent avoir une colonne Date en plus de la colonne obligatoire Id. Lorsqu'une colonne Date est présente, la table est non seulement indexée par identifiant d'article mais aussi par date. L'indexation par date est pratique car, souvent, lorsque l'on cherche à appliquer un période particulière à un calcul, la totalité de historique, quel que soit le type d'entrée, doit être filtré de façon similaire.

Pour illustrer ceci, revenons au calcul des flux de trésorerie et restreignons le calcul aux valeurs de l'année écoulée.

end := max(date)
when date > end - 365
  CashFlow = sum(O.NetAmount) - sum(PO.NetAmount)

La variable end (fin) est définie comme la date la plus récente dans les données d'entrée. Puisque end est une date, cet exemple montre qu'il est possible de manipuler arithmétiquement les dates avec Envision. La convention qui consiste à ajouter 1 (+1) à une date dans Envision a pour résultat d'ajouter un jour à une date en particulier. Et donc en soustrayant 365 jours, on remonte à peu près un an en arrière.

Le script commence par un filtre when (lorsque) qui représente une condition qui doit être remplie pour toutes les lignes traitées dans un bloc de script donné. En ce qui concerne les articles, ils ne sont pas indexés par date, le filtre de date n'a donc aucun effet sur eux et ils sont tous pris en compte dans le bloc when. Par contre, les tables des commandes et des commandes d'achats ont toutes les deux une colonne Date et, par conséquent, toutes les lignes de ces tables qui ne remplissent pas la condition du filtre when sont exclues du bloc.

Ainsi, l'agrégation sum() dans le bloc when ne traite que les lignes qui n'ont pas été exclues par le filtre, celles qui datent de moins d'un an. Cet exemple peut également être décomposé avec des variables intermédiaires comme dans l'exemple avec l'ensemble de l'historique.

end := max(date)
when date > end - 365
CashIn = sum(O.NetAmount)
CashOut = sum(PO.NetAmount)
CashFlow = CashIn - CashOut
Avec ce dernier exemple, la notion de bloc sous le filtre when est peut-être plus claire : toutes les commandes du bloc, qui sont indentées de 2 espaces (lignes 2, 3 et 4), manipulent uniquement les lignes des tables filtrées par date.

Ce script illustre également la capacité d'Envision à réaligner des données complexes issues d'autres tables sur la table « article ». Cela correspond, dans Excel, à transformer d'autres feuilles (par exemple l'historique des commandes) en colonnes en utilisant la feuille principale qui contient la liste des produits. Envision facilite grandement ce traitement.