Changements récents - Rechercher:

Tutoriel Filemaker

  1. Structure
  2. Modèles
  3. Opérations diverses
  4. Calculs
  5. Scripts
  6. Privilèges d'accès

Filemaker avancé

  1. Partage des données
  2. Astuces et Exemples
  3. Développement

Règles de nommage

Versions de FileMaker Pro

Liens utiles Contact Commentaires

edit SideBar

Script avec boucle

<==Recherche par Activer enreg. liés ^ Scripts Lecture de documents PDF==>

Une possibilité intéressante dans les script est l'utilisation de boucles, à l'instar de tous les programmes de gestion de bases de données.

Une boucle permet simplement la répétition, un certain nombre de fois, d'une série de lignes de commandes.

Une boucle doit comporter 3 éléments :

  • La commande "Boucle" qui indique le point de départ de la boucle
  • La commande "Fin de boucle" qui indique la fin de la boucle, c'est-à-dire le point à partir duquel on remonte au départ, ou on quitte la boucle
  • Une condition de sortie de boucle

Ce dernier élément est à contrôler sévèrement, afin d'éviter des boucles infinies... Il existe deux méthodes de sortie de boucle :

  • La commande "Afficher enreg/requête/page [Suivant(e) ; Fin de script après dernière]", dont le nommage peut prêter à confusion : "Fin de script après dernière" ne signifie en rien que le script est terminé après que le dernier enregistrement soit atteint, mais bien la boucle et seulement elle (fin de boucle après dernière eut été préférable) !
  • La commande "Fin de boucle si", qui permet, par calcul, d'imposer une condition de sortie de boucle. C'est souvent avec cette commande que l'on expérimente des boucles infinies, la condition calculée n'étant jamais rencontrée...

Illustrons cela par un exemple :

Description
Le Script




Description


Dans le fichier à jour, sur la table INS_Inscriptions, la rubrique zkc_Annee reprend l’année scolaire. On voudrait savoir, pour chaque personne, si elle est inscrite pour l’année en cours. Nous allons donc procéder à l’action suivante : rechercher les inscriptions de l’année en cours (Zkc_Annee renseigné), puis, pour chacune des inscriptions trouvées, compléter une rubrique AnneeInscription de la table PER_Personnes avec l’année scolaire en cours. Il faut donc commencer par créer cette nouvelle rubrique dans notre table PER__. On pourra ensuite la placer dans notre modèle PER_Fiche, par exemple.

Nous allons procéder par boucle au sein de la table PER pour renseigner successivement tous les enregistrements trouvés. Il faudra bien sûr se placer sur le 1er enregistrement avant de démarrer la boucle.

Il existe néanmoins un souci si le fichier est en réseau . Si une autre personne a activé un des enregistrements concernés dans la table PER, celui-ci ne pourra pas être mis à jour ! On va donc capter cette erreur possible et la signaler à la fin du script.

Le script


Bigre ! Voyons tout cela en détails...

Démarrage du script

Lorsqu'on veut prendre le contrôle total d'un script, on en contrôle les erreurs possibles, on empêche l'utilisateur d'interrompre le script et on désigne le modèle sur lequel on démarre. D'où les 3 lignes de commandes :

Gestion erreurs [Oui]
Autor. annulation utilisateur [Non]
Activer Modèle ["INS_Fiche" (INS__)]

