Structures de contrôle (syntaxe Crystal). SAP Enterprise 4.1 Support Package 1
Formules
Pour certains produits, tels que l'antivol Guardian, aucune couleur n'a été enregistrée de sorte que l'objet {Produits.Couleur} ait une valeur nulle dans la base de données pour cet enregistrement. C'est pourquoi aucun mot n'est imprimé en regard de "antivol Guardian".
Voici comment mettre au point l'exemple ci-dessus à l'aide de IsNull :
If IsNull({Product.Color}) Or
InStr({Product.Color}, " ") = 0 Then
"basic"
Else
"fancy"
Pour ce qui est des opérateurs, lorsque Crystal Reports évalue la condition :
IsNull({Product.Color}) Or
InStr({Product.Color}, " ") = 0
L'évaluation de IsNull ({Produits.Couleur}) se fait en premier ; si le résultat est déterminé comme étant vrai (True), il est certain qu'il en est de même pour l'ensemble de la condition, et il n'est donc pas nécessaire de vérifier si
InStr({Product.Color}, " ") = 0
En d'autres termes, Crystal Reports arrête d'évaluer une expression booléenne quand il peut déduire le résultat de la totalité de l'expression. Dans l'exemple suivant, la formule surveille les tentatives de division par zéro dans le cas où le dénominateur serait égal à 0 :
Local NumberVar num;
Local NumberVar denom;
...
If denom <> 0 And num / denom > 5 Then
...
13.8.13 Structures de contrôle (syntaxe Crystal)
Les formules dépourvues de structures de contrôle exécutent chaque expression de la formule au moment exact où la formule est évaluée. Les expressions sont exécutées de manière séquentielle, de la première à la dernière expression de la formule. Les structures de contrôle vous permettent de faire varier cette séquence rigide. Selon la structure de contrôle que vous choisissez, vous pouvez sauter certaines expressions ou en évaluer d'autres de manière répétée en fonction de l'existence de certaines conditions. Les structures de contrôle constituent le moyen principal pour exprimer une logique d'entreprise, et des formules de rapport habituelles en font un usage extensif.
13.8.13.1 Expressions If (syntaxe Crystal)
L'expression If est l'une des structures de contrôle les plus utiles. Elle vous permet d'évaluer une expression si une condition est vraie et d'évaluer une expression différente dans le cas contraire.
373 2013-09-19
Formules
374
Remarque :
La syntaxe Crystal correcte pour l'instruction If est if <condition> then <then> else <else>,
<condition>
, <then> et <else> étant des expressions uniques. Si vous avez plusieurs expressions après <then> ou <else>, convertissez-les en expressions uniques en les insérant entre parenthèses.
Par exemple :
Global stringVar lastValue; if {Branch_View.Branch_ID} = lastValue then
(lastValue := {Branch_View.Branch_ID}; else crRed;)
(lastValue := {Branch_View.Branch_ID}; crBlack;)
Remarque :
• Lorsque vous procédez à une mise en forme à l'aide de formules conditionnelles, incluez systématiquement le mot clé Else. Les valeurs ne remplissant pas la condition If risquent sinon de perdre leur mise en forme initiale. Pour éviter cela, utilisez la fonction DefaultAttribute (If...Else
DefaultAttribute
).
• Lorsque vous créez des formules de sélection d'enregistrements comprenant des expressions If, incluez systématiquement le mot clé Else, sans quoi il se peut qu'aucun enregistrement ne soit renvoyé ou que des enregistrements inattendus soient renvoyés. Par exemple, une sélection d'enregistrements telle que If {paramètre} = "inférieur à 100" then {objet} <
100" est évaluée comme False (faux) et ne renvoie aucun enregistrement. Pour remédier à ce problème, complétez la formule avec Else True.
Exemple
Une société envisage de payer une prime de 4 % à ses employés, à l'exception de ceux travaillant au service des ventes qui recevront une prime de 6 %. Ceci sera effectué par la formule suivante à l'aide d'une expression If :
//If example 1
If {Employee.Dept} = "Sales" Then
{Employee.Salary} * 0.06
Else
{Employee.Salary} * 0.04
Dans cet exemple, si la condition {Employés.Poste occupé} = "Ventes" est évaluée comme vraie, alors
{Employee.Salary} * 0.06
l'expression est traitée. Sinon, l'expression qui suit la clause Else, c'est-à-dire
{Employee.Salary} * 0.04
est traitée.
Supposons qu'une autre société ait l'intention d'accorder une prime de 4 % à ses employés et que cette prime ne puisse pas être inférieure à 1 000 €. L'exemple suivant illustre ce scénario. Remarquez que la clause Else n'est pas incluse ; elle est facultative et n'est pas nécessaire dans ce cas.
//If example 2
Local CurrencyVar bonus := {Employee.Salary} * 0.04;
If bonus < 1000 Then bonus := 1000;
//The final expression is just the variable 'bonus'.
//This returns the value of the variable and is the
2013-09-19
Formules
375
//result of the formula bonus
Une autre façon d'effectuer l'exemple 2 consiste à utiliser une clause Else :
//If example 3
Local CurrencyVar bonus := {Employee.Salary} * 0.04;
If bonus < 1000 Then
1000
Else bonus
Supposons maintenant que la société précédente veuille également que la prime soit au maximum
égale à 5 000 €. Vous devez alors utiliser une clause Else If. L'exemple suivant comporte seulement une clause Else If, mais vous pouvez en ajouter autant qu'il en faut. Notez qu'il faut cependant une clause Else au maximum pour chaque expression If. La clause Else est exécutée si aucune des expressions If ou Else If n'est vraie.
//If example 4
Local CurrencyVar bonus := {Employee.Salary} * 0.04;
If bonus < 1000 Then
1000
Else If bonus > 5000 Then
5000
Else bonus
13.8.13.1.1 Exemple If (syntaxe Crystal)
Supposons qu'une société souhaite calculer une estimation du montant de l'impôt qu'un employé aura
à payer, et écrire un message en conséquence. Un revenu inférieur à 8 000 € n'est pas imposable, un revenu compris entre 8 000 € et 20 000 € est imposé à 20 %, un revenu compris entre 20 000 € et
35 000 € est imposé à 29 % et un revenu supérieur à 35 000 € est imposé à 40 %.
//If example 5
Local CurrencyVar tax := 0;
Local CurrencyVar income := {Employee.Salary};
Local StringVar message := "";
If income < 8000 Then
( message := "no"; tax := 0
)
Else If income >= 8000 And income < 20000 Then
( message := "lowest"; tax := (income - 8000)*0.20
)
Else If income >= 20000 And income < 35000 Then
(
)
Else
( message := "middle"; tax := (20000 - 8000)*0.20 + (income - 20000)*0.29
message := "highest"; tax := (20000 - 8000)*0.20 + (35000 - 20000)*0.29 +
(income - 35000)*0.40
);
//Use 2 decimal places and the comma as a
//thousands separator
Local StringVar taxStr := CStr (tax, 2, ",");
"You are in the " & message & " tax bracket. " &
"Your estimated tax is " & taxStr & "."
Remarque :
Les variables servent à simplifier la logique de calcul. Deux expressions sont exécutées quand l'une des conditions est remplie ; l'une affecte une valeur à la variable impôt et l'autre affecte une valeur à
2013-09-19
Formules
376 la variable message. Il est souvent utile que plusieurs expressions soient exécutées en tant que résultat d'une condition.
13.8.13.1.2 Détails supplémentaires sur les expressions If (syntaxe Crystal)
L'expression If est une expression. En d'autres termes, elle est évaluée sous la forme d'une valeur d'un type donné. S'il n'y a pas de clause Else et que la condition n'est pas vraie, la valeur est la valeur par défaut du type. Par exemple :
If Length ({Employee.First Name}) < 5 Then
"short"
L'expression If ci-dessus renvoie une valeur de type chaîne. La valeur de la chaîne est “court” si le prénom de l'employé comporte moins de 5 lettres ou la chaîne vide "" dans le cas contraire.
Observez la formule :
If Year({Orders.Order Date}) >= 1995 Then
{Orders.Order Date}
Pour les dates de commande antérieures à 1995, l'expression If ci-dessus renvoie la valeur de type date/heure nulle. Il s'agit d'une valeur de type date/heure et non d'une valeur de date puisque
{Commandes.Date de commande} est un objet de résultat de type date/heure. Crystal Reports n'imprime pas cette valeur nulle et, ainsi, si la formule ci-dessus est utilisée dans un rapport, la formule sera vierge pour les dates de commande antérieures à 1995. Il en va de même pour les valeurs nulles d'heure et de date.
Voici un exemple illustrant l'utilisation de parenthèses pour que le résultat d'une condition If débouche sur l'exécution de plusieurs expressions. Une société facture des frais de port de 5 % pour les commandes livrées sous trois jours, et de 2 % dans les autres cas. Elle souhaite imprimer des messages tels que “Frais de port pour livraison expresse : 100 €” ou “Frais de port pour livraison normale : 20 €” selon les cas.
Local StringVar message;
Local CurrencyVar ship;
If {Orders.Ship Date} - {Orders.Order Date} <= 3 Then
( message := "Rush";
//A semicolon at the end of the next line
//is optional ship := {Orders.Order Amount} * 0.05
) //A semicolon cannot be placed here
Else
( message := "Regular"; ship := {Orders.Order Amount} * 0.02;
);
//The preceding semicolon is required to separate the
//If expression from the final expression below message & " shipping is " & CStr (ship)
Lorsque des expressions sont regroupées à l'aide de parenthèses, le groupe tout entier est considéré comme une seule expression, et sa valeur et son type sont ceux de l'expression finale entre parenthèses.
//The parentheses group expression as a whole has
//Currency type
(
//The first expression in the parentheses has
//String type message := "Rush";
//The second and final expression in parentheses
//has Currency type
2013-09-19
Formules ship := {Orders.Order Amount} * 0.05;
)
Ainsi, par exemple, la formule suivante produit une erreur. C'est parce que la partie Then de l'expression
If renvoie une valeur monétaire alors que la partie Else renvoie une valeur de type chaîne. Ce n'est pas autorisé, car l'expression If est une expression et en tant que telle doit toujours renvoyer une valeur d'un seul type.
//An erroneous formula
Local StringVar message;
Local CurrencyVar ship;
If {Orders.Ship Date} - {Orders.Order Date} <= 3 Then
(
)
Else
( message := "Rush"; ship := {Orders.Order Amount} * 0.05
//The following 2 lines were interchanged ship := {Orders.Order Amount} * 0.02; message := "Regular";
); message & " shipping is " & CStr (ship)
Un moyen de corriger la formule erronée sans avoir à se préoccuper de l'ordre de l'expression consiste simplement à faire en sorte que l'expression If renvoie une valeur constante du même type dans chaque branche. Par exemple, l'expression If renvoie maintenant la valeur numérique 0:
//Repaired the erroneous formula
Local StringVar message;
Local CurrencyVar ship;
If {Orders.Ship Date} - {Orders.Order Date} <= 3 Then
( message := "Rush";
)
Else
( ship := {Orders.Order Amount} * 0.05;
0 ship := {Orders.Order Amount} * 0.02; message := "Regular";
0
); message & " shipping is " & CStr (ship)
13.8.13.2 Expressions Select (syntaxe Crystal)
L'expression Select est semblable à une expression If. Quelquefois, cependant, vous pourrez écrire des formules plus claires et moins répétitives à l'aide de l'expression Select. Par exemple, pour évaluer l'objet {Clients.Fax} afin de déterminer si l'indicatif téléphonique correspond à l'Etat de Washington
(206, 360, 509) ou de la Colombie-Britannique au Canada (604, 250) :
//Select example 1
Select {Customer.Fax}[1 To 3]
Case "604", "250" :
"BC"
Case "206", "509", "360" :
"WA"
Default :
"";
377 2013-09-19
Formules
L'expression située à droite du mot clé Select est appelée condition Select. Dans l'exemple ci-dessus, il s'agit de {Clients.Fax}[1 To 3]. L'expression Select essaie de trouver le premier cas qui correspond
à la condition Select, puis exécute l'expression qui suit le signe deux-points pour ce cas. Le cas par défaut est pris en compte si aucun des cas précédents ne correspond à la condition Select. Notez qu'il y a également un signe deux-points après la valeur par défaut.
//Same effect as Select example 1
Local StringVar areaCode := {Customer.Fax}[1 To 3];
If areaCode In ["604", "250"] Then
"BC"
Else If areaCode In ["206", "509", "360"] Then
"WA"
Else
"";
Exemple
Cette formule regroupe le nombre de nominations aux Oscars reçues par un film dans l'une des catégories faible, moyen, élevé ou très élevé et montre dans le processus certaines des possibilités pour les listes d'expressions qui suivent les intitulés des cas :
//Select example 2
Select {movie.NOM}
Case 1,2,3, Is < 1 :
(
//Can have expression lists by using
//parentheses
10 + 20;
"low"
)
Case 4 To 6, 7, 8, 9 :
"medium"
Case 10 :
"high"
Default :
"extreme"
La clause par défaut de l'expression Select est facultative. Si la clause par défaut est absente et qu'il n'y a aucune correspondance pour chacun des cas, l'expression Select renvoie la valeur par défaut pour son type d'expression. Par exemple, si dans l'exemple ci-dessus la clause par défaut avait été omise et {movie.NOM} = 11, la chaîne vide "" aurait été renvoyée. Select étant une expression, les commentaires figurant dans la section
Détails supplémentaires sur les expressions If (syntaxe Crystal)
s'y appliquent également.
13.8.13.3 Boucles For (syntaxe Crystal)
Les boucles For vous permettent d'évaluer une suite d'expressions un certain nombre de fois. Le fonctionnement n'est donc pas le même que pour les expressions If et Select que le programme rencontrera au plus une fois pendant l'évaluation de la formule. Les boucles For sont préférables lorsque vous connaissez à l'avance combien de fois l'expression doit être évaluée.
378 2013-09-19
Formules
379
13.8.13.3.1 Syntaxe d'une boucle For au moyen d'exemples
Exemple 1
Supposons que vous vouliez inverser la chaîne {Clients.NOM DU CLIENT}. Par exemple, “Cyclistes urbains” devient “sniabru setsilcyC”.
//Reverse a string version 1
Local StringVar str := "";
Local NumberVar strLen :=
Length ({Customer.CUSTOMER_NAME});
Local NumberVar i;
For i := 1 To strLen Do
(
Local NumberVar charPos := strLen - i + 1; str := str + {Customer.CUSTOMER_NAME}[charPos]
); str
Examinez comment fonctionne cette formule en supposant que la valeur actuelle de l'objet {Clients.NOM
DU CLIENT} soit “Air propre”. La longueur d'“Air propre” est affectée à la variable strLen, à savoir 10.
La variable i est une variable de comptage de boucle For car sa valeur change à chaque itération de la boucle For. En d'autres termes, elle est utilisée pour compter les itérations de la boucle.
La boucle For va exécuter 10 itérations. La première fois, i est égal à 1, puis i est égal à 2, puis i est
égal à 3, et ainsi de suite jusqu'à ce que i soit égal à 10. Au cours de la première itération, le dixième caractère de {Clients.NOM DU CLIENT} est ajouté à la variable chaîne vide str. Ainsi, str est égal à “e” après la première itération. Au cours de la deuxième itération, le neuvième caractère de {Clients.NOM
DU CLIENT} est ajouté à str dont la valeur est désormais “er”. Ceci continue jusqu'à la dixième itération après laquelle str est égal à “erporp riA”, qui est la chaîne inversée.
Exemple 2
Voici une version plus simple de la formule ci-dessus qui utilise une clause Step avec un pas négatif
(step) égal à -1. Dans le cas de l'exemple d'“Air propre”, i est égal à 10 dans la première itération, à 9 dans la deuxième, à 8 dans la troisième, et ainsi de suite, jusqu'à ce qu'"i" soit égal à 1 dans la dernière itération.
//Reverse a string version 2
Local StringVar str := "";
Local NumberVar strLen :=
Length ({Customer.CUSTOMER_NAME});
Local NumberVar i;
For i := strLen To 1 Step -1 Do
( str := str + {Customer.CUSTOMER_NAME}[i]
); str
Exemple 3
La version la plus simple consiste à utiliser la fonction intégrée StrReverse :
//Reverse a string version 3
StrReverse ({Customer.CUSTOMER_NAME})
Les fonctions de chaînes intégrées dans Crystal Reports peuvent gérer de nombreuses applications de traitement de chaînes qui sont habituellement gérées au moyen de boucles For ou d'autres types de boucles. Cependant, les boucles For apportent la plus grande souplesse en matière de traitement de chaînes et également de la puissance dans le traitement de tableaux, ce qui peut s'avérer essentiel si les fonctions intégrées ne couvrent pas l'application envisagée.
2013-09-19
Formules
380
13.8.13.3.2 Exemple de boucle For
Voici un exemple plus détaillé des fonctionnalités de traitement de chaînes de Crystal Reports. Le mode de cryptage César est un code simple qui est traditionnellement attribué à Jules César. Dans ce code, chaque lettre d'un mot est remplacée par la lettre qui est située 5 caractères plus loin dans l'alphabet.
Par exemple, “Jaws” devient “Ofbx”. Notez que “w” est remplacé par “b” ; puisqu'il n'y a pas 5 caractères après le “w” dans l'alphabet, on recommence à partir du début. Voici une formule qui applique le mode de cryptage de César à l'objet {Clients.NOM DU CLIENT} de la base de données Xtreme :
//The Caesar cipher
//The input string to encrypt
Local StringVar inString := {Customer.CUSTOMER_NAME};
Local NumberVar shift := 5;
Local StringVar outString := "";
Local NumberVar i;
For i := 1 To Length(inString) Do
(
Local StringVar inC := inString [i];
Local StringVar outC;
Local BooleanVar isChar :=
LowerCase(inC) In "a" To "z";
Local BooleanVar isUCaseChar := isChar And (UpperCase (inC) = inC); inC := LCase(inC);
If isChar Then
(
Local NumberVar offset :=
(Asc(inC) + shift - Asc("a")) Mod
(Asc("z") - Asc("a") + 1); outC := Chr(offset + Asc("a"));
If isUCaseChar Then outC := UpperCase(outC)
)
Else outC := inC; outString := outString + outC
); outString
Dans l'exemple ci-dessus, une expression If est imbriquée dans le bloc d'expressions de la boucle For.
Cette expression If est chargée des détails précis relatifs au décalage d'un seul caractère. Par exemple, les lettres sont traitées différemment de la ponctuation et des espaces. En particulier, la ponctuation et les caractères ne sont pas codés. Une remarque générale à ce point est que les structures de contrôle peuvent être imbriquées dans d'autres structures de contrôle et que plusieurs expressions peuvent
être incluses dans les blocs d'expressions entre parenthèses des autres structures de contrôle.
13.8.13.3.3 Utilisation d'Exit For (syntaxe Crystal)
Vous pouvez sortir d'une boucle For à l'aide de la clause Exit For. Dans l'exemple suivant, le nom “Fred” est recherché dans le tableau global de noms. Si le nom est trouvé, l'indice du nom est renvoyé dans le tableau. Sinon, la valeur renvoyée est -1.
Par exemple, si le tableau de noms est :
["Frank", "Helen", "Fred", "Linda"] la formule renvoie la valeur 3.
Global StringVar Array names;
//The names array has been initialized and filled
//in other formulas
Local NumberVar i;
Local NumberVar result := -1;
//The UBound function returns the size of its array
//argument
2013-09-19
Formules
For i := 1 to UBound (names) Do
(
If names [i] = "Fred" Then
( result := i;
Exit For
)
); result
Lorsqu'elle est considérée comme une expression, la boucle For renvoie toujours la valeur booléenne
True (Vrai). Ainsi, vous ne voudrez presque jamais qu'une boucle For soit la dernière expression dans une formule, puisque dans ce cas, la formule affichera seulement la valeur True plutôt que le résultat attendu.
13.8.13.4 Boucles While (syntaxe Crystal)
La boucle While est un autre mécanisme de mise en boucle. Une boucle While peut être utilisée pour exécuter indéfiniment un bloc défini d'instructions.
381 2013-09-19
Formules
382
13.8.13.4.1 2 types différents de boucles While
Type de boucle While Explication
While ... Do
Exemple
La boucle While ... Do évalue la condition, et si celle-ci est vraie, l'expression qui suit Do est
également évaluée.
Après ce premier passage, la condition est de nouveau évaluée et, si celle-ci est vraie, l'expression qui suit Do est de nouveau évaluée. Le processus se répète jusqu'à ce que la condition soit fausse.
While condition
Do expression
Do ... While
La boucle Do ... While évalue l'expression une fois, quelle qu'elle soit.
La condition est ensuite évaluée et, si celle-ci est vraie, l'expression est de nouveau évaluée.
Ce processus se poursuit jusqu'à ce que la condition soit fausse.
Do expression
While condition
Remarque :
• Les boucles While acceptent l'instruction Exit While qui assure une sortie immédiate de la boucle.
Son utilisation est analogue à celle de l'instruction Exit For dans les boucles For.
• Comme pour la boucle For, la boucle While considérée comme une expression renvoie toujours la valeur booléenne True (Vrai).
13.8.13.4.2 Exemple de boucle While ... Do (syntaxe Crystal)
Dans l'exemple suivant, la première occurrence d'un chiffre est recherchée dans une chaîne d'entrée.
Si un chiffre est trouvé, c'est la position du chiffre qui est renvoyée ; sinon c'est la valeur -1. Dans ce cas, la chaîne d'entrée est définie explicitement comme une constante chaîne, mais elle pourrait
également être définie comme égale à un objet de résultat de type chaîne. Par exemple, pour la chaîne d'entrée, “Les 7 nains”, la formule renvoie 5, qui est la position du chiffre 7.
Local StringVar inString := "The 7 Dwarves";
Local NumberVar strLen := Length (inString);
Local NumberVar result := -1;
Local NumberVar i := 1;
While i <= strLen And result = -1 Do
2013-09-19
Formules
(
Local StringVar c := inString [i];
If NumericText (c) Then result := i; i := i + 1;
); result
13.8.13.5 Mécanisme de sécurité pour les boucles (syntaxe Crystal)
Il existe un mécanisme de sécurité pour éviter le blocage du traitement d'un rapport à cause d'une boucle infinie. Pour chaque évaluation de formule, le nombre maximum d'évaluations de condition de boucle est de 100 000. Cette règle est illustrée par l'exemple suivant.
Par exemple :
Local NumberVar i := 1;
While i <= 200000 Do
(
If i > {movie.STARS} Then
Exit While; i := i + 1
);
20
Si {movie.STARS} est supérieur à 100 000, la condition de boucle (i <= 200000) sera évaluée un plus grand nombre de fois que le maximum autorisé et un message d'erreur s'affichera. Sinon la boucle est correcte.
Remarque :
Le mécanisme de sécurité s'applique au niveau de la formule, et non pour chaque boucle individuelle.
Par exemple :
Local NumberVar i := 1;
For i := 1 To 40000 Do
(
Sin (i);
); i := 1;
While i <= 70000 Do
( i := i + 1;
)
La formule ci-dessus déclenche aussi le mécanisme de sécurité puisque le nombre de 100 000 fait référence au nombre total d'évaluations de condition de boucle de la formule et cette formule comportera
40001 +70001 évaluations de ce type.
13.8.13.6 Option Loop (syntaxe Crystal)
383 2013-09-19

Public link updated
The public link to your chat has been updated.