IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Générer un événement dans un module de classe


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    3 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 3 453
    Par défaut Générer un événement dans un module de classe
    Bonjour tout le monde,

    Voici le code dans mon UserForm :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    Dim Txt() As New Classe1
    Private WithEvents Cls As Classe1
     
    Private Sub UserForm_Initialize()
     
        Dim Ctrl As Control
        Dim I As Integer
     
        Set Cls = New Classe1
     
        For Each Ctrl In Me.Controls
     
            If TypeName(Ctrl) = "TextBox" Then
     
                I = I + 1
                ReDim Preserve Txt(1 To I)
                Set Txt(I).GroupeTxt = Ctrl
     
            End If
     
        Next Ctrl
     
    End Sub
     
    Private Sub Cls_ValeurChange(Valeur As String)
     
        Label1.Caption = Valeur
     
    End Sub
    Le code dans le module de classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Public WithEvents GroupeTxt As MSForms.TextBox
    Public Event ValeurChange(Valeur As String)
     
    Private Sub GroupeTxt_Change()
     
        RaiseEvent ValeurChange(GroupeTxt.Text)
     
    End Sub
    Au changement de la valeur dans un des TextBox, on arrive bien dans "GroupeTxt_Change()" mais l'événement "ValeurChange()" n'est pas généré donc je pense que c'est parce que l'événement "GroupeTxt_Change()" n'est pas terminé qu'il ne produit pas "ValeurChange()" savez-vous si il est possible de contourner cela ?

    Bonne journée à vous toutes et tous !

  2. #2
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    Bonjour These
    je ne sais pas si cela est possible en fait je m'y suis jamais intéréssé de cette maniere
    d'autant plus que meme si c'est possible( ce dont je doute) tu ne peut pas gérer l'evenement valeur change dans une seule instance car a chaque textbox l'evenement change du textbox est propre a son instance de la classe ( 10 textbox =10 instancle de la classe donc 10 evenement change )

    cela dit créer une classe pour gérer l'evenement change dans le userform me parait inutile
    voila comment je vois les choses je te propose de faire harchi simple 2 solutions hypersimples
    met ceci dans ton userform dans le initialyse ou activate comme tu veux selon tes besoins
    solutionN1°
    code userform:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Option Explicit
    Dim cl As New Classe1
    Private Sub UserForm_Initialize()
     cl.initTexTbox Me
    End Sub
    pas tres compliqué

    code classe1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    Public WithEvents GroupeTxt As MSForms.TextBox
    Public usf As Object
    Dim TXT() As New Classe1
    Function initTexTbox(uf)
        For Each Ctrl In uf.Controls
            If TypeName(Ctrl) = "TextBox" Then
                I = I + 1
                ReDim Preserve TXT(1 To I)
                 Set TXT(I).GroupeTxt = Ctrl
                 'on integre le userform dans chaque instance de la classe pour y acceder en tant qu'object (attention!!!!! pas ses evenement car de cette maniere les evenement userform  sont inaccessible)
            Set TXT(I).usf = uf
            End If
        Next
    End Function
    Private Sub GroupeTxt_Change()
        'on accede au label par le usf car usf est intégré dans chaque instance de la classe pour chaque textboxs
        usf.Controls("Label1").Caption = GroupeTxt.Text
    End Sub
    pas tres compliqué non plus

    solutionN°2

    ici on va intégrer le label dans la classe et non le userform
    code userform:
    pour le userform on change absolument rien c'est la meme chose

    code classe1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    Public WithEvents GroupeTxt As MSForms.TextBox
    Public WithEvents labelo As MSForms.Label
    Dim TXT() As New Classe1
    Function initTexTbox(uf)
        For Each Ctrl In uf.Controls
            If TypeName(Ctrl) = "TextBox" Then
                I = I + 1
                ReDim Preserve TXT(1 To I)
                 Set TXT(I).GroupeTxt = Ctrl
                 'on integre le label1 dans chaque instance de la classe pour y acceder en tant qu'object et !!!! ses evenement meme si on s'en servira pas 
                 Set TXT(I).labelo=uf.controls("Label1")
     End If
        Next
    End Function
    Private Sub GroupeTxt_Change()
        'labelo a été integré dans chanque instance de la classe pour les textbox il est donc reconnus  dans les evenement change de tout les  textbox 
        labelo.Caption = GroupeTxt.Text
    End Sub
    voila comme dit le pitchooun chez renault "c'est simple"

    tu a null besoins de creer un evenement sur une variable si tant est que cela soit possible
    tu aura constaté aussi que je libere le userform de tout code d'instanciation de classe sauf une de depart pour l'appel d'amorcage
    je peus dire aussi que j'aurais pu intégrer le label de la meme maniere que j'integre le userform dans la solution 1
    A+

    Nom : demo2.gif
