VBA - Ajouter un évènement à un controle dynamique

Salut le forum,

Je suis en train d'avancer dans mon fichier d’apprentissage du japonais, et je me heurte à un petit problème.

Ce que je veux faire:

un écran de sélection sur lequel tous les hiragana apparaissent. L'utilisateur choisi ce qu'il veut réviser en cliquant sur le frame correspondant (sélection multiple possible)

J'ai donc créé un module de classe pour faire tout le boulot (en regardant le fichier, vous verrez que le formulaire est VIDE).

Pour chaque série (les hiragana peuvent être rassemblés par séries, la série des GA, SA, NA, PA, BA etc...) je crée grâce à un module de classe un cadre pour chaque série, je le dimensionne etc (partie graphique)

Pour afficher les caractères, j'utilise des labels créés dynamiquement.

Mon problème est là, je veux pouvoir écrire un code de ce type:

Dim unLabel as MSForms.Label
set unLabel = maFrame.Controls.Add("Forms.Label.1")
unLabel.onclick = "procedure de mon module de classe"

et je poste parce que je n'y arrive pas

Où regarder dans le code:

module de classe "classeFrameV2"

procédure où sont créés dynamiquement les labels: "initialiserFrame"

procédure que je veux appeler lors de l'évènement "onclick" de mes labels: "frameSerie_Click"

Actuellement, lorsque l'on clique sur un frame (en dehors de la position des labels), le fond passe au vert. J'aimerai avoir le même chose lorsque l'utilisateur clique sur les labels !! (et sans passer par un autre module de classe si possible !!!!)

Si quelqu'un a une idée, je prend!

63japonais.xlsm (49.11 Ko)

Bonsoir

Vous utiliser les frames pour contenir les petits labels

Ils se comportent comme si ils sont sur le même plan (une seul surface) veut dire lorsque vous déplacer le curseur sur une des labels le clique est pratiquer sur label et quand vous déplacer le curseur sur une des frames principales le cliquer est pratique sur le frame principale et vous avez inséré un code qui réagir que avec le clique sur frame

J ai essayé de mettre les labels en arrière plan mais il me semble impossible « question de défaillance d Excel »

Donc je pense que vous avez deux choix :

1 -Appeler le code par chaque clique de souris label et frames

2- changer les frames par des labels et la vous serai capable de les mettre en premier plan pour appeler le code sans code supplémentaire (il me semble pratique)


AJOUT :

Pour le deuxième choix mettez les labels principaux (qui vont contenir les autres petits labels) en transparent « fmBackStyleSransparent »

Pour le deuxième choix mettez les labels principaux (qui vont contenir les autres petits labels) en transparent « fmBackStyleSransparent » et comme ca les autres petits labels vont apparaitre mais ils seront derrière plan

Bonjour AMIR et merci pour ta réponse,

AMIR a écrit :

Ils se comportent comme si ils sont sur le même plan (une seul surface) veut dire lorsque vous déplacer le curseur sur une des labels le clique est pratiquer sur label et quand vous déplacer le curseur sur une des frames principales le cliquer est pratique sur le frame principale et vous avez inséré un code qui réagir que avec le clique sur frame

C'est tout à fait ça, et c'est précisément cette partie que je veux modifier (clique sur frame -> clique sur frame + clique sur labels)
AMIR a écrit :

1 -Appeler le code par chaque clique de souris label et frames

Tu as résumé ma question dans cette phrase =) C'est ça que je souhaite faire, mais je ne sais pas comment.

Dans chaque frame, je dispose de 15 labels. Le problème, c'est qu'un module de classe n'accepte PAS cette déclaration

Public WithEvents listeLabels() as MSForms.Label 'code incorrete

Je ne vois donc pas comment personnaliser l'évènement "onclick" de mes labels (l'objectif étant simplement de lier l'évènement "onclick" de mes 15 labels à l'évènement "onclick" de ma frame contenante)

PS: pour ta solution 2, tu proposes de mettre tous les labels avec du contenu en "arrière plan", et un gros label devant qui capturera le "onclick"? Ça résoud à 80% le problème, car là je n'ai qu'une variable à ajouter à mon module de classe en private (et plus 15 comme tout à l'heure). Je vais me pencher sur cette solution qui fonctionnera très certainement, mais j'aimerais vraiment avoir une solution pour la première proposition!

Bonjour d3d9x,

Heureux de se retrouver pour le formulaire japonais !

Ci-joint une proposition à tester.

Avec un nouveau module de classe (très simple) et juste quelques lignes de codes ajoutées.

Bonne soirée

Bouben

122japonais-v0-1.xlsm (45.79 Ko)

Salut bouben et merci de ta réponse!

Oui j'avais promis de poster

Ta solution fonctionne parfaitement, mais je ne l'avais pas mise en pratique car je ne voulais pas rajouter un module de classe uniquement pour mes labels.

De plus avec cette méthode, je ne peux plus lier l’événement "onclick" de ces labels (qui est dans ton module de classe) avec l’événement "onclick" de ma frame (qui est dans mon module de classe). Voilà pourquoi je voulais une solution alternative =)

