Une fonction FPScript personnalisée

23.04.2021

Cet exemple met en œuvre une fonction FPScript personnalisée qui peut être utilisée dans les formules FlexPro FPScript comme une fonction intégrée après enregistrement. Il est pris en charge dans l'assistant de l'éditeur FPScript et est automatiquement disponible dans toutes les bases de données chargées.

Remarques :
L'exemple montre comment mettre en œuvre ce type de fonction en VBA. Le texte source VBA complet de l'exemple se trouve dans la base de données du projet CustomFunction.fpd. Toutefois, vous pouvez également utiliser tout autre langage de programmation compatible avec l'automatisation, tel que C# ou C++. Une variante de l'exemple qui a été développée en tant que module complémentaire en C++, est également incluse dans FlexPro. Le chemin d'accès à la base de données du projet est généralement C:\Utilisateurs\Public\Documents\Weisang\FlexPro\2021\Examples\VBA\CustomFunction\CustomFunction.fpd or C:>Users>Public>Public Documents>Weisang>FlexPro>2021>Examples>VBA>CustomFunction>CustomFunction.fpd.
 
Vous pouvez également implémenter une fonction FPScript personnalisée dans FPScript. Voir Tutoriel sur les fonctions FPScript personnalisées.

Arrière-plan

L'exemple définit une fonction avec trois arguments qui additionne les deux premiers arguments et dépend du troisième. Il est construit à partir de plusieurs fonctions intégrées. L'exemple couvre les éléments essentiels de la mise en œuvre d'une fonction FPScript personnalisée :

Définir les arguments

Restrictions concernant le type et la structure des arguments

Utilisation des arguments par défaut

Enregistrement et désenregistrement de la fonction

Accès aux arguments après l'appel de la fonction

Définir des constantes FPScript personnalisées

Enregistrement d'une fonction personnalisée

Avant de pouvoir enregistrer une fonction, vous devez définir ses arguments et d'autres propriétés. L'enregistrement lui-même apparaît alors à la fin de la définition de la fonction.

Tout d'abord, la fonction est ajoutée à la collection UserDefinedFPScriptFunctions. Vous devez ensuite lui attribuer une description. Celle-ci s'affiche alors automatiquement lorsque la fenêtre de l'assistant est utilisée, par exemple.

Avec UserDefinedFPScriptFunctions.Add("MyFunction")

     .Description = "Adds or subtracts two values"

     .Indeterministic = False

     …
End With

La propriété Indéterministe définit si la fonction renvoie toujours le même résultat pour la même entrée. Si la valeur Indéterministe est définie sur True, les formules qui utilisent cette fonction doivent être calculées à chaque intervalle de mise à jour. Par conséquent, cette valeur ne doit être définie sur True que si cela est absolument nécessaire, par exemple en cas de modification des dépendances externes.

Une fois que la fonction a été acceptée dans la collection UserDefinedFPScriptFunctions, les arguments requis peuvent être ajoutés. Seul le nom de l'argument est obligatoire, tous les autres paramètres sont facultatifs. Toutefois, il est recommandé de fournir une description afin qu'une note concernant l'argument puisse être affichée dans la fenêtre de l'assistant. En outre, les types de données et les structures des arguments sont généralement limités au degré exact requis. L'avantage de cette procédure est que FlexPro gère déjà la vérification de la conformité avec les restrictions de type de données et de structure avant que la routine de fonction FPScript personnalisée ne soit appelée. Cela permet de limiter la quantité de code nécessaire à l'implémentation de la fonction et permet à FlexPro de gérer le renvoi des messages d'erreur.

Avec .Parameters.Add("Arg1")

     .Description = "First argument"

     .AllowedTypes = fpParameterTypeNumeric

     .AllowedStructures = fpParameterStructureScalar Or _

         fpParameterStructureDataSeries Ou fpParameterStructureSignal

End With

Dans le cas ci-dessus, le premier argument est limité aux types de données numériques et aux valeurs scalaires, les séries de données et les signaux sont autorisés comme structures de données. Les types de données et les structures peuvent être liés pour l'affectation avec l'opérateur OR comme indiqué. Si l'argument s'écarte des restrictions spécifiées lorsque la fonction est utilisée, un message d'erreur apparaît.

La valeur par défaut est utilisée pour le dernier argument de la fonction. Cela signifie que l'argument peut être omis. Dans ce cas, la valeur par défaut de cet argument peut être utilisée en interne.

With .Parameters.Add("Operation")

     .Description = "Type of operation"

     .AllowedTypes = fpParameterTypeNumeric

     .AllowedStructures = fpParameterStructureScalar

     .DefaultValue = "MYFUNC_OPERATION_ADD"

End With

Le cas ci-dessus présente une caractéristique unique. Le type du paramètre Opération est numérique, mais le texte est spécifié comme valeur par défaut. Le texte contient le nom d'une constante FPScript personnalisée précédemment incluse dont la valeur est déterminée automatiquement comme valeur par défaut dans ce cas. L'avantage de ce type de définition est que le nom plus accessible de la constante est affiché dans la fenêtre de l'assistant.

Les constantes FPScript personnalisées peuvent être insérées comme suit :

Avec UserDefinedFPScriptConstants

     .Add "MYFUNC_OPERATION_ADD", "Selects the add operation", 1

     .Add "MYFUNC_OPERATION_MIN", "Selects the subtract operation", 2

End With