Comme nous allons tester une boucle, l'instruction qui interdit les annulation par l'utilisateur sera désactivée le temps de la mise au point (c'est plus prudent).

Année scolaire en cours

Au lieu de définir directement l’année scolaire en cours par calcul directement dans les critères de recherche, on va "embarquer" la valeur du calcul dans une variable $annee, via la commande définir variable :

Comme cette variable ne sert que pour ce script, un seul $ suffit (variable de script)

Le calcul de la variable :

Cas(
Mois ( Obtenir (DateActuelle)) > 9 ;
Annee (Obtenir (DateActuelle)) & "-" & (Annee ( Obtenir (DateActuelle)) +1) ;
(Annee (Obtenir (DateActuelle)) - 1) & "-" & Annee ( Obtenir (DateActuelle) )
)

Comme c’est cette valeur qui sera également introduite dans chaque enregistrement de la table PER, on ne fera le calcul qu’une seule fois pour renseigner la variable. La mise à jour dans PER utilisera $annee au lieu du calcul. De la même manière, nous utilisons la variable dans la recherche. L'objectif est bien de trouver tous les enregistrements de la table INS créés pour l'année en cours, c'est-à-dire les enregistrements dans lesquels la valeur de(INS__::) Zkc_Annee est égale à l'année courante :

Gestion d'erreur

Comme on a décidé de gérer nous-même les erreurs, on va appliquer une gestion d'erreur sur la recherche en cas d'enregistrements non trouvés :

Boucle

Avant de démarrer la boucle, on n’oublie pas de se positionner sur le 1er enregistrement. Si vous vous placez sur le premier enregistrement dans la boucle, en première instruction par exemple, chaque "tour" ré-activera le premier enregistrement. Voilà une erreur classique qui génère une boucle infinie.

Notre boucle ne contient en fait que deux instructions :

Boucle
Définir rubrique [ ins_PER__::AnneeInscription ; $annee ]
Afficher enreg/requête/page [ Suivant(e) ; Fin de script après dernière ]
Fin de boucle
  • Définir rubrique ins_PER::AnneeInscription = $annee. Cette ligne met à jour avec la valeur de $annee la rubrique AnneeInscription.
  • Afficher enreg/requête/page [ Suivant(e) ; Fin de script après dernière ] active l'enregistrement suivant. Elle indique également la condition de sortie de la boucle
    • il faut évidemment placer cette ligne après l'action a effectuer, sinon le premier enregistrement sera ignoré
    • comme elle est immédiatement suivie par "Fin de boucle", après l'affichage de l'enregistrement suivant, on "remonte" au début (instruction "Boucle") pour ré-exécuter les lignes de commande
    • il ne faut surtout pas oublier de cocher "Fin de script après dernière", sinon nous n'avons aucun moyen de sortir de la boucle
      • "Fin de script après dernière" présente une double ambiguïté. Comme nous l'avons vu, le terme script est erronée et il faut lire boucle à sa place. De plus on pourrait craindre que le dernier enregistrement soit ignoré. Il n'en est rien. En effet, tant que l'instruction peut activer un enregistrement suivant, il va remonter au début de la boucle. Le constat du dernier enregistrement se fait uniquement lorsque, justement, on ne peut plus exécuter l'action d'affichage du suivant (il n'y a plus). Alors on considère que le dernier est atteint et a été traité, et on passe à la fin de boucle.

Durant la boucle, on va capter une erreur éventuelle, possible en réseau. Pour ce faire, si nous détectons une erreur lors de la mise à jour, on va monter les nom et prénom de l’enreg. correspondant dans une variable $$foutu avant de continuer la boucle, et, à fin de lisibilité, sous forme de liste :

La définition de la variable $$foutu est comme suit :

$$foutu & "¶" &
ins_PER__::Nom & ins_PER__::Prenom

On reprend la valeur de la variable (vide au début), on lui rajoute un retour chariot (& "¶" & ) et les nom et prénom. Ainsi, à chaque erreur, la variable sera augmentée d’un retour chariot et d’un nouveau jeu de nom et prénom. Le résultat sera donc une liste. Il suffira donc ensuite de vérifier si la variable est vide ou non. Comme cette variable doit nous servir à repérer une erreur, nous préférons pouvoir conserver sa valeur même après la fermeture du script. D'où son nom précédé de $$ (variable de session).

Pour poursuivre la boucle, comme nous l'avons vu, il faut aller à l’enreg. suivant. On en profitera pour indiquer à FileMaker Pro d’arrêter la boucle après le dernier enregistrement.

