Sous-formulaires : une mise au point

43 réponses

  1. Alino dit :

    bjr, svp je suis en entrain de faire une application de la gestion de facture, quelqu’un peut avoir un modele pour que m”inspire de ca. merci en access

  2. elvisogo dit :

    je suis désoler du dérangement mais je voudrais urgemment une réponse a une question ,si possible .
    voila j’ai fait un sous formulaire qui était au départ afficher empiler j’ai eu a modifier des champs ajouter et supprimer .
    maintenant je veux que lorsque j’ajoute un nouveau enregistrement que il fasse un retour a la ligne pour un nouveau .
    donc j’ai transformer(affichage) le sous formulaire en mode tabulaire .
    mais sa ne marche pas .
    je précise que les relation entre les deux table son bien établis
    voici un peu l’aspect que je veux obtenir
    http://www.developpez.net/forums/d1514062/logiciels/microsoft-office/access/ihm/access-presentation-d-sous-formulaire/

  3. BOBE48000 dit :

    MERCI HERVEE SUR CES TUTO ET LE DETAIL QUI TA APORTEE
    JE VEUT UNE CHOSE EN PLUS!!!!!!!!!!!!!!! JE VOUS EN PRIS SI TU PEUT

    PUISQUE JE TAPE MON ADRESSE EMAIL DS COMMENTAIRE UN EMAIL DE TA PART “BLOG” ME RENSEIGNÉE QUE TA RÉPONDRE A MON COMMENTAIRE
    ET MERCIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII

  4. Hervé Inisan dit :

    Julien > Dès qu’on parle d’impression, je pense “États”. On peut effectivement imaginer un état + un sous-état, qui donneront pour le papier sensiblement le même résultat que “formulaire + sous-formulaire” à l’écran.

  5. Julien dit :

    Bonjour,

    Est il possible d’imprimer l’ensemble? ( formulaires et sous-formulaires) , je tourne sous access 2010. En tout cas, merci pour cet article !! :) Julien.

  6. danbo dit :

    Excellent travail pédagogique. J’ai fait le bond d’Access 97 directement à 2010…pas comparable, mais quels progrès dans l’outil.
    Merci pour ces éclaircissements.

  7. Hervé Inisan dit :

    Greed > Est-ce que l’objectif est de renseigner à la fois la table intermédiaire ET la table de compte, ou seulement la table intermédiaire, les comptes étant déjà en place ?

  8. Greed dit :

    je me rend compte que je n’ai pas donné un exemple qui correspondait à ce que je suis entrain de réaliser. J’aurai du tout de suite dire ce que je faisait concrètement, ce que je vais expliciter ici.

    Je me suis peut-être un peu(voir beaucoup ^^) embrouillé sur la notion de contrat. En fait je travaille en tant que stagiaire dans une banque, et je travaille sur des comptes. Je réalise des transfert entre même banque, ou vers d’autres banques. Le but étant de mémoriser tout les transfert avec les dates etc…

    Finalement dans la table que j’appelais contrat, c’est une table qui correspond à un compte spécifique (je travaille sur deux type de comptes) et donc il faudrait aussi remplir la table du compte ce qui donnerait :

    le client et son compte à ajouter ainsi que la table intermédiaire

    je suppose qu’il faudrait utiliser deux sous-formulaires du coup, un pour la table intermédiaire et un avec le compte, mais peut-être est-il possible d’ajouter le client et le compte et que la table intermédiaire se remplisse en fonction de ces deux derniers?

    j’espère que c’est un peu plus compréhensible ^^

    Merci de m’accorder du temps ^^

  9. Hervé Inisan dit :

    Greed > A vue de nez, il faudrait effectivement :

    1. Que le formulaire principal soit effectivement basé sur la table des Clients (ou une requête qui en reprend tous les champs ; ça permet toujours de trier :-)).
    2. Construire une requête basée sur la table de jonction (TJ) et sur la table Contrats (TC).
    3. Placer sur la grille de cette requête tous les champs de TJ.
    4. Placer sur la grille les champs complémentaires de TC. Il faut considérer que TC n’est qu’accessoire ici : le but du sous-formulaire n’étant sans doute pas de définir des contrats, mais de les rattacher à un client. C’est bien TJ qui est la table principale du sous-formulaire.
    5. Construire un formulaire (futur sous-formulaire) en mode Feuille de données, basé sur la requête.
    6. Placer ce formulaire sur le formulaire Clients (ou l’insérer via l’icône Sous-form/Sous-état).
    7. Vérifier, dans les propriétés du container, que les champs Pères/Fils sont correctement définis.

    HTH!

  10. Greed dit :

    Oui c’est pour représenter sur formulaire.

    En fait j’essaye de faire un formulaire d’ajout, mais comme il y a 3 tables reliées, il faut que tout arrive à s’imbriquer dans les tables.

    J’ai un table client et une table contrat et donc la table intermédiaire. Le but étant à l’aide d’un sous formulaire de pouvoir ajouter tout ces éléments en même temps. J’ai essayer en faisant une requête qui contiendrai les champs de la table intermédiaire et de la table contrat, cette sous requête étant le sous formulaire en mode feuille de données. Et donc la table clients en formulaire principal avec zones de texte(comme
    vous avez fait avec votre formulaire).

    Mais quand j’essaye de mettre des données dans le sous formulaire, il y a des message d’erreurs du genre : “Un problème est survenu pendant la communication entre Microsoft access et le serveur OLE ou le controle ActiveX”.

    Je sais pas si j’ai été clair(j’ai pas trop l’impression ^^)

    Merci d’avance

  11. Hervé Inisan dit :

    Greed > Si c’est pour mettre en place la relation au niveau des tables, cet article du blog devrait aider. Mais j’imagine que la question porte plutôt sur la transposition de ces relations sur les formulaires ?

  12. Greed dit :

    Merci beaucoup^^

    J’ai une autre question, plus compliquée cette fois ci :
    Que se passe-t-il lorsque l’on essaye de représenter une relation de type plusieurs-à-plusieurs ?
    J’ai essayé de le faire dans ma base, mais j’ai des messages d’erreurs à tout va. Je me demande alors si c’est réalisable?

    Cordialement,

    Greed.

  13. Hervé Inisan dit :

    Greed > En mode Création de formulaire, un double-clic sur le carré au coin des 2 règles graduées donne les propriétés du formulaire. Dans ces propriétés, sous l’onglet Format, se trouve une option Image. Il y a quelques autres options, à côté, pour régler le positionnement ou le découpage de l’image de fond.

  14. Greed dit :

    J’ai juste une petite question :

    Comment fait-on pour mettre une image en fond d’écran du formulaire, comme sur votre formulaire plus haut ?

    Cordialement,

    Greed.

  15. Hervé Inisan dit :

    Sacapapiers > S’il s’agit de mettre à jour le formulaire parent, tu as plusieurs variantes :

    • Forms![Nom du formulaire parent]![Nom du champ]
    • Me.Parent![Nom du champ] devrait passer aussi (pas d’Access sous la main pour tester, à c’t’heure :-))
  16. Sacapapiers dit :

    Bonjour
    et bravo pour ce site!
    Je rencontre une difficulté pour mettre à jour un champ de mon formulaire principal (de type message texte) quand survient un evènement dans mon sous formulaire. Je dois surement me tromper dans la syntaxe mais j’ai l’impression d’avoir essayé toutes les combinaisons déjà!
    Merci de votre aide
    Cordialement

  17. beren57 dit :

    merci pour votre aide. J’avais tout simplement oublié de mettre un .form avant le .requery lors de ma première tentative. Après je suis parti dans tous les sens pour rien. Grâce a vous ca fonctionne. Merci beaucoup et bonne continuation

  18. Hervé Inisan dit :

    beren57 > Si l’action de mise à jour est déclenchée d’un sous-formulaire, il suffit sans doute de donner le chemin absolu du second sous-formulaire. Du style :

    Forms![Nom du formulaire principal]![Nom du 2nd sous-formulaire].Form.Requery

  19. beren57 dit :

    Bonjour

    J’ai un léger souci avec un de mes formulaires. Sans doute assez semblable a celui de xavier un peu plus haut. J’ai un formulaire principal, référençant tous les employés d’une entreprise. Ce formulaire est “unique”, c’est a dire que je garde les petites flèches en bas pour naviguer entre les enregistrements. Donc une page = un employé. Sur chaque page, j’ai une multitude d’infos sur les employés, la plupart d’entre elles étant réparties su différents onglets. Dans un de ces onglets, nommé “congés”, j’ai deux sous-formulaires.

    Le premier sous-formulaire est basé sur une Table “congés”, mais n’y récupère aucune information (a part dans les champs invisibles, remplis automatiquement : Nom et ID_employé, qui servent de lien avec le formulaire). Les champs y restent vides. A l’intérieur, un champ “date de début” avec calendrier associé, un champ “date de fin” idem, et un champ “durée en jours”. En dessous un bouton pour valider la saisie.

    Au dessus, un autre formulaire sous forme de liste d’enregistrements, lui aussi basé sur la Table “congés”, et en affichant toutes les infos sous forme de liste, là aussi avec les champs “Nom” et “Id_Employé” comme lien entre formulaire et sous formulaire.

    Tout fonctionne très bien, si ce n’est qu’une fois un congé ajouté pour un employé, il me faut aller voir l’employé suivant et revenir su le premier pour voir apparaitre mon nouvel enregistrement.

    Je me doute qu’il s’agit tout bêtement d’un problème d’actualisation, mais que ce soit via .requery ou via une macro dans laquelle je ne demande que d’actualiser le second sous formulaire, impossible d’y parvenir. Le bouton étant dans un sous formulaire, j’ai supposé qu’il fallait d’abord indiquer a cette conne de bécane qu’il fallait d’abord retourner dans le formulaire principal via un [Me].parent… Mais rien a faire, ca bloque. Quelle que soit la manière dont je m’y prends, Access ne comprend pas ce que je lui demande. Ça me paraissait pourtant assez con et rapidement maitrisable, comme ca, de prime abord, comme “bug”. Bref je ne sais plus vraiment quel chemin d’accès lui fournir pour qu’il comprenne que je veux actualiser le sous-formulaire juste au dessus du sous-formulaire contenant le bouton…

    Vous pourriez m’aider ?

    Ah oui et au fait ! je suis sous Access 2003, ca change peut être la donne, on sait jamais

  20. Hervé Inisan dit :

    Paselo > La base que j’utilise ici est dérivée de celle que j’ai publiée dans le “Cookbook 2002″. Les exemples du Cookbook sont téléchargeables sur cette page (l’exemple de vidéoclub correspond au chapitre 3 du livre).

  21. Paselo dit :

    Bonjour
    super votre site… je commence à me mettre à access…pffffffffff!
    Je suis en train d’essayer de faire un petit prog de location-vente de matériel avec des contrats… Votre exemple m’intéresse, pourriez-vous me l’envoyer ou un autre plus proche de ce que je cherche…
    D’avance merci
    PS j’ai access 2010

  22. Hervé Inisan dit :

    ticabri > En fait, je me dis qu’il y a une erreur de manipulation quelque part : le sous-formulaire doit rester sous-formulaire dans l’opération. Je m’explique :

    1. Tu as un sous-formulaire basé sur la table 2.
    2. Si j’ai suivi, ce sont les champs de ce sous-formulaire que tu essaies de placer dans un onglet. Tous les champs j’imagine.
    3. Si tu fais un Couper/Coller des champs, et que tu les places dans une page d’onglet, ces champs sont collés en tant que champs du formulaire principal. C’est donc normal à ce moment qu’ils perdent leur source (et qu’ils affichent #NOM?).
    4. Par contre, il faut que tu fasses un Couper/Coller du rectangle container complet, de façon à conserver l’objet sous-formulaire complet.

    Une autre façon de faire, qui peut simplifier les choses :

    1. Tu supprimes entièrement le sous-formulaire de son formulaire principal.
    2. Tu cliques sur l’icône “Sous-formulaire/Sous-état” (sans maintenir).
    3. Tu cliques directement dans la page d’onglet concernée. Le sous-formulaire s’insèrera directement là, et il n’y a plus besoin de Couper/Coller dans ce cas.

    J’espère que ça peut dépanner. :-)

  23. ticabri dit :

    Bonjour et merci pour la patience dont vous faîtes preuve!
    Je fais bien des couper-coller (et non pas des copier-coller).
    Par ailleurs, voici ce que j’obtiens au niveau des contrôles:
    - pour le Formulaire: source Table1
    - pour les champs venant du sous-formulaire, j’avais mis simplement leur intitulé (exemple: Question1).
    J’ai alors droit à l’erreur:
    “Propriété de contrôle non valide: Source contrôle
    Aucun champs de ce type dans la liste des champs”.
    J’ai corrigé en :
    [Table2]![Question1]
    mais j’ai la même erreur.
    Pourriez-vous m’indiquer comment corriger cela, svp?
    J’ai l’impression de n’avoir pas compris quelque chose au niveau de la construction du sous-formulaire…
    Encore merci!

  24. Hervé Inisan dit :

    ticabri > Dans ce cas, il reste une solution manuelle : vérifier/corriger la source de chaque contrôle (par ses propriétés, onglet Données) après le Coller. C’est un peu laborieux, mais ça devrait marcher. Tu fais bien un Couper/Coller, pas un Copier/Coller ?

  25. ticabri dit :

    Merci pour votre réponse.
    Je ne pense pas que ce soit la source de l’erreur car j’ai procédé de cette façon (apprise sur votre vidéo, par ailleurs…merci encore).
    De plus, il reconnaît les champs du premier formulaire, ce sont vraiment ceux du second (le sous-formulaire) qui posent problème.
    Est-ce une erreur de débutant ou y a-t-il du code caché derrière?
    Merci encore pour votre aide.

  26. Hervé Inisan dit :

    ticabri > Pour déplacer les champs existants dans une page d’onglets, il faut les couper/coller :

    1. Les sélectionner.
    2. Les couper.
    3. Sélectionner la page d’onglet de destination.
    4. Coller.

    Ça pourrait venir de là…

  27. ticabri dit :

    Bonjour,
    tout d’abord, bravo et merci pour ce site bourré de trucs et astuces, bien pratiques quand on débute!
    Je vous écris car j’ai du mal à jongler entre onglets et sous-formulaires…
    Je crée deux tables (en relation avec une requête) et deux formulaires séparément.
    Ensuite, à partir du premier formulaire, j’insère un sous-formulaire en utilisant un formulaire existant (celui correspondant à la deuxième table).
    Jusqu’à ce point, pas de problème.
    Lorsque je désire présenter le tout avec des onglets, cela se corse puisqu’il m’affiche les fameux #Nom ? .
    Je n’ai pas compris comment entrer les champs du sous-formulaire dans l’onglet de façon à ce qu’il les reconnaisse.
    Merci d’avance pour votre aide!

  28. Hervé Inisan dit :

    Florian > Si j’ai suivi la question, le comportement me semble normal : la recherche se fait dans la source de données “visible”. Or dans le cas du sous-formulaire, cette source de données est filtrée par le formulaire principal. D’autre part, la notion de client n’existe pas directement dans le sous-formulaire, celui-ci ne provoquera pas un déplacement dans le formulaire principal.

    Il faudrait penser les choses autrement, parce qu’il s’agit d’une recherche de client à partir d’un dossier. Dans les grandes lignes :

    1. Prévoir une requête qui associe les tables Client + SAV.
    2. Permettre une recherche de NoDossier sur cette requête et extraire le Numéro de client associé (les 2 sont disponibles dans la requête du 1.). La recherche elle-même peut s’envisager par un DLookup par exemple, ou par une liste déroulante basée sur la requête.
    3. Se positionner sur le client trouvé – s’il a été trouvé.
  29. Florian dit :

    Bonjour,
    Super votre blog. J’ai déjà lu la moitier je pense… par contre j’ai pas trouver la solution à mon problème!

    J’ai un formulaire principal(client) contenant 4 sous formulaires, se trouvant chacun dans un onglet respectif.

    Un sous formulaire (service après-vente), contient un champ “NoDossier”. C’est la clé primaire de la table aussi.

    Lorsque je tape “ctrl+F” et le nom d’un client par exemple, je le trouve automatiquement. Par contre, pour trouver un numéro de dossier, ça ne foncionne pas! Si je me possitione, dans le champ “NoDossier” de mon sous formulaire “Service après-vente”, il cherche le numéro qu’à l’intérieur de cet enregistrement. Alors que moi, je veux qu’il cherche ce numéro dans tout les enregistrement(donc pour chaque client).

    J’espère que j’ai étais clair…
    Merci d’avances!

  30. Hervé Inisan dit :

    doul > J’ai déjà donné une réponse à l’un d’entre vous, sur un autre message du blog ;-)

    Lorsque #Nom ? s’affiche, c’est que, dans la formule, un objet n’est pas référencé par son nom exact. Du coup, je vérifierais la première partie entre crochets (il doit s’agir du nom du sous-formulaire, pas celui de la requête ; voir sur cette page). Il faut aussi que le champ [Total TTC] existe dans le sous-formulaire pointé.

    En passant : en termes d’organisation, ce n’est pas une bonne idée d’appeler un formulaire ou sous-formulaire “Requête2″. Il vaut mieux donner un nom qui facilitera la mise au point (la preuve ! ;-)).

  31. doul dit :

    salut et merci pour ce blog;
    j’ai un formulaire nommé facture et un Sformulaire Requête2; basé sur une requête qui me permet de calculer le Total TTc de chaque produit acheté. Maintenant je voudrais pouvoir calculer le Net A Payer de chaque facture qui sera la somme de tous les T.TTc des differents produit achétes par un client. j’ai cette formule dans le pied de (s)formulaire =Somme(nz([Total TTc])) et celle-ci dans le second pied de formulaire =[Requête2 sous-formulaire].Formulaire![Total TTc] qui me donne ceux-ci a l’ouverture du formulaire #nom?.
    J’ai besoin de votre aide

  32. Hervé Inisan dit :

    xavier > Difficile d’être précis sans la base en mains, mais je dirais que ça vient d’un problème de mise à jour d’enregistrement. Des pistes à creuser :

    • Valider la saisie (celle où il faut changer d’enregistrement) comme indiqué ici.
    • Forcer une mise à jour du formulaire et/ou du sous-formulaire (ça dépend où ça coince). Un .Requery à mettre quelque part.

    Si tu peux poster une capture d’écran (sur Cjoint.com ou Imageshack.us), je peux peut-être avoir plus d’infos…

  33. xavier dit :

    ce site est super, mais malheureusement je n’y trouve pas la reponse a mon probleme. J’ai 1 formulaire et 2 sous formulaires. Je remplis le deuxieme grace au premier (une liste deroulante pour choisir mon produit).Mais dans une vente je peux en vendre plusieurs et je voudrais qu’ils s’inscrivent directement sur mon deuxieme sous formulaire. Je n’ai le resultat que si je passe a l’enregistrement suivant et reviens en arriere. Merci de votre écoute !!!

  34. Hervé Inisan dit :

    > Ricbois

    Pour l’instant, la technique donnée dans l’article qui parle du calendrier est limitée à un formulaire normal, elle “n’adresse” pas un champ de sous-formulaire. Je tâcherai de publier une autre version qui en tient compte…

  35. ricbois dit :

    Bonjour,
    J’utilise un sous-formulaire dans un formulaire et je voudrais utiliser la méthode mentionné sur un bouton Calendrier qui se trouve dans mon sous-formulaire. Le bouton appele un autre formulaire Calendrier et lorsque je sélectionne une date je veux qu’il renvoie la date dans un champ de mon sous-formulaire.

    Voici comment j’ouvre le calendrier lorsque je clique sur le bouton:
    DoCmd.OpenForm “frmCalendrier”, , , , , , “Forms![frmChatons]![sfrmChatonMedic].Form![DateMedic]“

    Mais cela ne fonctionne pas, lorsque je sélectionne la date il me donne un message d’erreur “Impossible de trouver le formulaire “Forms” auquel il fait référence….”

    Pouvez-vous m’aider??

  36. Hervé Inisan dit :

    Opo > Quelle est la formule de la mise en forme conditionnelle pour colorier la ligne active ?

    Et est-ce qu’il y a des calculs sur le sous-formulaire ?

  37. Opo dit :

    Bonjour,
    Je viens poser une question un peu “hors sujet” mais vous semblez maitriser Access sur le bout des ongles ! J’utilise un sous formulaire en tant que grille de saisie pour un applicatif métier. Certaines cellules de la grille sont “locked” car consultables seulement et non modifiables. J’utilise également des formatages conditionnelles pour mettre en surbrillance la ligne en cours de traitement (je n’ai trouvé que ça comme méthode !) le souci : une fois la donnée modifiée et validée, tout mon écran se met à “scintiller” jusqu’à ce que le curseur revienne en bonne position. le “docmd.echo false” ne fonctionne pas, l’écran scintille quand meme. Qu’utiliseriez vous à ma place ? d’avance merci de votre réponse.

  38. Hervé Inisan dit :

    Salut Maxence !

    Merci pour ton avis. L’idée de départ du billet était de clarifier la différence container/contenu pour les gens qui se mélangent les pinceaux, notamment dans les réglages Pères/Fils (sans attaquer l’angle programmation). J’ai tenu compte de tes remarques, et j’ai essayé de préciser certains termes pour que ça soit plus clair. Si tu as des compléments, n’hésite pas…

  39. Très intéressant article !
    Et la “vidéo” est un plus non négligeable !

    Je me permet cependant d’attirer ton attention sur le fait que les termes utilisés risquent d’induire en erreur le lecteur :
    Tu parles de contrôle conteneur, mais pas d’objet Sous-Formulaire/Sous-etat(class SubForm) de manière suffisamment explicite … enfin, je pense …
    Et tu parles bien de Formulaires, mais tu utilises aussi le terme de Sous-Formulaire.

    Bref, dans l’esprit de l’utilisateur, un Sous-Formulaire peut être à la fois le contrôle conteneur (SubForm) et le formulaire (Form) sous-jacent, décrit dans la propriété Objet Source du contrôle Sous-Formulaire/Sous-Etat, ce qui est bien différent, puisque
    * pour accéder à mon objet sous-formulaire, j’aurai
    Me.ObjetSousForm
    * pour accéder au formulaire sous-jacent j’aurai
    Me.ObjetSousForm.Form

    Que penses-tu de ces remarques ?

  40. quinou81 dit :

    Je serai vivement interresse par la solution pour faire ce formulaire ainsi que le sous formulaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">