2.5Événements & traitements WLangage
WinDev fonctionne par ÉVÉNEMENTS : le code n'est pas exécuté du début à la fin comme un script, il est DÉCLENCHÉ en réaction à quelque chose (l'utilisateur clique, une fenêtre s'ouvre, une valeur change). Comprendre QUEL code s'exécute QUAND est indispensable — c'est la source de confusion n°1 chez les débutants. Chaque élément (fenêtre, champ, bouton) possède une LISTE d'ÉVÉNEMENTS dans lesquels on peut écrire du code, appelés TRAITEMENTS dans le vocabulaire WinDev.
Les traitements les plus utilisés. Pour une FENÊTRE : Déclarations globales (les variables communes à toute la fenêtre — exécutées en premier), Initialisation (à l'ouverture : charger les données, préparer l'écran), Fermeture (nettoyage, contrôles avant de quitter). Pour un BOUTON : Clic (l'essentiel — l'action à exécuter). Pour un CHAMP DE SAISIE : Entrée (le champ prend le focus), Sortie (on le quitte — idéal pour CONTRÔLER la saisie), Modification (le contenu change — pour réagir en direct). Pour une TABLE : sélection d'une ligne, affichage d'une ligne. Une notion importante est l'ORDRE d'exécution : les déclarations globales, puis l'initialisation, puis les événements au fil des actions de l'utilisateur. Bonnes pratiques : mettre peu de code dans les événements et déléguer à des PROCÉDURES nommées (le code métier ne doit pas vivre dans un bouton) ; écrire chaque traitement au BON endroit (un contrôle de saisie va dans la sortie du champ concerné, pas dans le clic du bouton Valider) ; et se méfier des EFFETS EN CASCADE (un code qui modifie un champ peut déclencher l'événement de modification de ce champ).
Vocabulaire de la section
- Événement / traitement
- Le code n'est pas linéaire : il est DÉCLENCHÉ en réaction à une action (clic, ouverture, changement de valeur). Dans le vocabulaire WinDev, ces blocs de code s'appellent des TRAITEMENTS.
- Déclarations globales
- Le traitement exécuté EN PREMIER pour une fenêtre : on y déclare les variables communes à toute la fenêtre.
- Initialisation / Fermeture
- INITIALISATION s'exécute à l'ouverture de la fenêtre (charger les données, préparer l'écran) ; FERMETURE au moment de quitter (nettoyage, contrôles ultimes).
- Entrée / Sortie / Modification
- Les traitements d'un champ de saisie : ENTRÉE (le champ prend le focus), SORTIE (on le quitte — l'endroit idéal pour CONTRÔLER la saisie), MODIFICATION (le contenu change).
- Effets en cascade (⚠️)
- Un code qui modifie un champ peut DÉCLENCHER l'événement de modification de ce champ, provoquant des enchaînements inattendus (voire des boucles). À anticiper.
Pourquoi ne faut-il pas écrire toute la logique métier dans le clic d'un bouton ?
En pratique — Placer son code au bon endroit
- Ouvrez la liste des TRAITEMENTS d'une fenêtre et repérez l'ordre : Déclarations globales, puis Initialisation, puis les événements au fil des actions.
- Écrivez le chargement des données et la préparation de l'écran dans l'INITIALISATION de la fenêtre.
- Placez les CONTRÔLES DE SAISIE dans la SORTIE du champ concerné (pas dans le clic du bouton Valider) pour un retour immédiat à l'utilisateur.
- Gardez les événements COURTS : déléguez la logique métier à des PROCÉDURES nommées, et méfiez-vous des effets en cascade quand du code modifie un champ.
Points clés à retenir
- WinDev fonctionne par ÉVÉNEMENTS : le code est DÉCLENCHÉ en réaction (clic, ouverture, changement) et non exécuté linéairement. Comprendre QUEL code s'exécute QUAND est la difficulté n°1 des débutants.
- Traitements essentiels — FENÊTRE : Déclarations globales (en premier), Initialisation (ouverture : charger, préparer), Fermeture. BOUTON : Clic. CHAMP DE SAISIE : Entrée, SORTIE (idéale pour CONTRÔLER la saisie), Modification. TABLE : sélection/affichage de ligne.
- Bonne pratique majeure : METTRE PEU DE CODE dans les événements et déléguer à des PROCÉDURES nommées — le code métier ne doit pas vivre à l'intérieur d'un bouton (sinon il est ni réutilisable, ni testable, ni maintenable).
- Écrivez chaque traitement au BON ENDROIT (un contrôle de saisie dans la sortie du champ, pas dans le clic du bouton Valider) et ⚠️ méfiez-vous des EFFETS EN CASCADE : modifier un champ par code peut déclencher son événement de modification.
Questions fréquentes
Pourquoi ne faut-il pas écrire toute la logique métier dans le clic d'un bouton ?
Parce que le code enfermé dans un bouton n'est ni RÉUTILISABLE, ni TESTABLE, ni maintenable : la même règle métier devra être recopiée ailleurs (et corrigée partout), et le bouton devient un fourre-tout illisible. Déléguez à des PROCÉDURES nommées. Le problème du « tout dans le bouton » : (1) DUPLICATION inévitable. La règle « calculer le total d'une commande avec remise » sert dans la fenêtre de saisie, dans l'état, dans un traitement par lot, dans un import. Si elle vit dans le clic d'un bouton, il faudra la RECOPIER partout. Le jour où la règle change (nouveau taux, nouvelle condition), il faudra la corriger à chaque endroit — et vous en oublierez un. Les incohérences qui en résultent sont parmi les bugs les plus difficiles à traquer. (2) ILLISIBILITÉ. Un événement de clic contenant 200 lignes mêlant contrôles, calculs, accès aux données et affichage devient impossible à comprendre et à modifier sans risque. (3) Pas de TEST possible : on ne peut pas tester un bouton isolément. Une procédure, si. (4) Couplage à l'INTERFACE : la règle métier devient prisonnière d'une fenêtre. Si demain la même règle doit s'appliquer dans WEBDEV ou dans un service web, tout est à réécrire. (5) MAINTENANCE : impossible de savoir où sont les règles métier — elles sont éparpillées dans les écrans. La bonne organisation : (1) L'ÉVÉNEMENT orchestre, la PROCÉDURE exécute. Le clic du bouton doit se lire comme un résumé : contrôler la saisie, calculer, enregistrer, informer l'utilisateur — chaque étape étant un appel de procédure. Quelques lignes lisibles. (2) Une procédure = UNE responsabilité, avec un nom explicite (CalculeTotalCommande, ContrôleSaisieClient, EnregistreCommande). (3) Regroupez les procédures métier dans des collections de procédures (voir niveau 3) ou des classes, séparées des fenêtres. (4) Les procédures deviennent RÉUTILISABLES partout : autre fenêtre, état, traitement par lot, service web — une seule définition, une seule correction. (5) Testez les procédures indépendamment de l'interface (tests automatiques, voir niveau 4). Comment s'y prendre concrètement : (1) Quand un événement dépasse une vingtaine de lignes, c'est un signal : découpez. (2) Quand vous vous apprêtez à COPIER-COLLER du code, arrêtez-vous : c'est le signe qu'il faut une procédure. (3) Demandez-vous : « cette règle est-elle propre à CET écran, ou est-ce une règle du MÉTIER ? ». Si c'est le métier, elle ne doit pas vivre dans un écran. (4) Gardez dans l'événement ce qui concerne réellement l'INTERFACE : lire les champs, afficher un message, ouvrir une fenêtre, rafraîchir un affichage. (5) Nommez explicitement : le code doit se lire comme une phrase. En résumé : n'écrivez pas la logique métier dans le clic d'un bouton parce qu'elle s'y retrouve DUPLIQUÉE (la même règle sert dans plusieurs écrans, dans les états, dans les imports — et une modification devra être répercutée partout, avec des oublis garantis et des incohérences très difficiles à diagnostiquer), ILLISIBLE (un événement de 200 lignes mêlant contrôles, calculs, données et affichage devient intouchable), NON TESTABLE (on ne teste pas un bouton, alors qu'on teste une procédure) et COUPLÉE À L'INTERFACE (impossible de réutiliser la règle dans WEBDEV, dans un traitement par lot ou dans un service web). La bonne organisation consiste à faire de l'ÉVÉNEMENT un simple ORCHESTRATEUR — quelques lignes qui se lisent comme un résumé : contrôler, calculer, enregistrer, informer — chaque étape étant déléguée à une PROCÉDURE nommée, ayant une seule responsabilité, regroupée avec les autres procédures métier hors des fenêtres. Ces procédures deviennent alors réutilisables partout, corrigibles en un seul endroit et testables indépendamment. Deux signaux pratiques doivent déclencher le découpage : un événement qui dépasse une vingtaine de lignes, et l'envie de faire un copier-coller de code. Gardez dans l'événement ce qui relève vraiment de l'interface : lire les champs, afficher un message, ouvrir une fenêtre.
Où placer les contrôles de saisie : dans le champ ou au moment de valider ?
Faites LES DEUX, mais pour des raisons différentes : les contrôles au fil de la saisie (sortie de champ) donnent un retour IMMÉDIAT et confortable, tandis que le contrôle global à la validation est INDISPENSABLE car il seul garantit qu'aucune donnée invalide n'est enregistrée. Le contrôle au fil de la SAISIE (sortie de champ) : (1) Avantage : retour IMMÉDIAT. L'utilisateur est informé de son erreur au moment où il quitte le champ, pendant qu'il y pense encore et qu'il a le contexte en tête. C'est bien plus confortable que de découvrir dix erreurs à la fin. (2) Bon pour : format d'une date, validité d'un code, existence d'une référence (le client saisi existe-t-il ?), calculs dépendants (recalculer un total dès qu'une quantité change). (3) Attention à ne pas être trop AGRESSIF : bloquer l'utilisateur dans un champ tant qu'il n'a pas corrigé (en l'empêchant d'aller ailleurs ou même d'annuler) est très frustrant — un cas classique de mauvaise expérience. Préférez signaler (message, mise en évidence visuelle) sans emprisonner. (4) Attention aussi aux contrôles déclenchés trop tôt (sur un champ à peine effleuré) ou qui interrogent la base à chaque frappe. Le contrôle GLOBAL à la validation : (1) Il est INDISPENSABLE : c'est le dernier rempart avant l'enregistrement. Un utilisateur peut avoir contourné les contrôles de champ (champ jamais visité, valeur modifiée par code, navigation inattendue). (2) Bon pour : les champs OBLIGATOIRES non renseignés, la COHÉRENCE ENTRE plusieurs champs (date de fin postérieure à la date de début, total conforme aux lignes), les règles métier globales (un client bloqué ne peut pas commander). (3) Ne pas enregistrer tant que tout n'est pas valide : c'est une question d'INTÉGRITÉ des données. Mieux vaut refuser un enregistrement que stocker des données incohérentes — car des données fausses en base sont bien plus coûteuses à corriger ensuite. (4) Signalez CLAIREMENT ce qui ne va pas : indiquez le champ concerné, donnez un message compréhensible et positionnez le curseur dessus. Un « Erreur de saisie » sans précision est inutilisable. Les bonnes pratiques d'ensemble : (1) Messages UTILES : dites ce qui ne va pas ET comment corriger (« La date de fin doit être postérieure à la date de début »), pas « Valeur incorrecte ». (2) Prévenez plutôt que guérir : contraignez la saisie à la source (listes déroulantes, sélecteurs de date, masques de saisie, valeurs par défaut). Un champ qui n'accepte que des valeurs valides ne nécessite aucun contrôle. (3) Centralisez les règles dans des PROCÉDURES réutilisables : la même règle doit valoir dans l'écran, dans un import et dans un traitement par lot. (4) Contrôlez aussi côté DONNÉES : contraintes et intégrité référentielle dans l'analyse — l'interface n'est pas le seul chemin vers la base. (5) Testez les cas limites (champ vide, valeurs extrêmes, caractères spéciaux). En résumé : faites LES DEUX. Les contrôles au fil de la saisie (dans la SORTIE du champ) apportent un retour IMMÉDIAT et confortable — l'utilisateur corrige pendant qu'il a le contexte en tête — et conviennent au format d'une date, à la validité d'un code, à l'existence d'une référence ou aux recalculs en direct ; veillez seulement à ne pas être agressif au point d'emprisonner l'utilisateur dans un champ. Mais le contrôle GLOBAL au moment de VALIDER reste INDISPENSABLE : c'est le dernier rempart avant l'enregistrement, le seul capable de vérifier les champs obligatoires jamais visités et surtout la COHÉRENCE ENTRE plusieurs champs (dates, totaux, règles métier) — et il ne faut jamais enregistrer tant que tout n'est pas valide, car des données incohérentes en base coûtent bien plus cher à corriger qu'un refus de saisie. Dans les deux cas, soignez les MESSAGES (dire ce qui ne va pas et comment corriger, désigner le champ, y placer le curseur), prévenez plutôt que guérir en contraignant la saisie à la source (listes, sélecteurs, masques, valeurs par défaut), CENTRALISEZ les règles dans des procédures réutilisables pour qu'elles s'appliquent aussi aux imports et aux traitements par lot, et complétez par les contraintes d'INTÉGRITÉ dans l'analyse — car l'interface n'est jamais le seul chemin vers les données.