Lorsqu'on sort de la boucle, tous les enregistrements ont été passés en revue. Nous nous arrêtons donc sur le dernier enregistrement. En règle générale, nous allons revenir au 1er enregistrement :

Résultat des erreurs de boucle

Après la fin de la boucle de mise à jour, on va vérifier si la variable $$foutu est vide ou non. Dans ce dernier cas, on affichera une boite de dialogue avec la valeur de $$foutu :

Le texte de la boite de dialogue est sous la forme suivante :

"les noms suivants n'ont pas pu être mis à jour :" & "¶" &
$$foutu

Nota : ne cherchez pas dans la liste la fonction Not EstVide ! Vous venez de découvrir l'usage d'un opérateur FileMaker Pro : Not, qui permet d'inverser une (quelques) fonction(s), comme, ici, EstVide ().

Remarque : A nouveau, & "¶" & sert de retour à la ligne. A noter que & "¶¶" & créera, outre un retour à la ligne, également une ligne de séparation vide.

Comme nous exécutons ce script sur le modèle INS_Fiche, il nous reste à placer un bouton sur ce modèle pour lancer ce script.

Si on lance le script, on constate dans un premier temps :

  • que la totalité des enregistrements de INS ont été trouvés
  • que nous sommes bien revenu sur le premier enregistrement

Passons sur notre modèle PER_Fiche. Si on lance une recherche en renseignant l'année en cours dans la rubrique AnneeInscription, nous trouvons bien nos 62 inscrits. Plus intéressant, on lance cette même recherche, mais en cochant la case exclure...

nous obtenons la liste des personnes présentes dans la base mais non encore inscrites.

Dernier point pour sécuriser ce script. Notre vérification d'erreur nous permet de lister les cas non traités. Bien sûr, une fois ceux-ci repérés, on peut aller les renseigner individuellement. Ou on peut aussi demander aux utilisateurs connectés de quitter les enregistrements concernés pour relancer le script afin qu'il traite tous les enregistrements à nouveau.

Mais nous avons défini $$foutu comme une variable de session. Donc, même une fois le script terminé, celle-ci conserve sa valeur. Si nous relançons le script sans avoir fermé et réouvert la base, le contenu de $$foutu restera le même, ou se complètera par les nouvelles erreurs, s'il y en a... Pour éviter cela, nous allons, en début de script, vider cette variable par l'instruction

Définir variable [ $$foutu ; Valeur : "" ]

Allez, un tout dernier pour la route (et pour ceux qui n'ont pas tout bien fait).

Il se peut que vous obteniez, après avoir exécuté notre script sur le fichier construit au fur et à mesure, le message suivant :

Pas de panique ! C'est simplement parceque vous avez certainement éliminé un enregistrement de la table PERsonnes qui était inscrit dans une classe, et que vous n'avez pas supprimé l'enregistrement correspondant de la table INS. Cet enregistrement est trouvé dans INS pour l'année en cours, mais il n'a pas (plus) d'enregistrement lié dans la table PER. Une erreur est générée, mais il n'y a évidemment ni nom ni prénom à afficher.

Au point où nous en sommes, on peut donc, avec des fonctions que nous connaissons déjà, modifier légèrement la fin de notre script pour envoyer un message du genre "tous les enregistrements ont été traités" si tout c'est bien passé et notre message d'erreur si $$foutu n'est pas vide.

Mais il y a aussi une leçon à retenir de ce type de message... Même si on ne comprend pas bien ce qui se passe et que le résultat semble aberrant (un message d'erreur alors que $$foutu ne semble rien contenir), avant de mettre le logiciel en cause, il faut (et il suffit souvent) se remettre soi-même en cause pour essayer de comprendre et de corriger. 99,99 fois sur 100 l'erreur est humaine, pas informatique.

Et voici notre fichier à jour.

<==Recherche par Activer enreg. liés ^ Scripts Lecture de documents PDF==>
Éditer - Historique - Imprimer - Changements récents - Rechercher
Page mise à jour le 26 septembre 2017 à 07h43