Comment créer un formulaire à partir de données d'une requête

[Résolu]
Signaler
Messages postés
75
Date d'inscription
vendredi 10 mars 2006
Statut
Membre
Dernière intervention
23 août 2006
-
Messages postés
792
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
12 juin 2012
-
Bonjour,
Je crée une interface utilisateur sur VBA Access et je souhaite dans un formulaire (Form1)créer un sous-formulaire (Form2) affichant les données d'une requête. Cela est possible manuellement avec l'assistant de création de formulaire (pour créer Form2), puis en insérant un sous-formulaire (issu de Form2) dans le formulaire principal (Form1). Seulement je veux l'écrire dans du code la création d'un formulaire à partir d'une requête....
Aidez-moi siou plait  ça fait plusieurs messages que j'écris sur le sujet et je n'ai pas de réponse!!!
Merci

21 réponses

Messages postés
75
Date d'inscription
vendredi 10 mars 2006
Statut
Membre
Dernière intervention
23 août 2006

Youpi j'ai réussi! Et finalement, c'était pas si loin de la première proposition, c'est-à-dire un simple changement de source (néanmoins j'ai utilisé pour d'autres choses le code de Trayac)

Sub Apercu(NomRequete As String)
DoCmd.OpenForm "Form2", acDesign, , , , acHidden 'le formulaire Form2 existe déjà
'effacement des contrôles existants
boucle:
i = 5
For Each ctl In Forms!Form2.Controls
i = 1
DeleteControl "Form2", ctl.Name
Next ctl
While i = 1
GoTo boucle:
Wend
Dim controle As Control
Set controle = CreateControl("Form2", acSubform, acDetail, , , 0, 1900, 6000, 3270)
controle.SourceObject = "Requête." & NomRequete
controle.Name = "SsForm2" 'il s'agit du sous-formulaire du formulaire Form2 (auquel j'ai ajouté d'autres contrôles)
DoCmd.Save acForm, "Form2"
DoCmd.Save acForm, "Form1"
DoCmd.Close acForm, "Form2"
SsForm1.SourceObject = "Form2" 'un sous formlaire est déjà intégré à ma form1, sa source d'origine est un formulaire vide
DoCmd.OpenForm "Form1"
End Sub

Private Sub CommandValider_Click()
SsForm1.SourceObject = "Form3" 'un formulaire vide
If QryExist("Requête") Then 'appel de la fonction interrogeant sur l'existance d'une requête
DoCmd.DeleteObject acQuery, "Requête"
End If
Requete 'appel de la requete définie dans un Sub
Apercu ("requête")
End Sub

Qu'en pensez-vous? Ca peut peut-être être amélioré...
En tout cas, ça a l'air de marcher pas trop mal, sauf qu'hier, lors de l'éxécution du programme finalisé, j'ai eu un paquet de bugs (Access s'éteignait automatiquement sans signaler les zones d'erreur, ni même ramer) et aujourd'hui comme par miracle il tourne à merveille! BIZARRE BIZARRE...

J'aurais donc à ce stade une autre question: existe-t-il un programme tout fait qui me permette d'ouvrir une requête existante (sorte de boite de dialogue), en proposant à l'utilisateur l'ensemble des requêtes qui existent?
D'autre part, est-il possible d'instaurer une sorte de mémoire de saisie, dans une zone de texte, comme sur les recherches internet : c'est-à-dire pouvoir retrouver une saisie déjà réaliser à partir des premières lettres ou encore mieux, d'un nom de code donné par l'utilisateur lors d'une précédente utilisation...?

En tout cas, merci pour tous ces conseils qui m'ont quand même mis sur la bonne piste!
3
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 112 internautes nous ont dit merci ce mois-ci

Messages postés
262
Date d'inscription
lundi 20 octobre 2003
Statut
Membre
Dernière intervention
27 avril 2007
1
La procédure est assez longue à expliquer ici. Pourquoi ne pas, plus simplement , modifier la source de données de ton sous-formulaire par code ?
Quel est plus précusément ton besoin ?

Cordialement,

Alain 31
Messages postés
792
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
12 juin 2012
5
Salut 716258 observatoire, salut =182298 asecher,

pas de réponses! t'es quand même culotté!
http://www.vbfrance.com/infomsg/APERCU-RESULTATS-1_724534.aspx
http://www.vbfrance.com/infomsg/AFFICHAGE-REQUETE-DANS-FORMULAIRE-2_725509.aspx