Une nouvelle unité est simplement ajoutée à la collection UserDefinedFPScriptConstants en spécifiant un nom, une description et une valeur scalaire. Les conflits avec les noms des constantes intégrées ou personnalisées existantes donneront lieu à un message d'erreur pertinent.

Une fois les paramètres de la fonction déclarés, vous pouvez enregistrer la fonction pour l'utiliser. La méthode Register est appelée à cette fin. Comme argument, il recevra un lien vers un objet qui implémente l'interface IUserDefinedFunctionCalculate.

.Register oMyFunction

L'interface IUserDefinedFunctionCalculate comprend la méthode Calculate qui est appelée par FlexPro lors du calcul d'une formule qui utilise MyFunction, pour autant qu'elle respecte les restrictions des paramètres.

Remarques :
Ce n'est qu'après l'enregistrement d'une fonction que la cohérence des paramètres définis est vérifiée. Si une erreur se produit au cours de cette vérification, vous devez revoir le code qui définit les paramètres pour détecter les problèmes.
 
En général, les fonctions FPScript personnalisées sont enregistrées dans une fonction exécutée automatiquement comme AutoOpen ou AutoExec afin qu'elles soient disponibles à un moment défini dès le début.

Le désenregistrement est le contraire de l'enregistrement d'une fonction, de sorte qu'en général, dans AutoOpen ou AutoClose, il se produit ce qui suit :

Sub AutoClose()

    ' fonction de désenregistrement

    UserDefinedFPScriptFunctions.Item("MyFunction").Delete

    

    ' désenregistrer les constantes

    Avec UserDefinedFPScriptConstants

        .Item("MYFUNC_OPERATION_ADD").Delete

        .Item("MYFUNC_OPERATION_SUB").Delete

    End With

End Sub

Le désenregistrement se fait automatiquement en supprimant la fonction de la collection UserDefinedFPScriptFunctions. Les constantes sont désenregistrées de la même manière.

Remarque :   Il n'est pas absolument nécessaire de désenregistrer les éléments personnalisés de FPScript, car ils sont automatiquement supprimés à la fermeture du programme. Toutefois, étant donné que seule une référence d'objet est fournie lorsqu'une fonction est enregistrée, le fait de la désenregistrer explicitement entraîne la terminaison contrôlée de l'objet qui exécute le calcul de la fonction. Cela permet d'éviter les effets secondaires indésirables (comme la suspension de FlexPro).

Utilisation d'une fonction personnalisée

Lors de l'appel de la fonction FPScript enregistrée MyFunction, la méthode Calculatemethodde l'interface IUserDefinedFunctionCalculate est appelée. Les arguments sont passés sous la forme d'un tableau de variance. L'exemple de mise en œuvre montre comment accéder aux arguments. En raison de la diversité possible des structures et des types de données, l'exemple a été simplifié à certains endroits.

Le tableau contenant les arguments SafeArrayOfArguments est unique, comme c'est souvent le cas en VBA. Vous pouvez donc accéder à l'opération souhaitée en utilisant l'index trois :

'   MYFUNC_OPERATION_ADD = 1

'   MYFUNC_OPERATION_SUB = 2

nOpération = SafeArrayOfArguments(3)

Le troisième argument a été restreint aux valeurs scalaires de type numérique. Toutefois, une valeur invalide peut toujours être spécifiée pour l'opération à exécuter. Un contrôle est donc effectué :

' opération de contrôle

Si nOpération <> 1 et nOpération <> 2 alors

' sera propagé comme erreur 0x800a0002 à FlexPro

    Err.Raise 2, "IUserDefinedFunctionCalculate_Calculate", "Valeur d'opération non valide"

               , "Valeur de l'opération non valide"

End If

En cas d'erreur, une exception se produit. Le message "Valeur d'opération non valide" apparaît alors, accompagné du code d'erreur spécifique, soit dans le journal des événements FlexPro, soit dans une boîte de dialogue d'erreur.

La partie restante du calcul de la fonction montre comment effectuer des différenciations de cas en utilisant le premier argument à l'aide des fonctions VB IsObject, TypeOf et IsArray, puis exécuter l'opération souhaitée.

 

Notes sur l'utilisation de VBA pour le développement

Si, après l'enregistrement d'une fonction, sa méthode de calcul est modifiée, la fonction doit être désenregistrée, puis réenregistrée. Ceci est nécessaire car sinon le point d'entrée de la fonction n'est plus valide et un message d'erreur s'affiche.

Au moins lorsque vous testez une méthode de calcul, vous devez vous assurer que, sous la rubrique File > Options de l'onglet System Settings, l'option Update objects in the background est désactivée. Sinon, FlexPro se bloquera si vous utilisez des points d'arrêt dans la méthode Calculate. La raison en est que des problèmes surviennent dans l'environnement VBA lors de l'appel de la méthode Calculate dans le fil du programme en arrière-plan.

Pour les fonctions FPScript personnalisées en VBA, l'environnement d'exécution garantit que la fonction Calculer ne s'exécute qu'une seule fois à un moment donné. Cette limitation est mise en place pour des raisons de sécurité. D'une part, l'environnement d'exécution de VBA ne prend pas très bien en charge le multitraitement, et d'autre part, la limitation nécessaire à une seule instance en cours d'exécution dans VBA n'est pas possible en utilisant le langage comme seul support.

Partager l’article ou envoyer par mail :

Vous serez probablement intéressé par les articles suivants :