|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Dans l'article précédent, nous avons vu comment programmer une base de données, ou du moins comment concevoir une application de base, point de départ de vos futures bases de données. Dans l'état, l'exemple donné ne permettait pas de faire autre chose que de créer un fichier d'adresses, d'effectuer des saisies et d'en supprimer, de se déplacer dans le fichier. Pour le rendre plus performant (et surtout plus utile) nous allons rajouter les possibilités suivantes : recherche d'un élément, impression des adresses, tri du fichier, ajout de fenêtre de requête... Pour bref rappel, disons qu'une base de données est une suite d'enregistrements (ou entrées). Chaque enregistrement regroupe le contenu de tous les objets (champs de saisie, documents...) dont le nom commence par un point (exemple : un champ de saisie ".prénom"). Pour rajouter ces options, il est nécessaire de voir en détail deux notions que j'ai rapidement abordées dans cette série d'articles : l'utilisation des sous-decks et le recours aux variables "aliasées". Ce sera donc l'objet de cet article. Les fenêtres de requête Dans un programme, il y a toujours une raison de faire intervenir l'utilisateur pour se prononcer sur un choix, au moins lorsqu'il désire quitter le programme. Vous êtes habitué à ces fenêtres qui s'ouvrent et demandent si oui ou non vous confirmez un choix, d'entrer un texte, ou de sélectionner une information, etc. Ces types de requêtes sont-ils facilement programmables avec CanDo ? Oui, si on a déjà compris comment se construit une application CanDo car une requête doit être pensée comme une nouvelle application. Comme une application (un deck) est composée d'une carte et qu'une carte n'a qu'une fenêtre, il faut, pour ouvrir une fenêtre supplémentaire, créer une deuxième application. Bien entendu cette deuxième application doit être liée à l'application principale. C'est en termes CanDo un sous-deck, l'application principale elle est un ParentDeck.
...permet de charger un sous-deck. Ensuite, pour s'en servir, il suffit d'utiliser une des deux instructions suivantes : OpenRequester et OpenWindow, la seule différence étant qu'OpenRequester bloque l'application principale tant qu'on n'a pas quitté la requête ainsi ouverte. La syntaxe est :
Dans le deck d'exemple, on ouvre deux sous-decks dans le script "AfterAttachment" de nom interne "Chercher" et "Req". Dialogue ParentDeck <-> sous-deck ParentDeck et sous-deck ne partagent ni documents, ni variables... Par contre, on peut passer des arguments (de 1 à 10 comme toujours) lors de l'appel, ou utiliser SendMessageToParentDeck ou SendMessageToSubDeck (avec des arguments). Dans ce cas les scripts MessageFromSubDeck ou MessageFromParentDeck seront exécutés. Un peu complexe ? Regardons l'exemple plus bas de la demande de confirmation de quitter dans "MaBaseDeck". Lorsqu'est choisi le menu "Quitter", le script "Occured" appelle la requête "Req" à la carte "OuiNon", il indique la routine à exécuter si on clique "Oui" et le texte à afficher. Dans le sous-deck (notre requête), la variable "RoutineRetour" (dans le script "AfterAttachment") mémorise la routine à exécuter lors du retour au ParentDeck (ici routine "Quitter"). Si on clique "Oui", le script du bouton fait exécuter la routine "QuitterAvecArg" qui, par l'instruction SendToParentDeck RoutineRetour, fait exécuter le script MessageFromSubDeck de "MaBaseDeck"... Celui-ci exécute alors la routine "Quitter" passée comme Arg1... Ouf ! C'est la même procédure pour la confirmation d'imprimer. Généralités De cette relative complexité de départ, il faut retenir un objet de satisfaction... il suffit d'avoir quelques requêtes de base et de les réutiliser au besoin. Les exemples "Alerte" et "OuiNon" peuvent resservir sans modifications. Dans les applications, le script "MessageFromSubDeck" sera toujours identique. Le même type de script peut servir comme script "MessageFromParentDeck" dans un sous-deck. Dans ce cas, ce script est à solliciter plus spécialement lorsque l'on veut faire exécuter une action (ou plusieurs) à un sous-deck sans pour autant cesser d'utiliser l'application principale. Analyse d'un sous-deck spécifique Revenons à notre base de données pour voir comment a été conçu le SudDeck "Chercher". Dans cet exemple, nous savons qu'un enregistrement de la base est composé d'une suite d'éléments (nom, prénom, etc.), mais dans une autre base les éléments seront forcément différents. Or, l'utilisateur doit indiquer sur quel élément d'un enregistrement il veut effectuer une recherche. S'il recherche l'adresse de "Durand" il doit saisir "Durand" et indiquer qu'il s'agit d'un nom. Ce qui suppose d'avoir recours à une requête. ![]() Pour connaître le nom de chaque élément d'un enregistrement, il suffit d'utiliser l'instruction :
...qui insère dans un document le nom de chaque élément de l'enregistrement "Variable". Un document de type "list" convient à cette tâche, et affiche les différents noms. Il faut aussi un champ de saisie pour saisir le texte à rechercher. Bon, jusque-là c'est assez facile... Cela se complique un peu lorsqu'il s'agit d'échanger des données entre l'application et la requête. Que doit savoir la fenêtre de requête ?
...que je décode : ouvre la requête "Chercher", à la "Carte.1", la routine de retour sera "Rechercher Entrée", le texte par défaut sera celui de la variable "MotRechercher", l'élément de recherche sera par défaut "RechercherSur", et Var indique l'enregistrement à traiter... Mais pourquoi des Alias("MotRechercher") et Alias("RechercherSur") ? Bonne question... Il s'agit d'une méthode pour obliger le sous-deck à pointer sur une variable du ParentDeck, et donc d'établir un pseudo-partage de variables. Reportez-vous aux listings exemples plus bas et suivons le chemin de la variable "MotRechercher" (son contenu est sans importance).
De cette façon, la variable "MotRechercher" est remise à jour automatiquement dès que l'utilisateur change le texte à chercher. Le même principe est appliqué avec la variable "RechercherSur". Exemple Deck "MaBaseDeck" Ce Deck vu le mois dernier ne contient que la description des objets et des routines rajoutés. Pour mémoire, les routines non listées sont : "Afficher Entrée", "Ajouter entrée", "Entrée Précédente", "Entree Suivante", "Ouvrir Base", "Sauver MaBase". Les routines "Effacer entrée", "Rechercher Entrée" et "Trier MaBase", ont été reprises afin de permettre une meilleure compréhension ou parce qu'elles ont été légèrement adaptées. De même, les scripts listés ne sont que les nouveaux ou ceux qui ont été modifiés.
Pour la fenêtre, modifiez le script "OnCloseButton" afin d'avoir une demande de confirmation lorsque vous voulez quitter, il devient :
Dans le même esprit, changer le script OnRelease du bouton "Effacer" par :
Script "AfterAttachment" : ![]() ![]() ![]() Ajoutez au menu "Fichier" l'option "Imprimer" qui aura deux sous-menus : Le menu "CetteAdresse" aura le script "Occured" : ![]() ![]() ![]() ![]() ![]() ![]() Routine "Effacer Entrée" ![]() ![]() ![]() Dans cette routine, ARG1 = "Valeur à chercher", ARG2 = "Key" de recherche (élément d'une entrée)". Exemple : Do "Rechercher Entrée","DURAND","Nom" ![]() Ici, ARG1 = "key" pour un tri. Exemple : Do "Trier MaBase","Nom". ![]() Les fenêtres (une par carte bien sûr) doivent être a priori sans gadget, et surtout avoir l'option "Try to open on current screen" pour qu'elles s'ouvrent sur le même écran que celui de l'application. A vous d'adapter la taille, la position des objets et des textes. La nouvelle instruction "ResizeWindow" (changer la taille de la fenêtre) de la version 1.6 peut ici trouver une utilité afin de faire coïncider la dimension de la fenêtre avec celle de l'écran sur lequel elle s'ouvre. Carte "Alerte" Script AfterAttachmemt : ![]() Un bouton "OkBut" de type "Area" avec comme script "OnRelease" :
Un objet "Key" (touche clavier) qui réagira à l'appui d'une touche quelconque (donc mettre "ANY" comme touche à attendre) comme si on avait cliqué le bouton "OK". Le script "OnDown" est identique au bouton :
Carte "OuiNon" Script AfterAttachment : ![]() Objets D'un bouton "OuiBtn" de type "Area" avec un script "OnRealease" :
D'un bouton "NonBtn" de type "Area" avec un script "OnRelease" :
Un objet "Key" (touche clavier) qui réagira à l'appui de la touche "O" avec un script "OnDown" :
Un autre objet "Key" qui réagira à la touche "N" avec script "OnDown" :
Routines Ces deux routines peuvent servir à plusieurs types de requêtes, ici il n'y a pas de raison de renvoyer des arguments en ce qui concerne la carte. Routine "QuitterAvecArg" ![]() ![]() ![]() Objets : Un bouton "NonBtn" de script "OnRelease" :
Un bouton "OuiBm". Script "OnRelease" :
D'un document de type "Liste" ayant pour nom de document "Doc". Un champ de saisie de nom "Champ", qui recevra le texte à chercher. Routines : Routine "QuitterAvecArg" ![]() ![]()
|