En plus, à chaque sujet, on en apprend plus. Restes dans le même sujet, et les messages se suivront.
Ton attitude est quelque peu égoïste, car il est possible que certains repèrent une de tes questions (parce qu'ils ont le problème), la marque pour être notifiés lorsqu'il y a une réponse, mais, comme tu changes tout le temps, ils finissent par penser qu'il n'y en a pas (peut-être même, si ça se trouve, ils changent de langage:) )

Cette fois-ci, j'apprends que tu veux créer un formulaire en code! Peut-être prépares-tu un robot codeur (si c'est ça, je ne t'aiderai pas :))? En plus, comme le dit asecher, tu peux peut-être te contenter de créer le tout avec l'assistant, et à l'affiner (contrôles, apparence et données), au dernier moment, en code.

Non allez, un peu de sérieux, restes dans un de tes messages (ici, par exemple), fais au moins une réponse à ce que l'on te demande (pour nous prouver que tu restes là), et on essaiera de t'aider du mieux qu'on peut! (j'en connait un, grand spécialiste de la génération de code en dynamique, et à partir de VBS, je ne dis pas son pseudo [commence par un J, finis par un O], sûr qu'il pourrait t'aider)

à+

rvblogn

<sup>
</sup><sup>Je veux ton bien... et je l'aurais... mais jamais avant la page 4
</sup>
Messages postés
75
Date d'inscription
vendredi 10 mars 2006
Statut
Membre
Dernière intervention
23 août 2006

Alors je t'arrête tout de suite: remarque que j'ai écris le message ci-dessus avant que tu me répondes à celui d'avant:
http://www.vbfrance.com/infomsg/AFFICHAGE-REQUETE-DANS-FORMULAIRE-3_725509.aspx
J'ai supposé qu'au fur et à mesure que de nouveaux messages arrivaient dans le même forum, mes messages avaient de moins en moins de chances d'être lus par les utilisateurs, étant donné qu'ils finissent par passer à une autre page. J'imaginais aussi que peut-être je n'étais pas assez claire dans mes messages et que c'était pour ça qu'on ne me répondais pas! De plus j'affine mes questions étant donné que je passe un certain temps à tourner autour pendant la journée!
En tout cas merci de suivre mon problème au fil des messages :-) (je vois que je suis surveillée de près!!)


