Contrôles dynamiques et modules de classe

Bonsoir à tous,

Je viens demander votre aide, car dans le cadre d'un "gros" projet, j'ai besoin de réaliser un "grand" nombre de formulaires présentant des motifs répétitifs (question avec Oui/non, zone de texte à remplir, zone de commentaire etc...). Après avoir bataillé pendant beaucoup de temps à faire chaque formulaire à la main, j'abandonne et je souhaite me tourner vers des formulaires générés dynamiquement.

Ce dont j'ai besoin, c'est de conseils et d'aide pour écrire des modules de classe. Dans ces modules de classe, je souhaite coder les éléments de mes formulaires (par exemple un cadre contenant:

  • une question
  • un bouton oui
  • un bouton non)

Ainsi lorsque je voudrais coder mon formulaire, je n'aurais qu'à instancier mon élément pré-codé (en texte, dimensions, position, contenu) ET AUSSI en évènements!

En effet, j'aurai besoin de réaliser PAR LA SUITE la chose suivante:

Si je clique sur le bouton Oui de mon cadre XXXX, alors le cadre YYYY réagis de la manière suivante (s'active/se désactive/fait la toupie)

D'un point de vu code, je ne sais absolument pas comment biencoder un module de classe, ni les choses à éviter. Je n'arrive pas à trouver d'exemple simple et complet de ce que je demande, donc si quelqu'un est capable de réaliser ce premier exemple, ça m'aiderait énormément comme base de travail.

Voilà pour le moment le frame que je souhaiterais réaliser grâce au module de classe.

Si quelqu'un peut m'aider, je l'en remercie d'avance !!

demande

L'idée finale est de pouvoir écrire quelquechose de ce genre de chose dans un module:

Set userform = new userformPerso 'Création DYNAMIQUE du userform, il n'est pas présent "physiquement" dans le projet VBA.

Set frame1 = userform.Add frameAvecOuiNon("Question que je veux poser")

Où la frame1 se place automatiquement à l'intérieur du userform, avec comme texte la question posée, et les deux checkbox souhaitées.

Bref si je rêve d'un monde utopique faites moi signe rapidement avant que je me noye sous les montagnes de documents qui expliquent comment on fait quelque chose qui ressemble mais qui au final n'aide pas

Bonjour

Je ne sais pas gérer un Userform crée dynamiquement

A tester

Salut Banzai64!

Merci pour ta proposition mais malheureusement j'ai déjà vu de nombreuses fois ce code et il ne répond pas à mon besoin (d'où le post)

En effet dans ce dernier, le module de classe ne sert qu'à associer aux objets des événements. C'est vrai que j'en aurai besoin, mais ce n'est que 10% de mon besoin. Ce qui me serait vraiment utile, c'est un frame personnalisé (contenant d'autres éléments) défini dans un module de classe. Avec 4 ou 5 modules de classes, je pourrais générer quasiment tous mes formulaires0

Si la génération d'un userform dynamique n'est pas possible ce n'est pas grave. Je préfère avoir un userform "vide" avec du code à l'intérieur que rien du tout, mais mon objectif est de pouvoir écrire chacun de mes formulaire de la manière suivante;

Dim monFrame = new framePersonnalise
With monFrame
.question = "La question que je souhaite afficher"
.reponse1 = "Réponse 1 proposée"
.reponse2 = "Réponse 2 proposée"
End with
Userform.Controls.Add monFrame

Et donc avoir un module de classe qui contiendrait ce genre de commandes

sub Class_Initialize()
set mFrame = MSForms.Frame
mFrame.Text = "La question que je souhaite afficher"
set mboutonOui = mFrame.Controls.add("ms.commandbutton")
mBoutonOui.Caption = "Réponse 1 proposée"
set mboutonNon= mFrame.Controls.add("ms.commandbutton")
mBoutonNon.Caption = "Réponse 2 proposée"
End sub

bonjour d3d9x, salut banzai64

Ou je n'ai pas bien compris ton besoin ou tu te fourvoies dans le côté obscure de la force