BONJOUR

Peut vous donne une idée

vous avez déclaré Public :

Public WithEvents frameSerie As MSForms.Frame

Et j ai ajouté (Public) pour :

Public WithEvents label1 As MSForms.Label
Public WithEvents label2 As MSForms.Label
Public WithEvents label3 As MSForms.Label 

Et j ai supprimé la même déclaration au sein de procédure « Public Sub initialiserFrame »

' JE VEUX AJOUTER UN EVENEMENT ONCLICK A CES LABELS (dans la boucle)
'Dim label1 As MSForms.Label
'Dim label2 As MSForms.Label
'Dim label3 As MSForms.Label

Puis :

Private Sub frameSerie_Click()
    frameSerie.BackColor = vbGreen
End Sub
Private Sub Label1_Click()
    frameSerie.BackColor = vbGreen
End Sub
Private Sub Label2_Click()
 frameSerie.BackColor = vbGreen
End Sub
Private Sub Label3_Click()
    frameSerie.BackColor = vbGreen
End Sub

Mais ca a marche seulement pour les labels qui sont en bas de chaque frame

(A cause de boucle ou autre chose je ne sais pas). Peut vous donne une idée

Dit moi la deuxième solution n est pas pratique comme j ai pensé !?

Les cartes sont elles déplaçables ?

Bonjour AMIR,

Cette proposition:

Public WithEvents label1 As MSForms.Label
Public WithEvents label2 As MSForms.Label
Public WithEvents label3 As MSForms.Label 

conviendrait parfaitement si je n'avais que 3 labels, sauf que dans mon cas j'en ai 15 par frame!!

Il faudrait donc

Public WithEvents label1 As MSForms.Label
Public WithEvents label2 As MSForms.Label
....
Public WithEvents label15 As MSForms.Label

ce qui est loin d'être une belle façon de coder, d'où ma recherche d'un

Public WithEvents listeLabels() As MSForms.Label

ou d'une autre méthode pour personnaliser l'évènement "onclick" de mes labels sans passer par un nouveau module de classe =)

Si j'ai 15 labels dans 15 variables séparées, je dois personnaliser 15 fois le même code .... et si je veux l'éditer, j'ai 15 déclarations et 15 événements à personnaliser!!

capture

1 cadre = 15 labels (seulements 10 sont visibles en même temps). Chaque label est en fond jaune.

bonsoir

SVP regarder ca je pense qu’il vous convient parfaitement :

74japonais-6.xlsm (38.04 Ko)

pour les frame SVP reactiver

'Private Sub frameSerie_Click()
  '  frameSerie.BackColor = vbGreen
'End Sub

Malgré que les labels sont serres sur les frames mais il arrive que le clique survient sur un frame ce qu’il montre moins de performance

Je te remercie du temps que tu me consacres AMIR, malheureusement il y a un point qui n'est pas respecté:

et sans passer par un autre module de classe si possible !!!!

Je sais me servir des modules de classes, les solutions proposées sont des solutions que je connais (et que j'utilise déjà comme tu as pu le constater).

A travers ce post, je suis à la recherche d'une solution que je ne connais pas, et qui me permettrait à l'intérieur d'un module de classe(donc sans rajouter de nouveau module de classe), de stocker un grand nombre de "controls" et leurs événements sans passer par 36 variables, ou rajouter dans mon formulaire un autre tableau de stockage!

Pourquoi je ne cherche pas de solution avec un autre module de classe? parce qu'il me suffirait d'en faire un avec:

Dim parentFrame as MSControls.Frame
Set = monLabel.parent
parentFrame.click

et le problème serait résolu. C'est bien beau pour un petit projet, mais pour un gros projet, si à chaque type de control et chaque personnalisation il faut ajouter un module de classe, c'est inutilisable!

Pour le moment ta première proposition (l'utilisation d'un label par dessus tous les autres) est une solution qui résout mon problème, mais qui ne solutionne pas ma recherche. Une autre solution n'existe peut être pas, mais j'aimerai être sûr de ne pas passer à côté si elle existe =)

J'ai essayé de mettre en avant ces points dans ma demande initiale, mais apparemment je n'ai pas été assez clair et je m'en excuse si c'est le cas.

Donc voilà le problème tourné différemment:

J'ai 750 labels et 750 textbox dans mon module de classe (créés dynamiquement)

Je veux pouvoir ajouter/modifier des événements à ces éléments SANS ajouter de tableau de stockage à l'extérieur de mon module de classe, et SANS ajouter d'autre module de classe. Bref tout le code doit être DANS mon module de classe.

BONSOIR

SVP essayer ca :

Je pense qu’il ne s agit pas d un nouvel tableau

Alor vous n’auriez qu’un nombre limité de control à déclarer :

Public WithEvents frames As MSForms.Frame
‘………………………………………………………………………
‘ Ops pas de control à déclarer

