4D v16.3Méthodes projet |
|||||||||||||||||||||||
|
4D v16.3
Méthodes projet
Méthodes projet
Les méthodes projet, comme leur nom l’indique, s’appliquent à la totalité de votre projet, c’est-à-dire votre base de données. Alors que les méthodes formulaire ou les méthodes objet par exemple sont associées à des formulaires ou des objets, une méthode projet est disponible partout — elle n'est associée à aucun élément particulier de la base. Une méthode projet peut tenir les rôles suivants, en fonction de la manière dont elle est exécutée et utilisée :
Ces appellations ne qualifient pas la nature des méthodes (ce qu'elles sont), mais leur fonction (ce qu'elles font). Une méthode de menu est une méthode projet appelée depuis une commande de menu personnalisé. Elle se comporte comme un agent de police chargé de la circulation, dirigeant les flux de votre application. Les méthodes de menu contrôlent, aiguillent lorsque c’est nécessaire, affichent les formulaires, génèrent des états ou encore gèrent votre base. Le deuxième type de méthode projet peut être considéré comme une méthode asservie — d’autres méthodes lui demandent d’effectuer des tâches. Ce type de méthode est appelé sous-routine. Une sous-routine qui retourne une valeur est appelée une fonction. Une méthode de gestion de process est une méthode projet appelée lorsqu’un process est démarré. Le process existera tant que la méthode sera en cours d'exécution. Pour plus d'informations sur les process, reportez-vous à la section Process. A noter qu'une méthode de menu associée à une commande de menu pour laquelle la propriété Démarrer un nouveau process est sélectionnée, est aussi la méthode de gestion de process pour le process créé. Une méthode de gestion d’événements est une méthode dédiée à la gestion des événements, qui s'exécute dans un process différent de celui de la méthode de gestion des process. Généralement, pour la gestion des événements, vous pouvez laisser 4D faire le gros du travail. Par exemple, lors de la saisie de données, 4D détecte les clics souris et les touches enfoncées, puis appelle les méthodes objet et formulaire correspondantes, vous permettant ainsi de prévoir dans ces méthodes les traitements appropriés aux événements. Une méthode de gestion d’erreurs est une méthode projet d'interruption. Elle s'exécute à l'intérieur du process dans lequel elle a été installée à chaque fois qu'une erreur se produit. Pour plus d'informations, reportez-vous à la description de la commande APPELER SUR ERREUR. Une méthode de menu est appelée en mode Application lorsque la commande de menu personnalisé à laquelle elle est associée est sélectionnée. Vous assignez la méthode à la commande de menu dans l’éditeur de menus de 4D. Lorsque l’utilisateur sélectionne la commande de menu, la méthode est exécutée. Ce fonctionnement est l’un des principaux aspects de la personnalisation d’une base de données. C’est en créant des menus qui appellent des méthodes de menu que vous personnalisez votre base. Reportez-vous au manuel Mode Développement de 4D pour plus d’informations sur l’éditeur de menu. Les commandes de menus personnalisés peuvent déclencher une ou plusieurs actions. Par exemple, une commande de menu de saisie d’enregistrements peut appeler une méthode effectuant deux actions : afficher le formulaire entrée approprié et appeler la commande AJOUTER ENREGISTREMENT jusqu’à ce que l’utilisateur annule la saisie de nouveaux enregistrements. L’automatisation de séquences d’actions est une possibilité très puissante du langage de programmation de 4D. A l’aide des menus personnalisés, vous pouvez automatiser des séquences de tâches, vous permettez aux utilisateurs de naviguer plus facilement dans votre base. Lorsque vous avez écrit une méthode projet, elle devient partie intégrante du langage de la base dans laquelle elle a été créée. Vous pouvez alors l'appeler de la même manière que vous appelez les commandes intégrées de 4D. Une méthode projet utilisée de cette manière est appelée une sous-routine. L'utilisation de sous-routines procure les avantages suivants :
Imaginons par exemple que vous travaillez avec une base de clients. A mesure que vous construisez la base, vous vous apercevez que vous répétez souvent certaines tâches, telles que la recherche d’un client et la modification de son enregistrement. Le code nécessaire à l’accomplissement de cette opération pourrait être : ` Recherche d'un client Si vous n’utilisez pas de sous-routines, vous devrez écrire ce code à chaque fois que vous voudrez modifier l’enregistrement d’un client. Si cette opération peut être réalisée dans dix endroits différents de votre base, vous devrez la réécrire dix fois. Grâce aux sous-routines, vous ne l’écrirez qu’une seule fois en tout. C’est le premier avantage des sous-routines : réduire la quantité de code à écrire. Si le code ci-dessus était une méthode projet appelée MODIFIER CLIENT, vous l’exécuteriez simplement en inscrivant son nom dans une autre méthode. Par exemple, pour modifier l’enregistrement d’un client puis l’imprimer, vous n’auriez qu’à écrire : MODIFIER CLIENT Cette possibilité simplifie énormément vos méthodes. Dans l’exemple ci-dessus, il n’est pas nécessaire de savoir comment fonctionne la méthode MODIFIER CLIENT, mais uniquement ce qu’elle fait. C’est le deuxième avantage que vous pouvez tirer de l’utilisation de sous-routines : la clarification de votre code. Ainsi, ces méthodes deviennent en quelque sorte des extensions du langage de 4D. Si vous devez modifier votre mode de recherche des clients, comme dans notre exemple, il vous suffit de modifier une seule méthode, et non dix. C’est un autre avantage des sous-routines : faciliter les modifications de votre code. Avec les sous-routines, vous rendez votre code modulaire. Cela signifie simplement que vous dissociez votre code en modules (sous-routines), chacun d’entre eux effectuant une tâche logique. Examinez le code suivant, tiré d’une base de gestion de comptes chèques : CHERCHER CHEQUES EMIS ` Rechercher les chèques émis Même pour quelqu’un qui ne connaît pas la base, le code est clair. Il n’est pas nécessaire d’examiner chaque sous-routine. Elles peuvent contenir de nombreuses lignes d’instructions et effectuer des opérations complexes, mais l’important est ce qu’elles font. Nous vous conseillons de découper votre code en tâches logiques, ou modules, à chaque fois que c’est possible. Vous aurez souvent besoin de fournir des valeurs à vos méthodes. Vous pouvez facilement effectuer cette opération grâce aux paramètres. Les paramètres (ou arguments) sont des données dont les méthodes ont besoin pour s’exécuter — le terme "paramètres" ou "arguments" est utilisé indifféremment dans ce manuel. Des paramètres sont également passés aux commandes intégrées de 4D. Dans l’exemple ci-dessous, la chaîne “Bonjour” est un paramètre de la commande ALERTE : ALERTE("Bonjour") Les paramètres sont passés de la même manière aux méthodes. Par exemple, si la méthode FAIRE QUELQUE CHOSE accepte trois paramètres, l'appel à cette méthode pourrait être de la forme suivante : FAIRE QUELQUE CHOSE(AvecCeci;EtCela;CommeCeci) Les paramètres sont séparés par des points-virgules (;). Dans la sous-routine (la méthode appelée), la valeur de chaque paramètre est automatiquement copiée séquentiellement dans des variables locales numérotées : $1, $2, $3, etc. La numérotation des variables locales représente l’ordre des paramètres. //Code de la méthode FAIRE QUELQUE CHOSE A l'intérieur de la sous-routine, vous pouvez utiliser les paramètres $1, $2... de la même manière que vous utilisez les autres variables locales. Toutefois, dans le cas où vous utilisez des commandes qui modifient la valeur de la variable passée en paramètre (par exemple Trouver dans champ), les paramètres $1, $2... ne peuvent pas être utilisés directement. Vous devez d'abord les recopier dans des variables locales standard (par exemple $mavar:=$1). Note de programmation avancée : Les méthodes projet de 4D acceptent un nombre variable de paramètres du même type, à la condition que ce soient les derniers paramètres de la méthode. Pour déclarer ces paramètres, il vous suffit d'utiliser une directive de compilation à laquelle vous passez ${N}) comme paramètre, où N désigne le premier paramètre de la suite. Par exemple, la déclaration C_ENTIER LONG(${5}) indique à 4D et au compilateur qu'à partir du cinquième paramètre la méthode peut recevoir un nombre variable de paramètres de type entier long. Grâce à la commande Nombre de paramètres, vous pouvez accéder à ces paramètres au sein d'une boucle de type Boucle...Fin de boucle via la syntaxe d'indirection de paramètres (${...}). Pour plus d'informations sur ce point, reportez-vous à l'exemple 2 de la commande Nombre de paramètres. En fonction de leur type, les paramètres sont passés par copie ou par référence :
Le tableau suivant indique comment les différents types d'éléments peuvent être passés :
Lorsque vous utilisez des champs, variables ou expressions de type scalaire en tant que paramètres de méthodes projets, seules des copies des valeurs sont passées. Puisque $1, $2... sont des variables locales, elles ne sont définies qu’à l’intérieur de la sous-routine et sont effacées à la fin de son exécution. Pour cette raison, une sous-routine ne peut pas modifier, au niveau de la méthode appelante, la valeur réelle des champs ou des variables passé(e)s en paramètre. Par exemple : ` Voici une partie de la méthode MA METHODE La boîte de dialogue d'alerte affichée par FAIRE QUELQUE CHOSE contiendra "WILLIAM" et celle affichée par MA METHODE contiendra "william". La méthode a modifié localement la valeur du paramètre $1, mais cela n'affecte pas la valeur du champ [Personnes]Nom passé en paramètre par la méthode MA METHODE. Si vous voulez réellement que la méthode FAIRE QUELQUE CHOSE modifie la valeur du champ, deux solutions s'offrent à vous : 1. Plutôt que de passer le champ à la méthode, vous lui passez un pointeur : ` Voici une partie de la méthode MA METHODE Ici, le paramètre n'est pas le champ lui-même, mais un pointeur vers le champ. Ainsi, à l'intérieur de la méthode FAIRE QUELQUE CHOSE, $1 ne contient plus la valeur du champ mais un pointeur vers le champ. L'objet référencé par $1 ($1-> dans le code ci-dessus) est le champ lui-même. Par conséquent, la modification de l'objet référencé dépasse les limites de la sous-routine et le champ lui-même est affecté. Dans cet exemple, les deux boîtes de dialogue d'alerte afficheront "WILLIAM". Pour plus d'informations sur les pointeurs, reportez-vous à la section Pointeurs. 2. Plutôt que la méthode FAIRE QUELQUE CHOSE “fasse quelque chose”, vous pouvez la réécrire de manière à ce qu'elle retourne une valeur : ` Voici une partie de la méthode MA METHODE Une sous-routine retournant une valeur est appelée une fonction. Ce point est traité dans les paragraphes suivants. Lorsque vous utilisez des variables, expressions ou champs de type objet ou collection en tant que paramètres de méthodes projet, ce sont des références vers les données sources qui sont passées. Dans ce cas, $1, $2... ne contiennent pas les valeurs mais des références. Toute modification de la valeur des paramètres $1, $2... à l'intérieur de la sous-routine sera propagée partout où l'objet ou la collection source est utilisée. C'est le même principe que pour les pointeurs, excepté le fait que les paramètres $1, $2... n'ont pas besoin d'être déréférencés à l'intérieur de la sous-routine. Par exemple : //La méthode CreatePerson crée un objet et l'envoie en tant que paramètre //La méthode ChangeAge ajoute 10 à l'attribut Age de l'objet reçu Si vous exécutez la méthode CreatePerson, les deux messages d'alerte contiendront "50" car la même référence est traitée par les deux méthodes. 4D Server : Lorsque des paramètres sont passés entre des méthodes qui ne sont pas exécutées sur la même machine (lors de l'utilisation de l'option Exécuter sur serveur par exemple, voir Propriétés des méthodes projet), il n'est pas possible d'utiliser des références. Dans ce cas, ce sont des copies des paramètres objet ou collection qui sont envoyées au lieu de références. Les méthodes peuvent retourner des valeurs. Une méthode qui retourne une valeur est appelée une fonction. Les commandes de 4D ou de plug-ins qui retournent une valeur sont également appelées fonctions. Par exemple, la ligne d’instruction suivante utilise une fonction intégrée, Longueur, qui retourne la longueur d’une chaîne. La valeur retournée par Longueur est placée dans une variable appelée MaLongueur : MaLongueur:=Longueur("Comment suis-je arrivé là ?") Toute sous-routine peut retourner une valeur. La valeur à retourner est placée dans la variable locale $0. Par exemple, la fonction suivante, appelée Majuscules4, retourne une chaîne dont les quatre premiers caractères ont été passés en majuscules : $0:=Majusc(Sous chaine($1;1;4))+Sous chaine($1;5) Voici un exemple qui utilise la fonction Majuscules4 : NouvellePhrase:=Majuscules4("Bien joué.") Dans ce cas, la variable NouvellePhrase prend la valeur “BIEN joué.” Le retour de fonction, $0, est une variable locale à la sous-routine. Elle peut être utilisée en tant que telle à l'intérieur de la sous-routine. Par exemple, dans le cas de la méthode FAIRE QUELQUE CHOSE utilisée précédemment, $0 recevait d'abord la valeur de $1, puis était utilisée en tant que paramètre de la commande ALERTE. Dans une sous-méthode, vous pouvez utiliser $0 comme n'importe quelle autre variable locale. C'est 4D qui retourne sa valeur finale (sa valeur courante au moment où la sous-routine se termine) à la méthode appelée. Des méthodes projet peuvent s'appeler les unes les autres, et en particulier :
Cela s'appelle la récursivité. Le langage de 4D supporte pleinement la récursivité. Examinons l'exemple suivant : vous disposez d'une table [Amis et relations] composée de l'ensemble de champs suivant (très simplifié) : 1. Vous pouvez procéder de la manière suivante : $vsNom:=Demander("Saisissez le nom :";"Pierre") 2. Vous pouvez également procéder ainsi : $vsNom:=Demander("Saisissez le nom :";"Pierre") en utilisant la fonction récursive Généalogie de suivante : ` Méthode projet Généalogie de Vous notez que la méthode Généalogie de s'appelle elle-même. La première manière de procéder utilise un algorithme itératif. La seconde manière utilise un algorithme récursif. Lorsque vous implémentez du code pour traiter des cas comme celui décrit ci-dessus, vous aurez toujours le choix entre écrire des méthodes utilisant des algorithmes itératifs ou récursifs. Généralement, la récursivité permet d'écrire du code plus concis, lisible et plus facilement modifiable, mais utiliser la récursivité n'est absolument pas obligatoire. Dans 4D, la récursivité est typiquement utilisée pour :
Important : Les appels récursifs doivent toujours se terminer à un moment donné. Dans l'exemple ci-dessus, la méthode Généalogie de cesse de s'appeler elle-même lorsque la recherche ne trouve plus d'enregistrement. Sans ce test conditionnel, la méthode s'appellerait indéfiniment et 4D pourrait au bout d'un certain temps retourner l'erreur “La pile est pleine” car le programme n'aurait plus assez de place pour "empiler" les appels (ainsi que les paramètres et les variables locales utilisés dans la méthode).
Voir aussi
Conditions et boucles
|
PROPRIÉTÉS
Produit : 4D
HISTORIQUE
UTILISATION DE L'ARTICLE
4D - Langage ( 4D v16) |
|||||||||||||||||||||