Pour en revenir à mon problème, je ne sait pas ce que tu appelles un "robot codeur". Effectivement "modifier la source de données de ton sous-formulaire par code" ça me conviendrait mais je ne sais pas comment faire ça (pour l'instant).
Pour être plus précise: j'ai une interface utilisateur, où l'utilisateur a des cases à cocher, des zones de listes déroulates à remplir. A partir de ça une requête (sur une base de donnée existante) est créée, et je souhaite intégrer les résultats de cette requête à l'affichage du formulaire comme un aperçu des résultats dans la même fenêtre. Je sais c'est un peu gadget lol. J'ai essayé par état, mais ça ne s'intègre pas je crois au formulaire, et par sous-formulaire qui intègre une requête, mais ça marche uniquement pour une requête donée déjà créée.


Voilà


Sur ce @+
Messages postés
792
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
12 juin 2012
5
Salut observatoire,

tu as parfaitement raison, et je m'en excuse. De plus, ta technique d'affinement n'est pas stupide du tout (bien au contraire), c'est juste le suivi de tes questions qu'il faut assurer, c'est tout (tu peux d'ailleurs te contenter de mettre un lien vers le nouveau message).
Je ne cherchais pas à te froisser, mais à t'attrapper. Bon, c'est fait.

Dans le sujet que tu cites, j'ai fais une réponse ce matin, que je ne répètes pas ici (un peu fainéant le gars).

Le "Robot codeur", c'était une mauvaise plaisanterie.

Pour modifier la source de données du formulaire, en code, il faut utiliser la propriété Me.Form.RecordSource ou Me.Recordset.RecordSource du formulaire, et les propriétés ControlSource pour les Controls.
Pour le RecordSource, comme son nom l'indique, il est de type Recordset, ce qui convient parfaitement à une requête exécutée (donc à ton cas).

PS : j'adore ce genre de phrase, c'est admirable :
"mais je ne sais pas comment faire ça (pour l'instant)"
à+

rvblogn

<sup>
</sup><sup>Je veux ton bien... et je l'aurais... mais jamais avant la page 4
</sup>
Messages postés
75
Date d'inscription
vendredi 10 mars 2006
Statut
Membre
Dernière intervention
23 août 2006

"mais je ne sais pas comment faire ça (pour l'instant)"
je sais c'est un peu ridicule, mais c'est parce que ça m'arrive de résoudre les problèmes TOUTE SEULE avant d'avoir des réponses sur le forum.
Messages postés
792
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
12 juin 2012
5
non, non, ce n'est pas ridicule du tout !
je pensais (et pense toujours) ce que j'ai écrit! c'est admirable !
cela reflète un état d'esprit de combattant(e), et j'adore ça! (et tout le monde ne l'a pas, c'est précieux)

à+

rvblogn

<sup>
</sup><sup>Je veux ton bien... et je l'aurais... mais jamais avant la page 4
</sup>
Messages postés
75
Date d'inscription
vendredi 10 mars 2006
Statut
Membre
Dernière intervention
23 août 2006

Mon problème c'est qu'en changeant uniquement la source d'un formulaire déjà existant, les variables du résultat restent celles du formulaire d'origine et ne correspondent pas forcément aux variable de la nouvelle requête (plus ou moins de varioables). Je n'arrive qu'à créer un formulaire vide, en mode création (createform), et non directement un formulaire contenant toutes les varaibles de la requête.


 
Messages postés
792
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
12 juin 2012
5
oui, c'est logique.

c'est pour cela que je t'invite à créer un formulaire générique, couvrant la majeure partie de tes besoins.
Je reste donc orienté formulaire construit statiquement (en mode création), et contenant le plus de contrôles possibles.

Une astuce : met des Alias dans tous les champs de ta requête. Pas n'importe quels alias, des alias que tu auras conventionnés, et qui correspondent, à la lettre près, aux identificateurs de champs de formulaire, que tu auras, exhaustivement définis.
Tu pourras ainsi écrire, un outil :

Private Function FieldExists(Byref TargetFields As ADODB.Fields, _
                                            Byval strKey AsString ) As Boolean
On Error Goto FieldExistsErr
'********************************************************
'***   Renvoie True si le champ existe dans le recordset, False sinon   ***
'********************************************************
Dim fTemp As ADODB.Field

   Set fTemp = TargetFields(strKey)
   FieldExists = True
Exit Function
FieldExistsErr:
   FieldExists = False
End Function

Et puis, une procédure générique d'affectation des valeurs :

Dim ctlTemp As Control

   For Each ctlTemp In Me.Controls
      Select Case Typename(ctlTemp)
         Case "TextBox" '         vérifies les noms de type
            'si l'identificateur du contrôle de formulaire existe en tant qu'identificateur
            'de nom de champ dans le jeu de réponses
            If FieldExists (TonRecordset.Fields,ctlTemp.Name) Then
               'affecte la valeur du champ de jeu de réponses, au contrôle de formulaire
               ctlTemp.Text = TonRecordset.Fields(ctlTemp.Name).Value
            End If
         Case "Label"  '         vérifies les noms de type
            IfFieldExists(TonRecordset.Fields,ctlTemp.Name) Then
               ctlTemp.Caption = TonRecordset.Fields(ctlTemp.Name).Value
            End If
         '...
      End Select
   Next ctlTemp

Attention, je n'ai pas testé ce que je viens d'écrire, je l'ai écrit directement, mais d'instinct, ça marche :)

Qu'en penses-tu?
à+
rvblogn

<sup>
</sup><sup>Je veux ton bien... et je l'aurais... mais jamais avant la page 4
</sup>
Messages postés
75
Date d'inscription
vendredi 10 mars 2006
Statut
Membre
Dernière intervention
23 août 2006

J'en penses que ça doit faire des trous quand il manque des colonnes dans la requête!
Mais j'ai trouvé un code sur le site : http://www.vbfrance.com/code.aspx?ID=26450
ça me permet de faire correspondre exactement mon formulaire à ma requête.
Il me reste à déterminer comment l'intégrer comme "sous-formulaire" dans mon formulaire principal, avec les réactualisations, etc...
Messages postés
792
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
12 juin 2012
5
Dac,

j'ai vu la source, je ne suis pas sûr que cela soit prévu pour une utilisation run-time (avec la souris de l'utilisateur en plein milieu) mais plutôt comme une aide à la création de formulaire en développement.

Mais, qui vivra verra.

En tout cas, je suis content de savoir que tu utilises bien le moteur de recherche.

à+

rvblogn

<sup>
</sup><sup>Je veux ton bien... et je l'aurais... mais jamais avant la page 4
</sup>
Messages postés
75
Date d'inscription
vendredi 10 mars 2006
Statut
Membre
Dernière intervention
23 août 2006