Ensuite vous n’auriez qu’un nombre limité d’événements à déclarer :

Private Sub labels_Click()
PrintControlName
End Sub
‘………………………………
‘ Ops pas de control à déclarer

Vous pouvez utiliser a l intérieure de usform :

MsgBox listeFrames(7, 1).m_PassedControl.Name 'color , visible .....
MsgBox listeFrames(2, 3).m_PassedControl.Name 'color , visible .....
‘……………………………………………………………………………………………………….

Moi je ne comprends pas s’il s’agit de jeu japonais ou carte japonais ou comment se déroule C est pourquoi je vous ai demandé ses les cartes sont déplaçable ou non et si chaque label a un comportement spéciale déférent a l autre (couleur,…), seulement si je peux savoir si vous avez réalisé quelques progression sur la deuxième solution (arrière plan et premier plan) je veux vous propose une autre idee pour la deuxième solution (arrière plan et premier plan) .

32japonais-7-4.xlsm (52.70 Ko)

Bonjour AMIR,

L'objectif final de mon fichier est un fichier d'apprentissage du japonais par le biais de petits tests.

La partie que j'ai partagé et la partie "sélection des caractères à réviser"

Etant donné qu'on peut décomposer les symboles japonais par catégorie (sonorité en Ka, Ga, Na etc...) l'utilisateur doit pouvoir choisir la ou les catégories qu'il souhaite réviser (chaque catégorie étant stockée à l'intérieur d'une frame).

Après avoir choisi ses catégories, le programme génèrera un test de révision avec tous les symboles retenus par l'utilisateur.

Voilà pourquoi je souhaitais lier l'évènement "onclick" de mes labels à l'évènement "onclick" de ma frame. Aucun élément n'a donc vocation à être déplacé.

Concernant cette demande, elle est indirectement réglée grâce à ta première proposition qui me convient(l'utilisation d'un label qui remplie la totalité de la frame et placé au premier plan)

La question qui ne l'est pas est:

est-il possible de stocker un tableau de controls avec des évènements personnalisés à l'intérieur d'un module de classe, sans passer par un tableau à l'extérieur de mon module de classe, et sans autre module de classe. J'aimerai que l'ensemble des événements personnalisés soient dans un seul et unique module de classe.

Cette question est beaucoup plus générale que la requête concernant mon fichier d'apprentissage. car je travaille de plus en plus avec des modules de classe, et je ne veux pas avoir un module de classe par événement personnalisé!!!

BONSOIR d3d9x

est-il possible de stocker un tableau de controls avec des évènements personnalisés à l'intérieur d'un module de classe, sans passer par un tableau à l'extérieur de mon module de classe, et sans autre module de classe. J'aimerai que l'ensemble des événements personnalisés soient dans un seul et unique module de classe.

Je n ai pas encore compris

Mais MERCI, je suis débutant et j ai appris plusieurs chose sur les modules de classes

Bon chance

Je suis ravi que ce post t'ai permis d'apprendre des choses sur les modules de classe, et je te remercie de ta participer =)

Bonjour,

Pour commencer, merci beaucoup à tous les deux pour cette conversation qui m'a permis d'en apprendre davantage sur 1/ les modules de classes et 2/ sur les contrôles d'événements dans Excel.

Il se trouve que ce post tombe à point nommé au moment où j'en ai besoin, et où j'étais sur le point de baisser les bras. En effet, on ne trouve nulle part sur les forums d'information sur la gestion d'événements dans les UserForms dynamiques ; et dans l'application que je suis en train de monter (une optimisation de répartition de charge dans un planning), j'ai utilisé des moyens détournés pour accéder à mes fins : un contrôle des valeurs a posteriori, à partir de contrôles inscrits "dans le dur" dans le formulaire, qui me permettent de mettre du code derrière. De ce point de vue, ce post est une innovation en soi.

En revanche, après quelques tests sommaires sur la base du programme d'apprentissage du japonais de d3d9x, je ne parviens toujours pas à adresser le contrôle sur lequel j'ai cliqué. J'ai bien identifié le contrôle m_PassedControl dans la classeFrameV2 mais toutes mes tentatives me renvoient un objet vide (j'ai tenté d'afficher la m_PassedControl.Value du contrôle depuis PrintControlName, ce qui plante ; et le TypeName me renvoie Nothing...)

Il y a donc sans doute une finesse qui m'échappe encore.

Mon but : déclarer un ensemble de contrôles constituant une ligne (avec des textbox, combobox, checkbox... interagissant les uns avec les autres quand l'état ou la valeur de ceux-ci changent...). Et donc pour cela, je dois récupérer le nom et la référence du contrôle qui a changé d'état ou de valeur.

Si vous avez une idée, ce serait formidable !

En tout cas merci encore à tous les deux pour ce cours express...

... et pour d3d9x : どうもありがとうございました !!!

laudgut

Rechercher des sujets similaires à "vba ajouter evenement controle dynamique"