Affichages : 2048
Taille : 86,7 Ko
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  3. #3
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    3 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 3 453
    Par défaut
    Bonjour Patrick,

    la solution est intéressante et je vais creuser mais avec ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Private Sub GroupeTxt_Change()
        'on accede au label par le usf car usf est intégré dans chaque instance de la classe pour chaque textboxs
        usf.Controls("Label1").Caption = GroupeTxt.Text
     
    End Sub
    La classe étant encapsulée, le risque de plantage est trop important car depuis la classe, tu n'est pas sensé connaître le nom des contrôles.
    L'initialisation doit être faite dans l'UserForm et non dans la classe mais l'idée me semble bonne et je vais creuser en tout cas, je te remercie et te souhaite une bonne journée.

  4. #4
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    re
    La classe étant encapsulée, le risque de plantage est trop important car depuis la classe, tu n'est pas sensé connaître le nom des contrôles.
    et pourquoi ca???
    dans ton exemple tu dirige toujours la valeurchange dans la caption du Label1 pourquoi pas dans la classe????????rien ne t'en empeche surtout que Label1 recois tout les changements de tout les textboxs

    risque de plantage ou???
    si plantage dans la classe il y a ;plantage dans le userform il y aura aussi
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  5. #5
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    3 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 3 453
    Par défaut
    dans l'UserForm tu passes la valeur sur l'événement Change() des TextBox ("GroupeTxt_Change()") et la Classe génère l'événement "ValeurChange()" dans la foulée (enfin, c'est ce que j'espérais ) en faisant suivre la valeur entrée dans le TextBox donc, aucun risque de plantage (normalement) et c'est sur la récup de l'événement que tu passes la valeur au Label tu pourrait tout aussi bien l'attribuer à une variable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Private Sub Cls_ValeurChange(Valeur As String)
     
        Label1.Caption = Valeur
     
    End Sub
    Comme c'est juste pour voir ce qui est possible et je n'en ai pas besoin réellement, ce n'est pas capital !

  6. #6
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    oui mais perso je me mefie de raiseevent selon les versions office
    ton label1 peut tres bien etre intégré dans ta classe(solutionN°2) pas besoins de creer un evenement en plus

    au pire!!! tu garde ton evenement dans ton userform et tu le run a partir de l'evenement textbox substitué dans la classe mais perso pour moi c'est du code et de la grignotte memoire pour rien
    A mediter
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  7. #7
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Code Classe1 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     Public WithEvents GroupeTxt As MSForms.TextBox
    Public Event ValeurChange(Valeur As String)
     
    Private Sub GroupeTxt_Change()
         UserForm1.ValeurChange (GroupeTxt.Text)
    End Sub
    Code UserForm1 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     Dim Txt() As New Classe1
    Private WithEvents Cls As Classe1
     
    Private Sub UserForm_Initialize()
     
        Dim Ctrl As Control
        Dim I As Integer
     
        Set Cls = New Classe1
     
        For Each Ctrl In Me.Controls
     
            If TypeName(Ctrl) = "TextBox" Then
     
                I = I + 1
                ReDim Preserve Txt(1 To I)
                Set Txt(I).GroupeTxt = Ctrl
     
            End If
     
        Next Ctrl
     
    End Sub
     
    Public Sub ValeurChange(Valeur As String)
     
        Label1.Caption = Valeur
     
    End Sub

  8. #8
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    3 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 3 453
    Par défaut
    Bonjour Robert,

    Dans ce cas là, l'événement n'est pas généré par la classe mais cette dernière appelle un procédure située dans l'UserForm donc, pas d'encapsulage puisque la classe appelle un objet extérieur qui peut ne pas exister et là, plantage !

    Merci de t'être penché sur ma question !

    Bonne soirée

  9. #9
    Invité
    Invité(e)
    Par défaut
    Tu peux appeler le.parent de l'objet!

    L'objet existe forcement puisqu'il est construit dans UserForm_Initialize()


    GroupeTxt.parent.ValeurChange (GroupeTxt.Text)Que ce soit ma solution ou la tienne il faut bien que ça existe dans le UserForm?

    Private Sub Cls_ValeurChange(Valeur As String)


    Pour pouvoir gérer RaiseEvent il faudrait pouvoir indexer les événements si c'est possible en VB6 ça ne l'est pas en VBA!

    Du reste en VB6 les contrôles porteraient le même nom avec un index et possèderaient un événement commun avec passage d'index en paramètres!
    Dernière modification par Invité ; 20/03/2018 à 17h56.

  10. #10
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    je ne suis pas sur robert mais je crois que theze a raison
    ton model appelle la procedure dans le userform mais ne créé pas d'object dans la classe
    hors theze tient absolument qu'il y est un evenement créé dans la classe
    mais comme j'ai essayé de lui expliquer il faut qu'il integre ca dans chaque instance pour chaque textboxs
    oui mais la dans le userform ce ne serait plus cls.valeurchange_change()
    mais autant de sous classe .valeurchange_change() et la c'est ingerable sauf collection retourner dans une variable au userform ou en public

    en gros il y aurait eu 1 !! textbox nikel on integre et on peut continuer a gérer l'evenement de valeurchange dans le userform mais c'est pas le cas


    les evenement textbox qui sont dans les instances(x) de la classe ne connaissent pas "valeurchange"car elle est que dans l'instance "cls"
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  11. #11
    Invité
    Invité(e)
    Par défaut
    Bonjour Patrick,

    Oui tu as raisons mais que l'évènement change appel un RaiseEvent qui ne peut en aucun cas exister dans le UsersForm ou une procédure public du parent c'est pas la même chose!

    Dans mon exemple j'utilise le nom express du userform et pas le parent du texte box mais hormis cela mon code est à iso de l'original et il fonctionne.

    Si non pourquoi ne pas passer à l'instance de la classe le texbox et le label?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Public WithEvents GroupeTxt As MSForms.TextBox
    Public WithEvents GroupeLab As MSForms.Label
    Ce qui m'échappe c'est qu'un modules de classe bien utilisé nous facilite la vie, pourquoi en faite une usine à gaz?

    Dans class1 tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    For Each Ctrl In uf.Controls
    Pourquoi ne pas fait ca
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub GroupeTxt_Change()
         uf.ValeurChange (GroupeTxt.Text)
    End Sub
    Dernière modification par Invité ; 20/03/2018 à 20h08.

  12. #12
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    re
    @robert
    Si non pourquoi ne pas passer à l'instance de la classe le texbox et le label?
    Ce qui m'échappe c'est qu'un modules de classe bien utilisé nous facilite la vie, pourquoi en faite une usine à gaz?
    tout a fait d'accords avec toi c'est la solution N°2 que j'ai proposée plus haut

    mais je crois que these est dans une phase "mes petites experiences" et essaie simplement d'enrichir son savoir


    et comme je le comprends!!! je suis un peu pareil aussi quand j'ai quelque chose qui metitille le lobe frontal gauche je peut rester devant le PC 8 heures tant que j'ai pas trouvé


    je pense qu'il n'arrive pas bien encore a faire la distinction entre une classe et instance(s) de classe c'est la tout son probleme en ce qui concerne son histoire de raiseevent
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  13. #13
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    3 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 3 453
    Par défaut
    Bonjour les gars,

    mais je crois que these est dans une phase "mes petites experiences" et essaie simplement d'enrichir son savoir
    Tu as tout compris et merci à vous deux de vous être penchés sur ma question, je vous souhaite une bonne journée et je vais clore ce sujet

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VBA] Connexion permanente dans un module de classe
    Par cocobingo dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 14/01/2009, 13h54
  2. Setter dans un module de classe
    Par Mathusalem dans le forum Général VBA
    Réponses: 2
    Dernier message: 10/11/2008, 15h25
  3. [VBA] Collection dans un module de classe
    Par spaiku dans le forum VBA Access
    Réponses: 5
    Dernier message: 22/08/2008, 10h38
  4. erreur avec withevents dans un module de classe
    Par patbou dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 20/12/2007, 04h32
  5. Accesseur de collection dans un module de classe
    Par in dans le forum Général VBA
    Réponses: 4
    Dernier message: 17/08/2007, 18h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo