|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 |
|
Membre Expert
![]() ![]() Etienne PailleretDéveloppeur VBA Inscription : mars 2004 Messages : 748 ![]() |
>>>> Merci de noter toutes remarques concernant ce cours dans le sujet parallèle : [Cours papyturbo]Commentaires, remarques et suggestions
------------------------------------------------------------------------- Ce cours est la suite - du [Cours pt-01][Débutants]Analyse structure base de données simple et - du [Cours pt-02][Débutants]Requête avec plusieurs sommes Il commence donc par une réponse aux questions posées par Serge57, dans la réponse #4 du cours précédent. ------------------------------------------------------------------------- Je regarde tes 2 formulaires : - 1 boîte de dialogue "Choix Affaire", pour choisir une affaire selon 2 critères (numéro ou classement -- je n'argumenterai pas sur ce que représente chacun de ces champs, je suppose qu'ils te conviennent en tant qu'utilisateur du logiciel) + 1 option pour créer une nouvelle affaire - 1 formulaire "SaisieAffaires", qui contient une affaire à la fois (pas de boutons de navigation...), en modification ou en ajout. Nous avons 2 choix : - soit, nous aménageons directement tes 2 formulaires, en conservant la même structure, ce qui sera plus rapide, - soit, le modèle de "turbo-formulaire" ci-dessous te plaît, et on prend le temps d'aborder chaque aspect 1 par 1. Le principe des "turbo-formulaires" (j'utilise ce type de formulaires dans toutes mes applications, depuis plus de 10 ans, avec quelques améliorations à chaque fois C'est à dire réunir sur un seul formulaire toutes les fonctions de recherche + filtrage + modification des enregistrements + ajouts... jusqu'à la préparation d'états spécifiques. Nous évoquerons certains pièges à éviter. La structure générale : - 1 formulaire principal, qui n'est lié à aucune donnée : il sert juste de conteneur. Son en-tête contient : + des listes déroulantes de "choix d'affaires" (autant que nécessaire). Ces listes joueront le même rôle que ta boîte de dialogue "Choix Affaire", mais sur place, donc un peu + rapide pour passer d'une affaire à l'autre, + en option, d'autres listes de sélection : par Client ou tout autre critère, selon tes besoins. Le principe général est à peu près le même que dans le Cours Construire un formulaire de recherche multi-critères de Caféine, avec variantes et adaptations : nous n'utiliserons pas une liste, mais nous filtrerons directement le contenu du formulaire Affaires (par exemple, pour n'avoir que les affaires d'un client...). Si nous allons jusqu'au bout, nous verrons comment utiliser ce choix pour imprimer des états qui contiennent les mêmes affaires, triées dans le même ordre qu'à l'écran... Autrement dit : sélectionner et trier les affaires en wysiwig, puis lancer un ou plusieurs états reprenant les mêmes tris + sélections. - le formulaire Affaires devient un sous-formulaire du conteneur ci-dessus : un bouton permet de le faire basculer entre mode feuille de données (pour voir la liste des affaires, lancer une recherche avec Ctrl+F, voir le résultat des tris et sélections mentionnés ci-dessus, etc.) et mode formulaire, évidemment + pratique pour les saisies (modifications, ajouts, la suppression étant possible dans les 2 modes). - de même, le formulaire Affaires contient un sous-formulaire SectionsAffaires, que l'on peut basculer d'1 clic entre les 2 modes : + en mode feuille de données, tu peux voir la liste des sections actives de l'affaire qui est à l'écran, avec un résumé des totaux d'heures allouées/passées par section, + en mode formulaire, chaque SectionAffaire contient tous les détails des sous-formulaires, à peu près comme les sous-formulaires dans l'application que tu as envoyée aujourd'hui : tu pourras ajouter des SectionsAffaires à tout moment, ajouter/modifier les heures que tu veux, dans l'ordre que tu veux... Nous n'irons pas plus loin que 3 niveaux de sous-formulaires imbriqués parce que ça suffit, parce que plus de niveaux devient confus et illisible et pour rester compatible avec Access 2000 (3 niveaux maximum). Quand je parle d'ergonomie, je ne m'intéresse pas, au départ, à faire de jolies images (tu peux toujours ajouter ça après J'attends ta décision, le temps de créer un nouveau sujet pour ce formulaire. ---------------------------------------- Maintenant, pour répondre à ta question : dans les 2 cas ci-dessus, seul le conteneur et le formulaire principal diffèrent. Toutes les heures (allouées/passées, pour Employés ou fournisseurs) tournent autour des SectionsAffaires. Donc, à mon avis, tout commence par un sous-formulaire Sections(Affaires), à l'intérieur du formulaire Affaires. Voir ci-dessus, la possibilité de voir un résumé des sections, en mode feuille de données, puis de basculer la section en mode formulaire pour les détails, les modifs, ajouts... Si tu veux absolument maintenir tous tes sous-formulaires d'heures (par exemple, les heures passées par Employé) directement sur le formulaire Affaires, avec une liste complète des sections concernées, il manquera juste une liste ou un bouton (on verra le + simple), pour ajouter une nouvelle section. Mais je ne suis pas du tout convaincu que cette approche soit + claire, parce que chaque liste affichera des sections différentes, pour la même affaire... Attention, cette question concernant l'architecture générale de l'application, du moins la partie traitée ici, est fondamentale. Bien sûr, c'est un exercice, donc tu peux t'offrir le luxe de faire les 2, puis de choisir la solution qui te convient. Mais, dans la réalité, le coût de revenir sur une décision trop rapide revient très cher. Aujourd'hui, ta solution ira + vite parce que tu la connais déjà. Et c'est un facteur de coût+vitesse primordial, qu'il ne faut jamais oublier. Demain, si tu sais faire un "turbo-formulaire", tu iras aussi vite, sinon plus, pour mettre en oeuvre ce genre d'architecture, par rapport à la solution "fractionnée". |
|
|
00
|
|
|
#2 | |||
|
Membre du Club
![]() Inscription : mai 2006 Messages : 79 ![]() |
Citation:
Exemple : Au début je ne voulais que suivre les affaires, donc un formulaire de création d’affaire, et les états qui vont bien … puis plus tard, la gestion des employés m'a apparu une bonne idée Citation:
Je t’ai donné mon état d’âme, mais comme tu m’a toujours bien conseillé (pour l’instant Citation:
Pour en revenir au « cours sur Requête avec plusieurs sommes », si une autre nouvelle requête principale a besoin d’une sous requête (mais que celle-ci existe déjà) est il préférable d’en créer une autre ou d’utiliser celle existante ??? |
|||
|
|
00
|
|
|
#3 | |||
|
Membre Expert
![]() ![]() Etienne PailleretDéveloppeur VBA Inscription : mars 2004 Messages : 748 ![]() |
Citation:
Citation:
Concernant les données, elle est limitée à un seul enregistrement : le dernier modifié. Et elle n'agit pas sur les suppressions. Nous en reparlerons. Sinon, j'ai réuni tes 2 citations parce qu'elles évoquent le même sujet : Considérant un ensemble de données liées sur un formulaire, faut-il créer - un formulaire séparé pour voir/atteindre les données ? - un autre pour les modifier ? - un autre pour en ajouter de nouveaux ? - un autre pour les suppressions ? Ma réponse est très claire : Non. Réponse basée sur des tests dans diverses applications, et les réponses des utilisateurs. Les demandes vont plutôt dans l'autre sens : regrouper tout ce qui concerne un sujet donné, et gérer le tout sur place. Pourquoi faire perdre son temps à l'utilisateur à passer constamment d'un formulaire à l'autre, alors qu'il pourrait faire la même chose, "sans bouger" ? Plus le fait que la multiplication des objets (ici, des formulaires) donc des routines de code, etc. va entraîner la multiplication des bugs... On invoque souvent des questions de sécurité, notamment : - absence, dans Access, de validation de la saisie, - suppressions abusives. Ces questions là n'ont, à mon avis, rien à voir avec le fait d'utiliser un seul, ou plusieurs formulaires. Nous en parlerons en temps utile, pour sécuriser les suppressions, valider toute saisie (modif/ajout), si tu y tiens... Ceci dit, cette réponse est très personnelle. Je propose de tester ensemble le "tout-en-un" que je défends d'un point de vue purement ergonomique. Libre ensuite à d'autres d'indiquer leurs solutions, et à chacun de choisir selon ses préférences... Citation:
- ce que tu décris est typique de la majorité des applications Access. Access est particulièrement à l'aise dans ces domaines où les besoins apparaissent succesivement, et se réalisent au fur et à mesure qu'on a le temps et les moyens de le faire. - il n'est pas question de mettre "toute ton application" sur un formulaire. Celui que nous allons construire gère un sous-ensemble de données cohérentes : une affaire + ses sections + les heures allouées/passées sur ces sections. Il faudra des formulaires séparés pour gérer les employés, les clients, les fournisseurs, etc. Rien ne t'empêchera plus tard, d'ajouter ce que tu veux, soit dans les mêmes formulaires (onglets séparés), soit dans des formulaires séparés... - cela évoque le sujet de la circulation entre formulaires, dont nous parlerons brièvement aussi (mais après avoir complété au moins ce fomulaire). ------------------- Puisque tu es d'accord, allons y : Je te propose de garder dans un coin tout ce que tu as déjà fait et - de partir de (sous-)formulaires totalement vierges, pour y voir plus clair, - de créer un formulaire principal : Affaires. Celui-ci, comme déjà indiqué ne doit avoir aucune source de données. Il contiendra : - une section entête, avec (pour l'instant) --- une liste déroulante [cmbChoixNoAffaires] (cmb pour CoMBo) permettant de choisir une affaire par son Numéro. Ce choix devra sélectionner l'affaire correspondante dans le sous-formulaire : évènement _AfterUpdate() du contrôle combobox. --- un bouton bascule [tglChangeVue] (tgl pour ToGgLe button) qui permettra de faire basculer les affaires entre le mode formulaire et le mode feuille de données : évènement _Click() - une section détails entièrement occupée par un sous-formulaire ssfAffaires. Le sous-formulaire ssfAffaires ne doit - contenir pour l'instant que la table des Affaires, avec les champs que tu souhaites voir et/ou modifier, (je conseille la création d'une requête, pour chaque source de formulaire : la requête porte le même nom que le formulaire, précédée d'un "F"). - s'ouvrir par défaut dans le mode que tu veux (formulaire ou feuille de données), mais doit avoir le droit d'utiliser les 2 vues. Toutes les autres options restent avec les valeurs par défaut pour l'instant : boutons de navigation, séparateurs,... rien en modal ni indépendant... Nous les reverrons en détail. Le but de l'exercice est de pouvoir : - afficher les affaires, dans les 2 vues, - atteindre n'importe quelle affaire. Il y a pas mal de boulot. À toi de jouer |
|||
|
|
00
|
|
|
#4 | ||
|
Membre du Club
![]() Inscription : mai 2006 Messages : 79 ![]() |
Remarques : J’ai écris mes réflexions au fur et à mesure que j’avançais dans la création du formulaire, donc il est fort possible que les réponses d’une question se trouvent dans la réflexion suivante.
1 - Pour la création des formulaires, vaut-il mieux utiliser l’assistant ?? 2 - Pour liste déroulante, et vu ta remarque Citation:
3 – J’ai constaté que pour avoir un lien entre le sous-formulaire ssfAffaires) et la liste déroulante cmbChoixAffaires je devais créer une requête interne au sous-formulaire. Citation:
Ci-joint base avec Formulaire brute de fonderie comme demandé. ![]() ------- Fichier attaché : SuiviAffaire 2006-07-24.zip (59,9 ko) ------- |
||
|
|
00
|
|
|
#5 | |||||
|
Membre Expert
![]() ![]() Etienne PailleretDéveloppeur VBA Inscription : mars 2004 Messages : 748 ![]() |
Citation:
Disons que, usage perso, j'utilise les assistants - jamais pour les tables, - quasi toujours pour une requête "Trouver les doublons", - souvent pour une 1ère mise en forme d'état (en colonne ou tabulaire...) - rarement pour les formulaires (mais ils sont rapides, c'est vrai) - jamais pour les contrôles (j'aime pas les codes d'erreur qu'il génère !) Citation:
Tu constateras que je l'ai enregistrée, selon les indications du cours précédent, réponse #7 1- pour une question de débogage : en enregistrant la requête séparément, et, entre autres, si cette requête contient une clause liée à la valeur d'un contrôle, sur le formulaire, c'est beaucoup plus facile - d'ouvrir le formulaire et mettre une valeur appropriée dans le contrôle concerné, pour le test, - ouvrir séparément la requête en question et la tester, en ajustant son contenu + références aux divers contrôles du formulaire (qui est ouvert à côté)... jusqu'à ce qu'elle soit impec. Il n'y a qu'un seul avantage à coller le SQL d'une requête directement dans une propriété d'un contrôle : dans les références à un autre contrôle, sur le même formulaire, tu peux mettre directement le nom du contrôle. Exemple : - sur le formulaire [NomFormulaire], - dans le contenu d'une liste déroulante qui est lié à la valeur d'une autre liste nommée[ListeDéroulanteTruc], - au lieu de mettre "=Formulaires!NomFormulaire!ListeDéroulanteTruc" - tu peux mettre juste "=ListeDéroulanteTruc" Si tout ça se passe dans un sous-formulaire, c'est plus simple que, par exemple, "=Formulaires!NomFormulaire!SousFormulaire.Formulaire!ListeDéroulanteTruc" 2- je me suis fait, comme tant d'autres, un utilitaire nommé Qsearch, qui cherche/remplace un texte quelconque dans tous les "SQL" des requêtes de la base : ça ne marche pas sur les requêtes qui ne sont pas enregistrées. Citation:
Mais, même si il en fallait un, ça ne changerait rien que la requête soit enregistrée séparément ou pas : elle marche aussi bien, pourvu que la référence au contrôle soit correctement qualifiée. Pour ça, une seule astuce imparable, et dont je me sers régulièrement : ouvrir l'assistant "baguette magique", sur la barre de boutons, et lui faire trouver le contrôle, parmi les formulaires chargés... (voir détails dans l'aide d'Access) Citation:
Détails ci-dessous.Citation:
-------------------- Erreur sur le formulaire principal : Il ne contient aucune donnée, donc, faut - affichage autorisé : seulement formulaire - Afficher sélecteur : Non - Boutons de déplacement : Non Noter que, pour le sous-formulaire Affaires, j'ai mis l'affichage "feuille de données" par défaut -> il s'ouvre en donnant une vue d'ensemble de la liste des affaires, avant que - soit, on choisisse celle avec laquelle on veut travailler dans une des listes déroulantes, - soit, on applique un critère de sélection (prochaine séance, dès que les 3 listes de choix sont en place) : on verra d'un coup d'oeil toutes les affaires d'un client, par exemple. C'est mon choix, mais restons clair : c'est à l'utilisateur de l'application, et pas au programmeur, de décider de choix comme celui là. le développeur propose, l'utilisateur dispose. Astuce (=proposition du développeur --------- Erreur dans la liaison entre la liste déroulante CmbChoixNoAffaires et le sous-formulaire Affaires : Tel que tu l'as fait, le sous-formulaire serait limité, de manière à n'afficher qu'une seule affaire. Pas bon, si on veut à tout instant, basculer entre vue feuille de données et vue formulaire. Ce qu'on veut faire ici : atteindre un enregistrement, parmi ceux qui sont affichés. Après, on appliquera des filtres... Donc un ssfAffaires.Form.Recordset.FindFirst sera la meilleure solution. L'ancienne méthode Docmd.Find... doit, si possible, être remplacée par celle là, qui a l'avantage de s'appliquer à l'objet recordset du (sous)formulaire. De plus, la nouvelle méthode permet de tester si la recherche est bonne : if .NoMatch... Et l'utilisateur peut toujours utiliser les boutons de navigation d'Access pour se balader d'affaire en affaire... Faut pas se priver, si c'est gratuit ! --------- Erreur dans la liste déroulante CmbChoixNoAffaires elle-même : Si on choisit par Numéro d'affaires, il faut que ce numéro soit visible dans la 1ère colonne. J'ai fait le choix suivant, en pensant aux 2 autres listes semblables qu'il faudra encore ajouter : - la 1ère colonne, généralement invisible, contiendra toujours l'IdAffaires : la clé primaire. On l'utilisera pour la recherche avec FindFirst, ne serait-ce que parce qu'elle est indexée et unique, donc impossible de se tromper d'affaire, et recherche + rapide. - du coup, elle est cachée, pour que le NumeroAffaire soit le 1er visible. - du coup, je la réaffiche plus loin, pour que l'utilisateur voit tout, lorsque la liste est déroulée. Ce qui fait : - 4 colonnes en tout - la colonne liée est (et sera toujours) la 1ère (idAffaires) - les largeurs varient selon le contenu de chaque colonne. Erreur : la propriété "Largeur Liste" ne doit pas être la largeur du contrôle (2.54 cm), mais celle de la liste, lorsqu'elle est déroulée = somme des largeurs de toutes les colonnes. --------- Classement des objets, dans la fenêtre base de données - renumérotation de tous objets concernés ici, conformément à la réponse d'aujourd'hui, sur le cours n°02, réponse #7 Là aussi, tu feras ce que tu voudras au final, mais j'essaie d'être cohérent entre les divers conseils et recommendations... - noter que, à condition que le formulaire et tous les objets soient bien fermés, il suffit de renommer une requête ou un sous-formulaire, dans la fenêtre de base de données, pour que les objets qui l'utilisent soient automatiquement corrigés par Access (à partir d'Access 2000) -> tu pourras les renommer/renuméroter comme tu préfères (ne pas hésiter à faire le test). --------- bouton bascule tglChangeVue : Basculer entre vue formulaire et vue feuille de données : - Non, la propriété DefaultView est la vue (formulaire ou continu ou feuille de données) par défaut, utilisée à l'ouverture du formulaire. La propriété qui indique la vue en cours d'un formulaire est Form.CurrentView. Mais elle est en lecture seule ! ![]() Seule méthode pour changer la vue, (à part l'ancienne technique atroce d'Access 97, à jeter aux oubliettes dès que possible : DoMenuItem... ) : Docmd.Runcommand accmd...Impératif : que le focus soit sur le sous-formulaire avant de lancer cette commande, sinon, ça ne marchera jamais (à toi de tester les messages d'erreur, en enlevant la commande .SetFocus ...) ---------- Présentation : Quelques touches de couleur pour bien différencier la zone de choix, pour atteindre une affaire, de la zone de données : - fond de l'entête d'une couleur bien contrastée, - liste pour atteindre une affaire, de la même couleur que les affaires en dessous Rappel : on mettra ensuite une ou des listes de sélection : pas la même couleur que les listes pour atteindre ! Faire joli, c'est pas interdit, même, ça crée des utilisateurs heureux, donc plus efficaces que si c'est moche. Mais là, bien sûr chacun ses goûts... ---------- IdAffaires : champ non modifiable, que j'aime bien voir en tête, parce que c'est l'identifiant. Même si il doit rester discret (police plus petite ?) D'ailleurs, maintenant que j'y pense,on pourrait le supprimer complètement ? À toi de voir ? Mes habitudes : tout champ non modifiable est - en relief et non pas en creux - fond transparent (plus discret, et pour l'utilisateur, ça devient vite inconsciemment "un champ non modifiable") - éventuellement verouillé (Locked = True/False), mais jamais désactivé (Enabled = true), sinon, il serait grisé -> illisible et surtout, on ne pourrait pas le copier (pour coller ailleurs...), ni se mettre dedans pour lancer une recherche avec Ctrl+F, ni... ni... ni... ni... En mode feuille de données, revoir l'ordre initial des colonnes, même si les utilisateurs pourront les changer librement. Et, éventuellement, figer les titres des affaires ou autres n°/dentifiants... de l'affaire, à gauche : menu Format > Figer les colonnes. ------------- Reste à faire : Il restera à - ajouter 2 autres listes semblables, pour atteindre une affaire en choisissant, soit le titre, soit l'Id (si on garde l'Id visible,pas obligatoire). L'ordre des colonnes changera d'une liste à l'autre, selon le choix à faire, bien sûr. - lier ces listes déroulantes entre elles : dès qu'on a fait un choix, non seulement le sous-formulaire se positionne sur l'affaire choisie, mais les autres listes déroulantes aussi -> affichage cohérent. - Prévoir un redimensionnement du sous-formulaire, pour remplir complètement le formulaire principal -> évènement Form_Resize du conteneur... - dès que c'est bon, on passe aux filtres : j'ai suggéré un filtre par client, à titre d'exercice, mais tu en as peut être d'autres qui seraient plus utiles ? On en fera idéalement 2 au moins (le 2ème est toujours + complexe que le 1er), et puis tu pourras en rajouter autant que tu veux après... |
|||||
|
|
00
|
|
|
#6 | |||
|
Membre du Club
![]() Inscription : mai 2006 Messages : 79 ![]() |
Citation:
Une recherche sur le titre je crois que ce n’est pas possible, champ mémo.(mais enfin la recherche m’intéresse. Donc je regarde dans mon appli qui tourne, si 255 caractères est suffisant pour la définition du titre et donc changer le type de donnés pour les passer en type texte). Dans la base je prends comme recherche le NuméroAffaire (champ n’étant pas obligatoirement croissant ou continu plutôt destiné à la comptabilité et crée hors BE), le classement (champ interne au bureau d’étude et chantier). Citation:
Citation:
Le code pour tglChangeVue, jamais j’aurai trouvé tout seul. C’est la différence entre un développement d’un développeur occasionnel et d’un professionnel. Donc je récapitule ce que j’ai fait : Rajouter un champ liste déroulante pour choix par classement, Fait suivre les différentes listes entre elles, Fait beaucoup d’exercices pour essayer la méthode, Et …. plus rien parce que bloqué. Pour les filtres, ce qui m’intéresse: Filtre par clients IdClients, Et filtre par Responsables Affaires IdEmployesRA. Le filtre doit agir sur le sous formulaire ssfAffaires ?? Donc quand il y a filtre aucune recherche n’est possible par les liste déroulantes ?? Le filtre doit agir sur les listes déroulantes pour limiter la recherche ?? J’en pose des questions hein !!! Fichier attaché avec quelques petites évolutions ( si l’on peut appeler évolution). Cours de plus en plus intéressant, parce que tout à fait nouveau la façon d'aborder les formulaires pour moi.(j'étais beaucoup plus basic). Il y aura un petit décalage d’une semaine dans mes réponses (semaine 31). Petit repos bien mérité (pas par le boulot, ni la formation, mais par la chaleur). ![]() ------- Fichier attaché : SuiviAffaire 2006-07-28.zip (64,5 ko) ------- |
|||
|
|
00
|
|
|
#7 | ||||||||
|
Membre Expert
![]() ![]() Etienne PailleretDéveloppeur VBA Inscription : mars 2004 Messages : 748 ![]() |
Citation:
D'ici la fin de l'été, je soupçonne, tu reliras ça et tu rigoleras tellement c'était simple, si on prend chaque problème un par un... ------------------------------ Avant de répondre, quelques petites retouches sur l'application : - bouton tglChangeVue : je l'ai remis en bas à gauche de l'en-tête, immédiatement au dessus du sous-formulaire. Pas obligatoire, bin sûr, mais pourquoi ce choix : - Le meilleur moyen pour que ce bouton ne bouge pas d'un formulaire à l'autre, c'est de le mettre à gauche - visuellement, il est en liaison directe avec le sous-formulaire qu'il contrôle. Il y aura d'autres boutons de ce type (un par sous-formulaire !), non seulement sur les affaires, mais sur d'autres formulaires aussi (Employés, etc.). Donc, choisir une disposition, puis ne plus bouger, sinon, utilisateurs perturbés. - titre "Affaires" sur le formulaire : moi qui était très fier de mon petit effet "pseudo-graphiste", en coupant les pattes du titre ! Effet pas cher et hyper tendance dans les années 60 - j'ai ajouté un titre, dans les propriétés du menu Outils > Démarrage : pratique sur la barre de tâches, pour distinguer parmi les 5 à 18 fenêtres Access ouvertes en même temps... - j'ai mis le formulaire principal en ouverture automatique, toujours dans Outils > Démarrage. J'aime bien que l'utilisateur démarre avec directement ses données à l'écran. Un petit Maximize serait bien ? (on verra ça après avoir digéré le Form_Resize !) ------------------ Le titre en mémo Citation:
- soit un commentaire, mais il y a déjà un champ commentaires ! - soit il contient beaucoup d'autres informations (nom du client, lieu, dates ou période, type d'affaire, je sais pas quoi encore, et tout ça devrait figurer proprement dans d'autres champs. Ne serait-ce que pour permettre les filtrages, les tris, les recherches, etc. Si tous ces champs séparés existent déjà, inutile de mettre l'info en double. Sinon, faut les créer maintenant. Par contre, si chaque affaire a un titre simple (de 30 à 50 caractères, c'est déjà beaucoup), il me paraît indispensable de pouvoir sélectionner chaque affaire par son titre. Y aura toujours quelqu'un pour se tromper de n° ! Mais, du moment que tu as pigé la technique, tu peux maintenant - mettre autant de listes que tu veux pour trouver une affaire parmi toutes les autres, - synchroniser ces listes entre elles. Sur ce sujet, tout est bon, tu sais faire. Donc, je ne me sens plus tellement concerné ici. Citation:
Je ne connais pas d'autre méthode. Je voulais juste que tu vois comme c'est simple de synchroniser les listes entre elles.Juste attention : que toutes les listes aient bien le même champ, en colonne liée (boundcolumn) ! qui peut être visible ou invisible ----------------------------------------- Redimensionnement du formulaire + sous-formulaire Citation:
Résultat : ils restent scotchés en mode formulaire, avec, ici ou là un petit form "en continu", sans jamais profiter de la souplesse du "feuille de données". Allons-y donc d'un exemple simple (ça va se compliquer plus tard ) avec, au moins 2 bugs (sinon plus ), à corriger/compléter pendant que je serai dans la piscine.Commentaires : Le formulaire principal (conteneur) a 3 propriétés qui nous concernent ici : + Width : largeur de la zone qui reçoit les contrôles. Limitée par le contrôle situé le plus à droite, + InsideWidth : la largeur intérieure, entre les bordures du formulaire, + InsideHeight : idem, verticalement. Noter que Me.InsideHeight est égal à la somme des 3 sections : acHeader + acDetail + acFooter, sans la barre de titre, ni l'ascenseur horizontal, en bas. Bien séparer le redimensionnement horizontal, de tout ce qui concerne la verticale, sinon foutoir immédiat, impossible à déboguer. De plus, du fait que c'est un exercice de formation, j'ai ajouté les variables NewWidth + NewHeight. Bien sûr, ici, on pourrait s'en passer. Mais elles seront indispensables, si on a de 5 à 15 contrôles à redimensionner (en horiz. et/ou en Vert.). Dans l'exemple, au lieu de mettre le sous-formulaire dans le coin de la section détail (position : 0/0), juste pour rire et pour qu'on voit si notre méthode marche bien, j'ai mis - Haut = 1 mm (.Top) - Gauche = 1 mm (.Left) Du coup, dans Form_Resize, j'essaye de mettre une marge uniforme tout autour : haut = bas et gauche = droite. On doit donc, si tout va bien, - voir une marge orange de 1 mm tout autour du sous-formulaire. Ni plus, ni moins. - jamais d'ascenseur vertical (à droite du conteneur). Sauf si le sous-formulaire a complètement disparu. Essaye de le réduire à son minimum, jusqu'à ce qu'il ne reste plus qu'un bout de la barre de titre : il va y avoir un message d'erreur, à corriger. - pas d'ascenseur horizontal (en bas du conteneur, en dessous des boutons de navigation et de l'ascenseur horizontal propre au sous-formulaire), tant que tous les contrôles posés sur le form. principal sont entièrement visibles. À partir du moment où l'étiquette "Affaires" commence à être masqué, un ascenseur horizontal doit apparaître, pour permettre d'afficher soit le bord gauche, soit cette étiquette en entier, à droite. La marge orange, à droite du sous-formulaire, doit augmenter alors, pour atteindre la limite droite de l'étiquette en question, et pas plus loin que ça : sinon, bug, à corriger. Ensuite, on verra comment arranger un poil les contrôles du (sous)formulaire Affaires, en mode fomulaire. Mais juste un poil. Si il te reste du temps, rien n'empêche de faire quelques essais. -------------------------------------------------- Filtrage des affaires : Citation:
- à trouver une affaire parmi celles du client, - lancer une recherche avec Ctrl+F, mais uniquement parmi les affaires sélectionnées, - pourquoi pas, plus tard, imprimer une statistique touchant toutes les affaires de ce client, - etc. Citation:
Mais on aura alors des choix, dont la décision se fera au cas par cas : - soit on signale à l'utilisateur qu'il faut enlever les filtres, et, dans ce cas, faudra prévoir un bouton pour faire ça d'un seul clic, - soit on enlèvera nous-même le filtre, par code, et on lancera directement une 2ème recherche... - il y a aussi des cas ou la liste déroulante des affaires est tellement longue que non seulement, il faut filtrer le formulaire, mais aussi les listes déroulantes. Ça permet une approche en plusieurs temps, comme dans l'exemple déjà cité des stagiaires (plusieurs milliers) qui travaillent dans divers établissements, avec, par établissement, des composantes, et dans chaque composante, des services. Le fait de choisir un établissement dans la 1ère liste : - filtre la liste des composantes pour n'afficher que celles de l'établissemnt, - filtre la liste des services idem (seulement ceux de l'établissement) - filtre la liste des stagiaires, - filtre le sous-formulaire Stagiaires (équivalent de nos Affaires ici). Idem, bien sûr, pour les autres listes : la liste des composantes permet de filter la liste des services + celle des stagiaires + le sous-formulaire stagiaires. Etc. Dans ce cas là, on trouve toujours, puisque la liste contient les mêmes stagiaires que le sous-formulaire. À chaque cas sa recette. Tu en inventeras d'autres, lorsque tu utiliseras cette méthode qui, en elle même, est simple. ------ À faire sur les filtres (c'est plus courant que le form_Resize, et surtout, ça ne manque pas de resources sur ce sujet, sur le forum DVP, donc, je n'ai rien fait) : 1- impératif : lire et faire tous exercices du cours de Caféine : Construire un formulaire de recherche multi-critères 2- une fois pigé le principe, - cmbFiltreClient : mettre une liste déroulante avec tous les clients. Colonne liée : le même idClients qu'on voit sur chaque affaire. - évènement cmbFiltreClient_AfterUpdate (pour l'instant) : En termes de pseudo-code : - Si cmbFiltreClient est null : pas de filtre, on affiche toutes les affaires. Noter que Cafeine utilise des cases à cocher pour déterminer si tel ou tel filtre est actif ou pas. J'ai l'habitude de simplement vider (-> valeur Null) la liste. Par contre, j'ai toujours un bouton qui enlève tous les filtres d'un coup. Chaque solution a ses avantages... - sinon, ---- variable SQLstring = ... voir cours de Caféine, pour un string bien formé, en fonction du type du champ (ici :IdClient) ---- filtre de ssfAffaires = SQLstring ---- Ne pas oublier le .filterOn = True/False Voir l'aide d'Access sur les propriétés Filter et FilterOn du formulaire. ** Il s'agit bien ici du sous-formulaire Affaires. Donc, vu depuis le conteneur, ce sera : ssfAffaires.Form.Filter... Plus tard, ou si tu as le temps : - 2ème liste déroulante, pour sélection par Responsable affaires - sortir tout le code de l'évènement cmbFiltreClient_AfterUpdate et le mettre dans une sub SetFilter(), appelée depuis les 2 contrôles - créer un SQLstring + complexe, combinant les 2 critères : voir cours de Caféine. S'il y a des questions, quelque chose qui ne marche pas, on verra à mon retour (vers le 15 août). ------------------------------------------ Citation:
Citation:
Moi itou : l'université d'été sera fermée la semaine prochaine (5-14 aout) pour cause de farniente. |
||||||||
|
|
00
|
|
|
#8 | ||||
|
Membre du Club
![]() Inscription : mai 2006 Messages : 79 ![]() |
Coucou me revoilà
Citation:
Citation:
Autre souci, si changement de résolution de l’écran, message d’erreur d’exécution ‘2100’ contrôle ou sous formulaire trop grand. Je penses qu’il y a deux méthodes : On piège l’erreur par ‘On Error Goto’ ou en surveille la variable ‘NewHeight’ ( ce que j’ai choisi de faire.). Est ce bon ?? Citation:
Lors du choix d’un des deux filtres, je remets les contrôles de recherche à la valeur ‘null’, et passer le formulaire ssfAffaires en mode feuille de données (mais je n’ai pas trouvé la constante qui va bien Pour relancer une recherche, il faut actionner le bouton qui enlève tous les filtres (si filtre existe). Je me suis lancé dans la construction du sous-sous-formulaire heures allouées des sections d’une affaire, baptisé ‘F10-100_b ssfHeuresAllouees-SectionsAffaires’ où j’ai rajouté un bouton feuille de données / formulaire pour montrer que j’ai compris le principe). Construction de deux autres sous-sous-formulaires heures prévues fournisseurs et employés baptisé ‘ F10-100_c ssfHeuresFournisseurs’ et ‘F10-100_d ssfEmployes-SectionAffaires’. Pour les noms de baptêmes j’ai peu être pas tous compris ?. Je suis arrivé à une représentation presque identique à mon formulaire ‘SaisieAffaires’, mais je suis sûr que c’est pas ce que tu voulais ?. Question (remarque) : Comment définir la grandeur d’un formulaire ?? Je sais que les écrans sont de moins en moins chère, mais nous n’avons pas tous des 19‘’ voir des 21’’. Le 800x600 est monnaie courante en entreprise (écrans 15’’ ou 17’’). Voilà ma crainte pour un formulaire tout en un. Chose que l’on voit de plus en plus sur les applications informatiques (il y a en a partout). Maintenant, le conteneur contient un formulaire qui lui même contient un formulaire. D’après ton intervention #1, il manquerait un sous sol. Et le(s) bouton(s) pour ouvrir les états qui vont bien. Citation:
![]() ------- Fichier attaché : SuiviAffaire 2006-08-03.zip (85,9 ko) ------- |
||||
|
|
00
|
|
|
#9 | |||||
|
Membre Expert
![]() ![]() Etienne PailleretDéveloppeur VBA Inscription : mars 2004 Messages : 748 ![]() |
Salut ! Retour de Sauvignon (Reuilly, Valencay...) tout bon.
Bon, c'est bien, ça avance, mais va falloir nettoyer avant d'aller plus loin. Il y a encore des bugs non résolus, et de nouveaux qui apparaissent. Alors, à chaque étape, à chaque subroutine : tests intensifs et corrections. Je repars de ce qu'il y avait à faire, suite à la réponse #7. Ma 'check list' (V+) indiquait : Form_Resize : - message d'erreur pendant réduction, - marge orange, à droite, à supprimer. Listes de recherche : - 2ème liste déroulante, pour sélection par Responsable affaires, - sortir tout le code de l'évènement cmbFiltreClient_AfterUpdate et le mettre dans une sub SetFilter(), appelée depuis les 2 contrôles - créer un SQLstring + complexe, combinant les 2 critères, selon cours de Caféine. Éventuellement, - ajouter un Maximize ? ------------ Je reprends ces points par ordre de composants, en partant du formulaire principal (le conteneur). Formulaire principal - Maximize Citation:
Notre formulaire n'a aucune donnée, donc, tu as de la chance, cet évènement s'exécute quand même, juste une fois, au démarrage ! Mais ce n'est pas le bon évènement. Pour trouver le bon : - choix dans l'onglet Évènement des propriétés du formulaire, - dans l'aide d'Access, taper "évènement" dans l'index et consulter la rubrique Rechercher le moment où les événements se produisent. Cette rubrique pointe sur celle qui nous intéresse, à savoir Visualiser l'ordre des événements relatifs aux formulaires et sous-formulaires. Mais chacune des autres rubriques dans la même catégorie est à apprendre par coeur : le choix du bon évènement peut devenir primordial et éviter beaucoup de temps perdu ! Formulaire principal - Form_Resize : Des 2 bugs signalés, aucun n'est corrigé. ![]() Citation:
Citation:
Pour la méthode, OUI : mieux vaut contrôler la valeur de NewHeight que d'utiliser un On Error Goto. (je reparle du contrôle d'erreur, plus bas) Par contre, pour l'instant, le 1er bug, au moins, est indépendant de la résolution. À titre d'exercice, ce serait bien d'essayer de corriger ces bugs sur ta dernière version de la base, avant d'ouvrir le corrigé ci-dessous et de comparer ta solution et la mienne. Je n'ai peut être pas été assez clair, donc, pour reproduire le bug, avec ta dernière version du .mdb : 1- démarrer l'application 'Affaires' 2- agrandir Access en plein écran, 3- réduire le formulaire Affaires, pour pouvoir le redimensionner à la souris, 4- saisir le bord inférieur, et remonter jusqu'à ce que la section détail, qui contient le sous-formulaire ssfAffaires, disparaisse. Dès qu'il disparaît complètement, on a une erreur 2100 'Contrôle ou sous-formulaire trop grand.' Faut pas trop se fier aux messages d'erreur. Dès qu'ils ont un problème de dimension, les programmeurs d'Access te renvoient une erreur 2100, mais ça peut aussi bien vouloir dire "Contrôle ou sous-formulaire trop petit", voire "Hauteur du contrôle ou du sous-formulaire carrément négative" !!! Faut extrapoler. --------- Le 2ème bug, la marge orange qui apparaît à droite du sous-formulaire, vient du fait que - à chaque fois qu'on agrandit la fenêtre, ça agrandit la propriété Me.InsideWidth, - notre code, dans Form_Resize, agrandit la largeur du sous-formulaire pour le remplir (avec marge de 1 mm tout autour). - donc, la largeur du formulaire (propriété Me.Width, sans le 'Inside') augmente pour être aussi large que le contrôle le plus à droite. Çà, c'est Access qui le fait tout seul, ce qu'on peut constater en augmentant la largeur et en mettant un Stop (ou point d'arrêt avec F9) dans le code, et en vérifiant la valeur de Me.Width ? - quand ensuite tu réduis la fenêtre, tu réduis Me.InsideWidth -> réduction de la largeur de ssfAffaires. Mais rien ne vient réduire la largeur (Me.Width) du formulaire lui même ! Elle garde sa plus grande valeur. D'où l'astuce toute bête qui consiste à la réduire un max, à chaque Form_Resize : Access la recollera sur la largeur du contrôle le plus à droite. Enfin, attention, dans ton code, - tu as ajouté une condition pour NewHeight (redimensionnement vertical), et - tu as inclus le redimensionnement horizontal à l'intérieur de cette condition ! Ils sont et doivent rester indépendants l'un de l'autre, en tout cas dans ce cas. En tête du formulaire - Filtres : Ta méthode marche bien, bravo. Corrections quand même : 1- le bouton tglAnnulerFiltre n'est pas un bouton bascule (toggle), mais un simple bouton de commande : faut le renommer cmdAnnulerFiltre, ou bien utiliser un vrai bouton bascule. 2- la procédure SetFilter() : - commence par un commentaire pour mettre les affaires en mode "feuille de données" : à titre d'ergonomie, je conseille de laisser l'utilisateur contrôler lui-même son interface le + possible. Sinon, ça devient vite troublant ! Mais, au cas où tu voudrais quand même le faire, Pour forcer le sous-formulaire à passer en affichage 'feuille de données' : Code :
Pourquoi ? Peut-il y avoir des affaires avec IdAffaires = 0 ? Si c'est 'non', cette ligne ne sert à rien qu'à ralentir le filtrage. Si c'était possible et qu'on ne veuille jamais traiter les affaires sans IdAffaires, faut mettre ce filtre sur la requête du formulaire, ou bien... Peut être as tu pensé à une autre raison, qui est restée confuse ? Bref, faut réfléchir et analyser maintenant (plus tard = trop tard). - ensuite, tes tests : If Not Me.CmbFiltreClients Then Sacré coup de bol : ça marche !Parce que CmbFiltreClients est indépendant, donc n'est pas lié à un type de données texte ou autre, donc si est null, renvoit 'faux'... Mais la bonne méthode serait quand même If Not IsNull(CmbFiltreClients) Then Ou alors, la méthode de Cafeine, avec une case à cocher qu'on peut tester comme ça. Bref, j'ai gardé la plupart de tes lignes de code, précédées de 2 ' (simples guillemets), dans le corrigé. J'ai ajouté une autre méthode aussi, pour l'exercice : - la tienne, en vidant les filtres avec un bouton de commande, est simple ![]() - la mienne permet de basculer entre le formulaire filtré et non filtré, avec un rectangle de couleur pour bien 'voir' si le filtre est ON ou OFF. - il y en a d'autres (à chacun son imagination... En tête du formulaire - Listes (Combos) de recherche : La 2ème liste par responsables d'affaires est OK. Il reste quelques bugs à corriger tout de suite : - liste par titre : revoir les largeurs de colonne - la liste par n° n'affiche pas le classement : à ajouter (cohérence entre les listes déroulantes) - la liste par classement efface le contenu des 3 listes : à corriger Ces corrections sont simples. Je ne les ai pas faites dans le .mdb ci-joint. En tête du formulaire - tglChangeVue : nouveau bug. Pour reproduire le double bug, toujours avec ta dernière base : - passer les affaires en mode formulaire, bug 1 : - cliquer dans un sous-sous-formulaire d'heures passées : Fournisseurs ou Employés, - cliquer sur tglChangeVue -> message "La commande ou l'action "FeuillesDonnéesSousFormulaire" n'est pas disponible pour l'instant." bug 2 : - cliquer dans le sous-sous-formulaire d'heures allouées, - cliquer sur tglChangeVue -> ce sont les heures allouées qui changent de vue, et non les affaires ! observation : - cliquer dans un des contrôles propres à l'affaire active : tout se passe bien, c'est bien le sous-formulaire ssfAffaires qui bascule d'un affichage à l'autre. Il faut comprendre que la commande exécutée par le bouton tglChangeVue s'exerce sur le sous-formulaire qui est actif ! quel qu'il soit, même s'il est au 2ème ou au 3ème sous-niveau. Donc, faudra éviter de laisser le focus dans un sous-formulaire, si c'est le cas. Je propose une solution dans le 'corrigé' ci-dessous, mais ce serait bien que tu la trouves tout seul, ou quelque chose qui approche... Enfin, avant de conclure, j'ai quelque peu "nettoyé" notre module de code, avant qu'il ne soit trop plein de choses hétéroclites. Module de code - Tri des routines Il est impératif de télécharger mzTools (voir page outils du forum Access). Après avoir installé cet outil qui a de nombreuses possibilités, la 1ère, pour aujourd'hui, consiste à utiliser, dans la barre d'outils MzTools qui s'affiche au dessus des modules de code, la commande Autres utilitaires > Trier les procédures. Il y a essentiellement 2 choix :- choix 1: trier par ordre alphabétique des routines (clic sur l'en-tête de la colonne Nom, puis sur OK) - choix 2 : ordre logique, comme par hasard, mon choix. En gros, je trierai du haut vers le bas du module : : évènements du formulaire ... démarrage + fermeture, ... autres évènements concernant le formularie (form_Resize, Form_Error...) : évènements concernant les enregistrements (Form_Current, BeforeUpdate, AfterUpdate, before/After Insert+Delete...) : ensuite, évènements qui concernent les contrôles - si on utilise des onglets, tri des contrôles par onglet - sinon, et à l'intérieur de chaque onglet, tri par ordre de tabulation De même, pour chaque contrôle : tri par ordre (chrono-)logique des évènements (Form_BeforeUpdate -> Form_AfterUpdate...) Enfin, toute sub ou fonction telle que SetFilter(), qui n'est donc pas un évènement, est toujours située plus bas dans le module que les procédures qui l'appellent. De préférence, juste en dessous du dernier appel. Tout ça me permet de "lire un module de code" très vite, en suivant + ou - l'ordre logique d'exécution de ces divers bouts de code. Si c'est trop compliqué, prendre un tri alphabétique simple te permettra de retrouver tes routines rapidement. Module de code - Code d'erreur : On a la chance de pouvoir partir proprement, sur des formulaires vierges. Donc, je supprime tout code d'erreur (tels que ceux qui étaient générés par les divers assistants de boutons...), pour l'instant. Si on tombe sur un message d'erreur intempestif, la bonne approche consiste à empêcher l'erreur de se produire, comme tu as fait dans Form_Resize (contrôle de NewHeight et non pas On Error Goto...) Pour une raison évidente : - dès qu'on a un (On Error) Goto, il faut aller voir plus bas ce qu'il s'y passe, pour comprendre le problème et la solution. - si on n'a aucun Goto, on peut tout comprendre sur place, dans le code -> moins d'erreurs plus tard. Si on ne met aucun code de gestion d'erreur (pour l'instant ), en cas d'erreur non prévue -> Access nous propose de déboguer, ce qui nous amène directement sur la ligne qui a provoqué l'erreur. C'est l'idéal pour tester les valeurs de chaque paramètre, trouver une parade, etc. On verra ensuite, quand on y sera obligés, comment contrôler les erreurs spécifiques, et surtout, comment traiter les erreurs non prévues, qui surviendront pendant les tests beta, sur le poste d'un utilisateur. --------------------- Ça suffit pour aujourd'hui, non ? ![]() Dès que tous ces petits bugs seront nettoyés nickel, et que les notions de base évoquées jusqu'ici seront bien claires, on passera aux nombreuses questions restantes concernant - l'interaction entre listes de recherche et listes de filtre, - le choix de dispositions des sous-formulaires, - les résolutions d'écran, etc. --------------------- Donc, ci-dessous, corrigé (sauf les combos de recherche) à ne télécharger qu'après avoir résolu chaque bug ! En tout cas, la grande leçon du jour, c'est Nettoyer chaque bug au fur et à mesure. Ne pas commencer une autre fonction, ou subroutine, ou quoi que ce soit, sans avoir testé soigneusement la précédente ! Sinon, ça devient vite incontrôlable. |
|||||
|
|
00
|
|
|
#10 | |||||||
|
Membre du Club
![]() Inscription : mai 2006 Messages : 79 ![]() |
Citation:
------------ Citation:
Citation:
------------- Citation:
------------- Citation:
Code :
SQLString = SQLString & "and [IdClients]=" & Me.CmbFiltreClients Citation:
------------- Citation:
![]() ------- Fichier attaché : SuiviAffaire 2006-08-17.zip (89,0 ko) ------- |
|||||||
|
|
00
|
|
|
#11 | ||||
|
Membre Expert
![]() ![]() Etienne PailleretDéveloppeur VBA Inscription : mars 2004 Messages : 748 ![]() |
Là, on va mettre un Stop, ou appuyer sur F9.
Je sens qu'il faut faire le point, en ce qui concerne le débogage. Pour l'instant, ça coince. je signale des bugs, tu en trouves d'autres, mais pas les solutions. Quand tu tombes sur ton message d'erreur 2448 parce que tu as un " and " en trop dans ton StringSQL, tu ajoutes une clause bidon. Ça marche, mais ça ne coûte pas plus cher de remplacer cela par une vraie condition qui corrige exactement le problème. La solution "quick and dirty" : Code :
Code :
Le 2ème Debug.Print affichera le contenu de SQLtring : exactement ce qu'on s'attend à y trouver. Surtout, le "bien fait" sera tellement plus facile à reprendre à tout moment. Et à faire évoluer, ce qui est inévitable, surtout avec une appli que tu fais pour toi même : tu vas toujours y ajouter des morceaux. Donc, reprenons nos bugs dans l'état où ils sont, et faisons une petite pause pour déblayer les bases du débogage ([Cours pt04]). Nous reviendrons ici compléter l'interface du formulaire, dès que ces bases seront digérées, ou au moins, digestes. |
||||
|
|
00
|
|
|
#12 | |
|
Membre Expert
![]() ![]() Etienne PailleretDéveloppeur VBA Inscription : mars 2004 Messages : 748 ![]() |
Je pense que toutes les questions de ta réponse #10 sont résolues, donc je reprends un point mentionné en #8 :
Citation:
Avant qu'on commence à mettre un paquet de sous-formulaires ici, il faut savoir la taille d'écran minimale : Quelle est la taille minimale d'écran, pour les utilisateurs de ton logiciel ? (tu dois les connaître tous) - Si il y a des écrans de 800x600, nous sommes obligés de tout tester en 800x600, et quelles que soient les gymastiques de Form_Resize, on sera très limités en affichage 'mode formulaire'. - si tout le monde a au moins une définition de 1024x768, on sera déjà beaucoup plus à l'aise en 'mode formulaire'. Parce que tu veux beaucoup d'information à la fois à l'écran, ce qui est la norme : on essaye d'en mettre le plus possible. Cette décision est à prendre au départ, parce qu'elle détermine les outils et toute l'ergonomie du formulaire : - bien sûr, on va compresser l'en-tête (voire, dans les cas extrêmes, le masquer et le réafficher avec un bouton ?). - serons nous obligés d'utiliser un contrôle Onglets ? Et, en fonction de la résolution, on verra ce qu'on peut y mettre... |
|
|
|
00
|
|
|
#13 | ||
|
Membre du Club
![]() Inscription : mai 2006 Messages : 79 ![]() |
Citation:
Citation:
|
||
|
|
00
|
|
|
#14 |
|
Membre Expert
![]() ![]() Etienne PailleretDéveloppeur VBA Inscription : mars 2004 Messages : 748 ![]() |
OK pour 1024. Je pense qu'avec la quantité d'info voulue, on aurait eu du mal en 800x600, même si c'est encore possible. Mais, inutile de se compliquer la vie.
Le cadeau bonux : pour finir avec le sujet des résolutions d'écran, un petit outil maison tout simple me permet de tester rapidement chaque définition. Voir image jointe ci-dessous, ou, pour ceux qui ont des lunettes de soleil, télécharger la version acidulée. Il suffit de - mettre un des gabarits d'écran ci-joint en fond d'écran, position centrée, puis, pendant le développement, - agrandir le formulaire à tester en 'maximize', - réduire la fenêtre d'Access, - la déplacer en haut à gauche du gabarit, - la redimensionner à la taille d'écran voulue, sans recouvrir l'image de la barre de tâches correspondante. C'est beaucoup plus rapide que de changer la résolution de l'écran, puis de revenir à l' "écran total" pour travailler sur le code... ------------------------------------ Notre formulaire : Le 1er exercice va consister à - compresser l'en-tête (supprimer quelques titres ?, garder le minimum, tasser sans nuire au fonctionnement), Dans la section détails, - ajouter un contrôle onglet, - garder au moins le titre de l'affaire au dessus de l'onglet, pour qu'on sache toujours quelle affaire est à l'écran, quel que soit l'onglet ouvert, (à toi de dire le minimum indispensable pour identifier chaque affaire. Tout le reste (le maximum) doit aller dans le 1er onglet). - mettre sur la 1ère page du contrôle, l'ensemble des champs définissant l'affaire, - inclure ce nouveau contrôle dans notre Form_Resize (ne devrait pas poser trop de problèmes Ensuite, on pourra ajouter tout ce qu'on veut dans les onglets. Ceci dit, avant de rajouter les sous-formulaires, avec les complications que ça va poser au niveau de Form_Resize et autres, il est indispensable de décider du contenu de chaque onglet. Sinon, on va - passer des heures à disposer et relier entre eux ces sous-formulaires, - recommencer x fois, parce qu'il y a x dispositions possibles -> perdre de nombreuses heures ! Donc, avant toute chose, on va juste faire une série de maquettes avec les sous-formulaires seulement posés dessus, en 1024x768, pour voir l'image (réduite, avant upload sur le forum Ce qu'il faudra mettre dans les onglets : - les détails de l'affaire, - je te propose d'inclure un résumé des sections, incluant le nom de chaque section concernée + tous les totaux d'heures (allouées/passées...) - les heures allouées, - les heures prévues (fournisseurs) - les heures prévues (employés) - les heures passées (fournisseurs) - les heures passées (employés). D'accord pour des maquettes, plein de maquettes, avec l'avis du client sur celle qui sera la plus pratique ? En voyant les maquettes, on réfléchira au fonctionnement... (trop de possibilités pour en parler avant |
|
|
00
|
|
|
#15 | ||
|
Membre du Club
![]() Inscription : mai 2006 Messages : 79 ![]() |
Beaucoup de retard, mais j’étais en déplacement pour le « Boulot ».
Deux grosses Questions sur ton dernier message: Citation:
En gros,le contrôle onglet se trouve où ?? Dans quel « FORMULAIRE » ou « SOUS FORMULAIRE » ?? Citation:
Mon approche du « contrôle onglet » par rapport à l’application « SuiviAffaire » et de mettre les 3 sous formulaires (F10-100_b ssfHeuresAllouees-SectionsAffaires, F10-100_c ssfFournisseurs-SectionsAffaires, F10-100_d ssfEmployes-SectionAffaires) dans 3 onglets différents. Et en ce qui concerne la saisie des heures passées je la verrai bien dans un autre formulaire.(l’organisation des pointages des employés il est plus facile à saisir : un tel a travaillé sur l’affaire 1 puis sur la 5 puis sur la 7 puis sur la 2…..) ------ Question que j’aurai du poser au début du cours : Comment envisages-tu le lien entre plusieurs « turbo-formulaire » ?? Un menu ? Un bouton dans chaque « Turbo-Formulaire » ? ------ Pour la suite du cours, il y aura un certain retard dans ma réponse. Je m’absente pour 2 semaines (Repos bien mérité pour l’élève). J’espère qu’a mon retour le professeur sera toujours aussi patient. Merci Papy Turbo. |
||
|
|
00
|
|
|
#16 | |||||
|
Membre Expert
![]() ![]() Etienne PailleretDéveloppeur VBA Inscription : mars 2004 Messages : 748 ![]() |
Citation:
On a pour l'instant, avec les niveaux de conteneurs/contenus : niveau1 - 1 formulaire principal [10-100 Affaires], qui n'est lié à aucune donnée. niveau 2 - 1 sous-formulaire "principal" ssfAffaires (source = [10-100_a ssfAffaires]). Sur le sous-formulaire, on trouve : - des données par liaison avec la requête F10-100_a ssfAffaires, qui renvoit la table Affaires, niveau 3 - divers sous-formulaires, chacun avec ses données. ------------ On va avoir juste un conteneur supplémentaire, le fameux contrôle onglet, sur le sous-formulaire 'principal' : niveau1 - 1 formulaire principal [10-100 Affaires], qui n'est lié à aucune donnée. niveau2 - 1 sous-formulaire "principal" ssfAffaires (source = [10-100_a ssfAffaires]). Sur le sous-formulaire, on trouve : - en-tête, le titre de l'affaire, au-dessus de l'onglet, lié à un champ de la requête F10-100_a ssfAffaires, niveau3 - un contrôle onglet, contenant plusieurs pages : --- une première page contenant toutes autres données de la table Affaires (requête F10-100_a ssfAffaires), niveau4 --- autant de pages que nécessaire pour contenir les autres sous-formulaires. Citation:
- faire un premier formulaire avec le contrôle onglet, sur lequel on trouvera tout ce qui concerne les affaires elles-mêmes (tous les champs mentionnés ci-dessus, page 1 de l'onglet). - ensuite, faire des copies de ce formulaire et, sur chaque copie, essayer diverses combinaisons de sous-formulaires, juste pour voir ce qui serait le plus pratique, en tant que responsable du bureau d'études, pour avoir toutes les infos requises sous la main. Citation:
Peut être un autre avec, - dans un onglet "Fournisseurs", les 2 sous-formulaires concernés, côte à côte : heures allouées fournisseurs et heures passées fournisseurs. Même si les heures passées sont en lecture seule, la question est : serait-il utile de pouvoir les comparer aux heures allouées ? - idem, dans un onglet "Employés" : heures allouées + passées ? etc. À toi de créer autant de scénarios que possible, sans faire aucune programmation (peu importe si les sous-formulaires ne changent pas de taille au Form_Resize, on verra après...), sur un formulaire en 1024 x 746, standard. Il faut que tu définisses précisément ce que tu attends de cet ensemble qui constitue le formulaire "Affaires". Citation:
C'est toi qui peut dire comment chacun (employé/fournisseur) ? ou seulement les responsables ? noteront le résumé des heures passées ? ... Citation:
- si tu ajoutes 5 ou 10 formulaires à cette application, il va falloir que tu ajoutes presque autant de boutons sur chaque formulaire, pour pouvoir accéder à tous les autres... - avec un menu, tu ajoutes juste une commande pour chaque nouveau formulaire, et elle est disponible partout C'est tellement facile de faire et modifier des menus, depuis access 2000, qu'il n'y a aucune raison de s'en priver. En général, je préconise - de ne faire qu'un seul menu pour tous les formulaires : les utilisateurs seront très vites perdus si le menu change ! - de partir d'une copie des menus standards d'Access, en laissant le plus grand nombre possible de commandes Access disponibles pour les utilisateurs. Elles finissent généralement par rendre de grands services (ne serait-ce que 'Rechercher', etc.) - d'ajouter un seul menu sur la barre principale, dans lequel sont affichés tous les formulaires. Pas de guide particulier : ce ou ces menus seront très différents d'une application à l'autre... - il suffit ensuite d'indiquer le nom de ce menu dans la propriété 'Barre de Menus' de chaque formulaire. Idem pour une barre d'outils qui reprend les outils usuels d'Access (dont le magique bouton de 'Filtre par sélection'...). J'espère que tout le monde sait faire des menus et les modifier : c'est la même méthode que dans Word ou Excel : clic droit dans une zone vide d'un menu ou barre d'outils, personnaliser... Et pourvu que tu nous reviennes en pleine forme, parce qu'on a encore du pain sur la planche.
|
|||||
|
|
00
|
|
|
#17 | |
|
Membre du Club
![]() Inscription : mai 2006 Messages : 79 ![]() |
Fin des congés, reprise du cours !!!
J’ai fait des copies des différents formulaires de la base en y ajoutant dans le nom « _ONGLET » .(Exemple 10-100 Affaires_ONGLET… ) pour ne pas abîmer ce qui tourne !! Dans le formulaire 10-100_a ssfaffaires_ONGLET, j’ai ajouté un champ onglet avec 3 pages. J’ai eu un petit bug avec le bouton de commande tglChangeVue (voir petite modif.) Dans le contrôle onglet, j’ ai inséré plusieurs sous-formulaires. (voir base jointe) ---------------- Pour le lien entre les différents turbo-formulaires Citation:
Question suivante : les menus personnalisés ne sont pas attachés à la base, donc si je déplace la base sur un autre PC, il faut que je transfère aussi les menus ??. ------- Fichiers attachés : SuiviAffaire 2006-09-27 (103,4 ko) ------- |
|
|
|
00
|
|
|
#18 |
|
Membre Expert
![]() ![]() Etienne PailleretDéveloppeur VBA Inscription : mars 2004 Messages : 748 ![]() |
Bon, je constate que tu es maintenant parfaitement à l'aise avec le contrôle onglets
- compléter la 2ème maquette avec les heures prévues/passées par Employé et par Fournisseur, - faire d'autres maquettes, pour tester toutes les configurations possibles et choisir la meilleure. Pour cela, ne pas hésiter à faire de simples croquis, même grossiers, mal dessinés, pourvu qu'ils permettent de mettre en évidence une autre disposition. Je joins 2 sketches, pour illustrer rapidement une autre solution avec : - mêmes formulaire principal et sous-formulaire Affaires, - un onglet Sections qui contient lui-même +++ un bouton pour basculer la vue (formulaire / feuille de données) + en option, une liste déroulante des sections, pour atteindre directement une section (peut être utile en mode formlaire ?), +++ un sous-formulaire + en affichage feuille de données, la vue d'ensemble : le résumé des sections et totaux d'heures, (semblable à ton sous-formulaire 'Somme-Différence Heures', avec tous les totaux) + en affichage formulaire, les détails par section : -- un entête avec le nom de la section et total Heures allouées... -- un onglet Employés, avec les heures prévues/passées, -- un onglet Fournisseurs semblable à l'onglet Employés (non dessiné). À mettre au point. -------------------------- Sinon, corrections et mises au point diverses (voir zip ci-joint), par rapport à ton dernier fichier zippé : En tête, filtres et listes d'affaires : - changé les noms des étiquettes : CmbFiltreClients_Etiquette remplacé par -> lblCmbFiltreClients. On met toujours le type de contrôle en préfixe, ce qui permet de les retrouver dans la liste alphabétique des contrôles. - Quelques mises au point sur la disposition des filtres : j'ai l'intention de reprendre cette disposition dans mes prochaines applications, avec le rectangle de couleur derrière les filtres eux-même, de manière à mettre en évidence le fait qu'un filtre est appliqué ou pas. C'est un point d'ergonomie très important, parce que les utilisateurs - oublient souvent qu'ils ont mis un filtre, - ne comprennent pas pourquoi ils ne voient pas les données qu'ils cherchent ! Tu vois, moi aussi, j'en profite pour mettre au point et améliorer mes formulaires : chaque réalisation va un peu plus loin que les précédentes. Reste à finaliser le choix de couleurs, pour la lisibilité des listes déroulantes (et l'esthétique!). sousformulaire Affaires : - j'ai agrandi le tout pour utiliser 1024 x 768 : ça permet de mettre les n°s et titre d'affaire sur une seule ligne, pour avoir le + de place possible dans l'onglet (exemple à ne pas forcément suivre, mais il faut utiliser tout l'espace, au cas où on en aurait besoin) - changé les noms des sous-formulaires (préfixe 'ssf'), pour 1- simplifier les références à ces sous-formulaires, en respectant une convention de nommage,('ssfHeuresAllouees' est plus simple, dans le code, que '10-110_b ssfHeuresAllouees-SectionsAffaires') 2- que le test, dans le code de l'évènement tglChangeVue_Click(), puisse fonctionner. Reste à décider si tu veux - soit, systématiquement mettre le focus sur le 1er contrôle (txtTitreAffaire), - soit, ne le faire que si c'est nécessaire (mon parti, parce que je n'aime pas faire bouger le focus sans raison, mais ce n'est pas forcément plus simple pour les utilisateurs ? À toi de choisir.) - renommé l'onglet 'Affaires' en 'Affaire' : n'y en a qu'une par onglet. - inversé les onglets 'Somme-Différence Heures' et 'Heures allouées' : pour que le résumé ('Somme-Différence Heures') soit en tête. C'est un choix : je propose toujours les totaux ou les résumés en tête, le détail après. sous-formulaire 'Somme-Différence Heures' - supprimé le champ 'NumeroAffaire' : inutile. Le 'NumeroAffaire' est affiché au-dessus de l'onglet. C'est le même pour toutes les sections. - déplacé l'IdAffaires, dont on a besoin comme 'champ fils' pour la liaison avec le formulaire parent (ssfAffaires), mais qu'on ne veut pas voir : tu avais masqué la colonne correspondant à ce champ. Astuce : Il vaut mieux, en le mettant dans l'en-tête, faire complètement disparaître la colonne. - déplacé toutes étiquettes dans la section détail, jointes à chaque champ : ça permet de modifier le libellé des colonnes, ce qui est + clair pour les utilisateurs. Astuce : pour joindre une étiquette avec sa textbox, il faut + supprimer l'étiquette avec Ctrl+X + sélectionner la textbox, + coller l'étiquette. L'avantage ergonomique d'une étiquette jointe à la text box (et non posée à côté) est que l'utilisateur peut cliquer sur l'étiquette pour sélectionner tout le contenu de la textbox. Souvent très pratique pour remplacer le tout... Fenêtre base de données : - renommé les (sous)formulaires 'XXX _- ONGLET' en '10-110 ...'. On a tout plein de numéros à notre disposition pour regrouper clairement chaque solution : évite de les mélanger entre elles, sinon ![]() - supprimé tous les 'F' en tête des noms de sous-formulaires : faut qu'il suivent leur conteneur, dans l'ordre alphanumérique. Sinon, la numérotation n'est pas utile. Code VBA : - La compilation (menu Débogage > Compiler db1.mdb) ne marchait pas, à cause de la routine Private Sub tglChangeVuessfHeuresAllouees_SectionsAffaires_Click(), que j'ai mise en commentaire. Une astuce, pour toujours vérifier que le code compile bien avant de l'enregistrer consiste à faire glisser la commande du menu VBA : Débogage > Compiler NomDuProjetsur la barre d'outils, à côté de la disquette (qui enregistre les modifs). Comme ça, avant toute sauvegarde du code, tu peux juste cliquer dessus pour vérifier tout de suite qu'il n'y a aucune erreur de syntaxe et autre problème de compilation. |
|
|
00
|
|
|
#19 | |
|
Membre du Club
![]() Inscription : mai 2006 Messages : 79 ![]() |
Hou lala ! Hou lala !
J’ai passé beaucoup de temps pour un résultat pas convaincant du tout. Le professeur va m’engueuler … Bon explication : Pour la 2ème maquette du turbo formulaire, (formulaire de base 10-110 Affaires), je crois que je suis arrivé à un résultat satisfaisant. Remarques sur les requêtes intermédiaires (requêtes masquées) ?? Pour la 3ème maquette (formulaire de base 10-120 Affaires), beaucoup de problèmes. J’ai toujours un mauvais résultat sur la requête F10-120_b ssfHeuresAllouees-Passees_SectionsAffaires. J’y travaille encore. Mais pour faire avancer le cours j’ai tout posté. (Fichier zip joint).Remarques sur le principe des turbo-formulaires. Dans les turbo-formulaires, tu mets beaucoup de résultats, de synthèses, de comparaisons ... Je pensais que le formulaire est surtout utilisé pour la saisie de données et que l'état est pour les « résultats »(et bien sûr l'impression). Donc il faudra une nouvelle mise en forme pour les états (d’autres requêtes…). Citation:
------- Fichiers attachés : SuiviAffaire 2006-10-08.zip (148,0 ko) ------- |
|
|
|
00
|
|
|
#20 | |||
|
Membre Expert
![]() ![]() Etienne PailleretDéveloppeur VBA Inscription : mars 2004 Messages : 748 ![]() |
Bon, d'abord, heureusement, le prof ne gueule pas, sauf pour réclamer un coup de rouge, mais c'est pas l'heure, et vaut mieux pas mélanger la culture (de la vigne) et le travail.
Mais si je n'avais rien à corriger, ni rien de nouveau pour toi, à te proposer, tout ça ne servirait pas à grand chose. Sur le fond, Citation:
Faut apprendre certaines techniques, bien sûr, mais, dès que tu les maîtrises, tout ça va vite : à peu près 2 heures pour mettre au point la 3ème maquette ci-dessous. Si ça représente 2 heures de temps gagné par mois, en utilisation, ou mieux encore, ça vaut l'investissement, non ? Citation:
Pour la différence entre une application "maison", "bidouillée pour toi-même" et une application "pro", ne t'inquiète pas, il y a encore beaucoup de choses dont tu n'as pas besoin (contrôle d'erreur systématique, avec journal d'erreurs par mail, pour débogage à distance en phase beta, par exemple), et aussi beaucoup d'améliorations que tu pourras apporter par petites doses, quand tu en auras le temps : ça pourrait inclure les totaux d'heures (pas indispensable pour que "ça marche", je suis d'accord) et beaucoup d'autres considérations ergonomiques ou fonctionnelles... Autre exemple : tu n'as pas besoin, au départ, d'aucun bouton bascule entre les affichages feuille de données / formulaire : il y a toujours le menu Affichage > Feuille de données sous-formulaire, qui fait ça. Ces boutons sont un "petit luxe" assez pratique, donc, toujours présents dans une application "pro" / seulement quand tu as le temps pour une application "perso". -------------------------- Sur nos maquettes, j'ai avancé la 3ème pour que tu voies au moins une autre approche. Il y a donc pas mal de remarques/explications, et quelques corrections, notamment sur les requêtes. La grande question sur laquelle je n'ai pas saisi ta réponse, c'est : faut-il que tu puisses saisir toutes les données sur ce formulaire ? En attendant, j'ai répondu Oui, ce qui ne t'empêchera pas de bloquer les sous-formulaires que tu veux en lecture seule (propriétés du formulaire Modif autorisée, etc.) Les remarques : Renumérotation des sous-formulaires, et des requêtes qui les alimentent, pour qu'ils reflètent bien la structure. Quel que soit le système d'indexation (tu peux ne mettre que 2 ou 3 chiffres, ou des lettres...) l'important, pour t'y retrouver clairement, c'est que chaque sous-formulaire soit juste en dessous de son conteneur, dans la fenêtre base de données. - pour chaque affaire -> des sections - pour chaque section (de l'affaire) -> des heures allouées, prévues et passées, ... Sous-formulaire "Sections" (renommé "ssfSections"), dans l'onglet du même nom, doit permettre - une vue d'ensemble de toutes les sections de chaque affaire, (mode feuille de données) - pouvoir ajouter des sections -> on ne peut pas mettre de champs calculés dans la requête. 1- Merise : Il y a des doublons (plusieurs fois la même section, pour une même affaire). Par exemple, dans ta base précédente, l'affaire n°3 avait 2 fois la section "pépinières". Il manque un index unique sur la table "SectionsAffaires", que j'ai ajouté, après avoir supprimé les doublons : index "CleMetier" (= "clé métier", sans les accents), clé unique sur l'IdAffaires + IdSections, pour qu'il n'y ait qu'une seule fois chaque section par affaire. Si ce n'est pas clair, j'attends toutes questions. Les "clés métier" sont, au même titre que la clé primaire, un élément essentiel de l'analyse des données. Ça conditionne tout le fonctionnement de l'application. De même, il va falloir vérifier les "clés métier" sur chaque table. Par exemple, sur les heures prévues par employé, il ne faut pas qu'on puisse saisir des heures pour un employé, sans indiquer la section de l'affaire concernée... 2- saisie des sections : en supprimant de la requête les champs calculés (total d'heures allouées/passées), on peut - afficher les sections en mode feuille de données et/ou formulaire (ajout d'un bouton bascule "tglChangeVue") - ajouter ou supprimer des sections, à l'intérieur de chaque affaire. 3- affichage calculs : (OK, c'est un luxe Code :
Total Heures Allouées = VraiFaux(EstNull([IdSectionsAffaires]);Null;SomDom("NbHeuresAllouees";"HeuresAllouees-SectionsAffaires";"[IdSectionsAffaires] = " & [IdSectionsAffaires])) Code :
VraiFaux(EstNull([IdSectionsAffaires]);Null;fonction SomDom(...)) Remarques : ce genre de calcul, sur le (sous)formulaire Affaires, qui peut contenir un grand nombre d'affaires, ralentirait beaucoup le fonctionnement. C'est beaucoup plus lent, à cause de chaque fonction SomDom, que les mêmes calculs dans la requête de la 2ème maquette. Ici, dans le sous-formulaire des sections de chaque affaire, il y a au plus une dizaine de sections par affaire, ce qui fait qu'on peut se permettre ce genre de luxe. 4- couleurs de chaque feuille de données, repères visuels, pour distinguer les Affaires -> Sections -> heures allouées (les 3 s'ouvrent les uns dans les autres, quand les Affaires sont en feuille de données, voir image) : voir les remarques dans les évènements Form_Load du ssfAffaires (pendant le débogage, les couleurs peuvent 'sauter' ou changer et être enregistrées avec les autres modifs de chaque sous-formulaire). Je ne pense pas que ce soit un luxe d'y voir clair en travaillant. Par contre, si tu as le temps ou les moyens de faire intervenir un graphiste professionel, il peut bien sûr faire beaucoup mieux, éviter les couleurs fatigantes... ![]() 5- sous-sous-formulaires (heures allouées/prévues/passées) :- corrections sur la requête (F10-120_a_a_c ssfHeuresPrevues-Employes) du ssfHeuresPrevues-Employes : pour pouvoir ajouter des heures prévues par Employé, il faut + utiliser une liste déroulante, pour choisir un employé (ton champ calculé n'était pas modifiable). + que la source du contrôle soit l'IdEmployé et non pas le nom + prénom : on peut faire afficher Nom+prénom par la liste, en masquant la 1ère colonne. Du coup, on n'a même pas besoin de la table Employes dans la requête - idem sur les heures passées... - suppression des listes déroulantes d'IdSectionsAffaires : elles ne sont pas utiles. Le champ est nécessaire dans la requête, en tant que 'champ fils', pour la liaison, mais c'est tout. Lorsque'on ajoute un enregistrement, Access met automatiquement le n° d'IdSectionAffaires du formulaire parent (ssfSectionsAffaires), comme si chaque 'Champ fils' avait une valeur par défaut, égale au 'champ père' correspondant. - à l'inverse, pour permettre l'ajout d'heures prévues/passées, les contrôles 'Employé' et 'Société' (fournisseur) sont devenus des listes (combo) -> 'cmbEmploye', 'cmbSociete'... avec une requête enregistrée qui porte l'index du sous-formulaire + le nom du contrôle (F10-120_a_a_c cmbEmploye, par exemple). 6- retouches diverses : - liste déroulante des semaines (ssfHeuresPasséesEmployes) : tri par + affichage du n° de semaine au lieu de l'Id (mais tu préfères peut être afficher le 1er jour de la semaine ?). Un "luxe" serait de remplacer cette requête et la table sous-jacente par un calcul qui renvoit le n° de semaine (fonction DatePart), ou au moins, de générer cette table automatiquement. - à vérifier/compléter : tous les noms de contrôle commencent par le préfixe : txt pour les text box, cmb pour les combo... Les sous-formulaires commencent directement par 'ssf', sans l'index avant ('10120-...'), qui n'est utile que dans la fenêtre base de données. Ceci est nécessaire pour le code de nos boutons bascule d'affichage ! D'autre part, je recommande fortement d'utiliser de tels préfixes, ne serait-ce que pour bien distinguer les champs de la requête et les contrôles auxquels ils sont liés. ----------------------------- Donc, ce qu'il reste à faire : - finir la structure des tables (indexes métier + champs obligatoires...) - décider du formulaire qui te convient le mieux pour faire ton travail, - le finir : au moins redimensionner les onglets et les sous-formulaires, pour profiter de tout l'écran, quelle que soit sa taille (techniques déjà vues, quelques détails nouveaux à mettre au point) - je te montrerai alors comment utiliser ce formulaire pour pré-sélectionner et trier des affaires, et imprimer un état correspondant (tu pourras très vite ajouter autant d'états que tu le souhaites) - passer à la suite : moteur de mise à jour de la base de données, - tests et livraison. |
|||
|
|
00
|
Copyright © 2000-2012 - www.developpez.com