(dans quelque chose de compliqué qui ne l'est pas )

Pour moi un module de classe est à utiliser quand tu as un grand nombre d'objets identiques dans un usf

Or là, c'est un grand nombre de formulaire.... mais pourquoi !?

Regarde la solution que je te propose (1usf pour X questions) et dis nous

A+

Salut BrunoM45 et merci de ta proposition, malheureusement le formulaire est bien plus complexe que juste des questions avec Oui/non. Je demande un cas simple de frame avec 2 boutons, car si ce simple cas n'est pas réalisable, la suite le sera d'autant plus.

Un exemple plus complet est donné en image.

Je réalise un programme VBA d'arbitrage de Handball. Le but du programme est double:

  • avoir un suivi du match
  • avoir un système pour évaluer les arbitres et comment ils ont jugés une action.

Ainsi à chaque action durant le match est associé différents boutons:

actionpossible

Pour chaque action, divers sous-actions peuvent existent. Par exemple dans le cas d'une attaque, ce sera par exemple un 7m.

Si c'est un 7m voilà le formulaire proposé à l'utilisateur:

ex7m

Les éléments présents dans le formulaire sont toujours les mêmes:

  • un frame avec une question posée, et X possibilitées (oui/non, repA, repB, repC....)
  • un frame avec une question posée et une zone de commentaire
  • un frame avec une question posée et une liste déroulante
  • etc....

Mais ces éléments sont dans des ordres différents. Je peux avoir dans un formulaire une question puis une zone de commentaire puis une liste déroulante, et dans un autre juste des questions Oui/non.

Vu que ces éléments sont toujours les mêmes, je voulais en créer une classe de module par frame personnalisé, dans laquelle les frame sont créés, dimensionnés, positionnés, et leurs sous éléments (bouton, case à cocher, listbox... sont insérés)

Ainsi je crée mon formulaire vide, et dans son code j'y ajoute mes éléments

  • > ajouter un frame Oui/Non avec comme question "Ai-je démystifié le problème?"
  • > à la suite ajouter un frame de commentaire
  • > à la suite .....
  • > Si l'utilisateur séléctionne Oui dans le premier frame alors le frame2 disparait, et un autre est généré à la place
  • > etc....

C'est autant par amélioration que par besoin. Plus j'avance dans le projet, plus j'ai de problèmes avec les userforms. Régulièrement le fichier se corrompt, et tout le travail réalisé est perdu, et ce uniquement lors de modifications/ajouts de userforms complexes.

Bonjour

Ce que j'ai compris : Tu veux développer un langage servant à construire un formulaire

Si c'est ça, cela ne va pas être évident, beaucoup de possibilités s'offrent au développeur

Quand tu modifies la position d'un contrôle , en ayant le formulaire sous les yeux, cette opération est assez facile (déplacer certains contrôles)

Avec un langage cela va être plus dur à réaliser, car il faudra modifier les paramètres des contrôles qui doivent bouger

Je m'explique surement très mal mais ce que tu envisages ne va pas être aisé à réaliser

C'est mon côté pessimiste qui parle

Oui en effet c'est sûrement un truc un peu trop balaise pour moi à réaliser. Pour le moment j'ai réussi à contourner le problème grâce à la chose suivante:

****** Partie Formulaire *******

  • Je crée un formulaire vide
  • Dans l'initialisation j'ajoute un frame
  • Je passe ce frame en paramètre dans une procédure
****** Partie Module indépendant du formulaire *******
  • Dans un module simple, je crée différentes procédures prenant comme paramètre mon frame
  • Dans ces procédures, je modifie et positionne mon frame (grâce à son parent, et aux dimensions de son parent)
Public Sub frameOuiNon(ByRef maFrame As control, ByVal question As String)
Dim UserForm As UserForm1
Set UserForm = maFrame.parent

Ca marche super bien pour un frame, mais lorsque je rajoute d'autres frames, les cases à cocher sont invisibles !! Pourquoi? Mystère... Les frames se positionnent correctement, la position des cases à cocher est bonne.

Ci joint le fichier sur lequel je travaille actuellement histoire d'essayer des possibilitées.

Bonjour

Tu positionnes tes OptionButtons en fonction de la position de la Frame, alors que leur position est fixe dans la Frame

OptionButton1.Top = 16    'maFrame.Top + 10
OptionButton2.Top = 16    'maFrame.Top + 10

Et bien je ne l'aurais jamais trouvé. Dans ma tête la position "top" était la position dans le userform, pas dans le frame... Oui tout de suite ça marche beaucoup mieux ^^ Merci je vais persévérer dans cette voie!

Aurais-tu une idée pour réaliser la chose suivante:

- Ajouter un évènement aux boutons de ma frame après avoir instancié cette dernière?

Je m'explique:

Lorsque je clique sur la réponse 1 de la frameInitiale, je souhaite que la frameX soit activée et la frameY désactivée (cachée, supprimée, désactivée)

Lorsque je clique sur la réponse 2 de la frameInitiale, je souhaite que la frameX soit désactivée et la frameY activée

et donc avoir une sorte de fonction activerEvenements(frameInitiale,frameX,frameY)?

Petit à petit le schmilblick avance

Bonjour

Je ne sais pas ce que tu veux dire

d3d9x a écrit :

après avoir instancié

Le code est déjà prévu avant la création des contrôles, mais celui-ci ne sera utile qu'une fois les contrôles créés

Pour faciliter (parce ce que je ne sais pas faire sans) j'ai nommé les contrôles

A vérifier

Banzai64 a écrit :

Je ne sais pas ce que tu veux dire

d3d9x a écrit :

après avoir instancié

J'entends par là la chose suivante:

(1) Dans mon userform, ajouter toutes mes frames (par exemple au total 5 frames)

(2) Toujours dans mon userform, faire l'appel à ma procédure qui personnalise mes frames (dimension, texte, contenu, etc..)

(3) Toujours dans mon userform faire appel à une autre procédure qui elle LIE les frames entre elles.

L'étape (3) que je cherche à réaliser, c'est ce que tu m'as proposé, à la différence près (et non des moindres): je souhaite paramétrer l'évènement. Dans ce que tu me proposes, Une frame peut agir sur X autres frames, mais ces X frames sont "fixes".

Ce que je voudrais, c'est une procédure:

Public sub lierFrames(byRef framePrincipale as Frame,byRef frameChoix1 as Frame,byRef frameChoix2 as Frame)

Qui me génère ce type d'évènement:

Sub framePrincipale.Bouton1_onClick()
frameChoix1.Enabled = True
frameChoix2.Enabled = False
End sub

Sub framePrincipale.Bouton2_onClick()
frameChoix1.Enabled = False
frameChoix2.Enabled = True
End sub

Bonsoir

Pour moi cela devient trop complexe

Mais je comprends (enfin je le crois) que tu cherches à générer du code suivant ta demande

Je pense que cela est possible (il existe des scripts qui ajoutent du code VBA - Bien sur il faut connaitre exactement le code à ajouter)

Pour le moment je passe la main

Je vais suivre le déroulement de ce post

Bonne continuation

Le but n'est pas d'ajouter du code VBA physiquement via la procédure, mais de "créer" un évènement personnalisé paramétré

Dans mon userform

Dim frame1 as MSForms.frame, frame2 as MSForms.frame, frameTartenpion as MSForms.frame

Set frame1 = Me.Controls.add("Forms.Frame.1")
Set frame2 = Me.Controls.add("Forms.Frame.1")
Set frameTartenpion= Me.Controls.add("Forms.Frame.1")

Call  customiserFrame(frame1)
Call  customiserFrame(frame2)
Call  customiserFrame(frameTartenpion)

Call lierFrames(frame1,frame2,frameTartenpion)

Et dans un module de classe avoir un évènement:

sub lierFrames(frameQuiLanceL'evenement, frameLiée1, frameLiée2)
'Créer l'évènement frame_click avec les 3 paramètres précédents
End sub

Sub frame_onclick(frameQuiLanceL'evenement, frameLiée1, frameLiée2)
if frame1.bouton1 = true then 
   frameLiée1.Enabled = True
   frameLiée2.Enabled = False
else 
   frameLiée1.Enabled = False
   frameLiée2.Enabled = True
End if

End sub

Oui je sais je recherche un truc balaise, mais bon c'est en cherchant des trucs balaises qu'on arrive à faire des choses géniales

Bon je suis en train de m'en sortir avec des procédures paramétrées et des classes avec seulement un élément.

Bref voilà ce que ça donne pour le moment, c'est un peu compliqué à expliquer en détails, donc en gros pour ceux que ça intéresse:

Grâce à un système de nommage des frames, une procédure permet de déterminer quelles frames doivent être affichées et quelles frames masquées.

Ainsi les frames sont nommées de la manière suivante:

- Q1 (frame contenant la première question)

Dim Q1 As MSForms.Frame
Set Q1 = Me.Controls.Add("Forms.Frame.1", "Q1", True)
framePossibilite Q1, "Question n°1", "Oui/Non"
  • Q1R1Q2 (frame qui doit apparaitre si la réponse 1 a été choisi pour la question 1)
  • Q1R1Q3 (frame qui doit apparaitre quelquesoit la réponse à la question 2, mais uniquement si la réponse 1 a été choisie pour la question 1)

Où framePossibilie est une procédure qui dimensionne, positionne, personnalise ma frame pour y mettre X boutons.

framePossibilite Q1, "Question n°1", "Oui/Non"

Cette procédure va créer une frame avec un bouton Oui et un bouton Non. Le bouton Oui sera appelé Q1R1 et le bouton non Q1R2 (automatiquement/dynamiquement)

A chacun de ces boutons est associé un évènement _onclick() qui appele ma procédure de "tri"

Cette procédure balaye toutes les frames et tous les boutons, et détermine en fonction des boutons cochés et des NOMS des frames lesquelles doivent être affichées/masquées.

Rechercher des sujets similaires à "controles dynamiques modules classe"