juste un petit problème: avec ce code, mon sous-formulaire serait défini par défaut en mode création (je n'ai pas identifié le pourquoi du comment!) ce qui empêche donc l'ouverture du formulaire en mode formulaire.
Messages postés
792
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
12 juin 2012
5
Je ne sais malheureusement pas te répondre.
Essaies d'envoyer un MP à Trayachttp://www.vbfrance.com/code.aspx?ID=26450#/auteur/TRAYAK/343422.aspx), ou ajoutes un commentaire là où tu as trouvé la source.

à+
<gras>
rvblogn

<sup>
</sup><sup>Je veux ton bien... et je l'aurais... mais jamais avant la page 4
</sup>
Messages postés
792
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
12 juin 2012
5
Si, en fait, j'ai une idée de la raison, mais je suis vexé que tu me répondes "que ça doit faire des trous quand il manque des colonnes dans la requête" alors que je te livre un FieldExists tout fait! infidélité, comme tout homme qui se respecte, ça m'émeut.

Une fois l'orage passé, je pense que si tu ouvres le formulaire en mode création, dans la fenêtre des propriétés, tu peux voir (en français) les propriétés Affichage par défaut, Autoriser le mode formulaire,..., et si tu trouves l'équivalent en code (et si elles ne sont pas en lecture seule) tu tiens là ta solution!

Mais je pense toujours ce que je t'ai dit sur le run-time.

à+
rvblogn

<sup>
</sup><sup>Je veux ton bien... et je l'aurais... mais jamais avant la page 4
</sup>
Messages postés
75
Date d'inscription
vendredi 10 mars 2006
Statut
Membre
Dernière intervention
23 août 2006

Pitié! je vais finir par m'arracher les cheveux!
J'ai découvert mon problème d'origine : mon sous formulaire était en mode création car c'est ce que j'avais défini dans mon code:

DoCmd.OpenForm "ApercuTable", acDesign, , , , acHidden (où acDesign = mode création)

Je réouvre donc le formulaire en mode normal à la fin de la procédure de création de formulaire dynamique:

DoCmd.OpenForm "ApercuTable", acNormal, , , , acHidden

Il faut noter que le code de création de formulaire dynamique (cf. http://www.vbfrance.com/code.aspx?ID=26450) est très long à tourner!

Là mon sous-formulaire est intégré à mon formulaire principal, je veux donc le réactualiser. J'ai pensé rendre mon sous formulaire non visible par défaut et le rendre visible lors du lancement de la requête, MAIS je ne sais pas pourquoi, mon formulaire se ferme lors de la création de formulaire dynamique, ou suivant les modif que je fais il reste ouvert mais ne veut pas appliquer ApercuTable.visible = true parce qu'il serait "fermé ou supprimé".

Help siou plait
Messages postés
792
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
12 juin 2012
5
Salut observatoire,

tu portes mal ton pseudo. Je t'ai dit (écris) que ce code est orienté "aide à la conception" !

Sous Access (à moins que je ne me trompe), tu ne peux pas ouvrir un formulaire référencé comme sous-formulaire d'un formulaire ouvert (essaies à la main pour vérifier, si tu trouves un moyen, alors automatises-le).

Logiquement, si tu devais automatiser ce que le développeur fait réellement quand il crée un sous-formulaire, il faudrait que le formulaire parent ne contienne pas le contrôle sous-formulaire (de type SubForm), que tu prépares le formulaire destiné à être hébergé par le formulaire parent, que tu le fermes, que tu l'enregistres, que tu ouvres le formulaire parent en mode design, que tu lui ajoutes dynamiquement un contrôle sous-formulaire (de type SubForm), que tu assures le lien entre ce contrôle et le futur sous-formulaire, que enregistres le formulaire parent, et que tu le ré-ouvres en mode exécution.

Ca paraît simple, non? Mais long à exécuter, je veux bien de croire ! (tant pis pour tes cheveux:) )

à+
rvblogn

<sup>
</sup><sup>Je veux ton bien... et je l'aurais... mais jamais avant la page 4
</sup>
Messages postés
75
Date d'inscription
vendredi 10 mars 2006
Statut
Membre
Dernière intervention
23 août 2006

Mouais
effectivement j'ai dû mal choisir mon pseudo (il n'a d'ailleurs malheureusement pas fait l'objet d'une longue réflexion), je ne vois toujours pas où tu m'as parlé de code est orienté "aide à la conception".
Si je comprend bien (parce que ça aussi j'ai un peu de mal surtour avec tout ce jargon!) ça me donnera deux formulaires distincts au final ou plutôt ça va me réactualiser le formulaire principal avant d'ouvrir le sous formulaire?...
Mais ce que je voulais (et je crois que je vais finir par abandonner, vu que c'était juste pour faire un peu mieux au niveau de présentation: je me contenterais des requêtes dans une table à part) c'était de garder les cases cochées par les utilisateurs dans le formulaire principal et faire apparaître un "aperçu" des résultats dans le même formulaire...
tanpire
@+
Messages postés
792
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
12 juin 2012
5
Message du 02/05/2006 17:25:10
"j'ai vu la source, je ne suis pas sûr que cela soit prévu pour une utilisation run-time (avec la souris de l'utilisateur en plein milieu) mais plutôt comme une aide à la création de formulaire en développement"

Message du 02/05/2006 18:04:10
"Mais je pense toujours ce que je t'ai dit sur le run-time"

bon, passons,
après, c'est moi qui ai du mal à comprendre "ça me donnera deux formulaires distincts au final". Un sous-formulaire hébergé par un formulaire parent, ça fait toujours 2 formulaires! ça ne se voit peut-être pas (pour l'utilisateur), mais ça fait quand même 2 formulaires.

Enfin, le truc qui est sûr (à mes yeux), c'est que pendant le fonctionnement de ton application, l'utilisateur verra passer sous ses yeux ébahis, le formulaire en mode création, et ça (toujours à mes yeux), c'est pas bien du tout.

d'où la solution qu'asecher et moi même te proposions (malgré les apparences, c'est la plus simple, et la plus faisable, on l'a tous déjà fait une fois).

à+


rvblogn<SUP>
</SUP><SUP>Je veux ton bien... et je l'aurais... mais jamais avant la page 4
</SUP>
Messages postés
75
Date d'inscription
vendredi 10 mars 2006
Statut
Membre
Dernière intervention
23 août 2006

oui j'en convient c'est peut-être mieux, mais j'avoue que je ne me voyait pas à nouveau me lancer dans la tranformation du code, d'autant que je n'ai pas bien compris (décidément elle est pas très fut' celle là) ce que je suis sensée modifier dans mon code d'origine en plus d'intégrer ton code. Parce que s'il faut que je me mette à retoucher à la structure des requêtes (pour les "alias") je sens que ça va être la prise de tête!!!
Messages postés
792
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
12 juin 2012
5
Salut observatoire,

et pourtant, ma propre expérience m'apprend qu'il ne faut pas faire d'"affectif" en programmation (je sais de quoi je parle, je fais souvent de l'affectif). Quand ce n'est pas bon, il faut savoir jeter, et recommencer. On perd, à long terme, beaucoup plus de temps à rattrapper ce que l'on a mal fait, qu'à recommencer (cf loi de l'effort maximum).

Dans ton cas, rassures-toi, il n'y a pas grand chose à jeter, juste l'idée que le code (très bon au demeurant) de Trayac convienne à ton cas d'utilisation, c'est tout.

Mettre des Alias à tes requêtes, cela ne revient qu'à nommer tes colonnes conventionnellement (c'est à dire avec des noms qui sont toujours les mêmes, d'une requête à l'autre, lorsque la colonne sert à la même chose, et surtout, lorsqu'elle s'affichera dans le même champ). Un exemple :

SELECT Machin, Bidule, Truc, DateDuMachin FROM CHOSES

devient

SELECT Machin As NomDocument,
Bidule As Ecart,
Truc As ToleranceMax,
DateDuMachin As DateDocument...

ou sur une autre requête :

SELECT UnAutreMachin As NomDocument,
UnAutreBidule As Ecart,
DateDunAutreMachin As DateDocument...

et dans le formulaire, il y a toujours (et exhaustivement) les champs nommés conventionnellement :

NomDocument DateDocument

Ecart
ToleranceMax

Tu perfectionnes un peu le modèle de code que je te proposais, par exemple, en cachant les champs du formulaire qui n'étaient pas résultats de la requête, et voilà. Rien de bien compliqué.

Le plus dur (et le mot est fort), c'est la rigueur et l'abstraction nécessaire à évaluer tous les cas de figure de jeu de réponses de toutes tes combinaisons de requêtes possibles. Mais comme c'est déjà codé (si j'en crois les apparences), il suffit d'en faire l'inventaire!

C'est quand même pas un mec qui va donner une leçon de rigueur à une gonzesse! On est d'accord? En tout cas, ma femme est d'accord :)

Baisses pas les bras, ça ne se fait pas :) (et on en est à 20 messages, juste dans ce sujet, tu le dois, tu le dois à ceux qui lisentà tes utilisateurs, et je te le dois)

à+

rvblogn<SUP>
</SUP><SUP>Je veux ton bien... et je l'aurais... mais jamais avant la page 4
</SUP>