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 :

[XL-2007] Module de classe et KeyPress


Sujet :

Macros et VBA Excel

  1. #1
    Candidat au Club
    Homme Profil pro
    Projeteur batiment
    Inscrit en
    Octobre 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Projeteur batiment
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2014
    Messages : 3
    Points : 3
    Points
    3
    Par défaut [XL-2007] Module de classe et KeyPress
    Bonjour a tous,

    Ne trouvant pas de solution/explication a mon problème sur la plupart des forums consacré ou du moins une solution que j'arrive a exploité je me permet d'exposer ici mon cas.

    Basiquement, un UserForm avec une brouette de TextBox, certaine destiné a recevoir du texte d'autre du numérique (ensuite exploité par excel).
    Afin de contrôler la saisie dans ces TextBox l'idée m'est venue d'utiliser un module de classe ( au bout de la 30eme TextBox, je me suis lassé).
    J'ai pris l'option de gerer le contrôle de saisie dans un premier temps via le Keypress pour transformer le "." (clavier num) en "," car je me suis aperçu qu'il s’agissait de l'erreur principale de saisie (pour les autres contrôles : décimale, 2 virgule, négatif,.. on verra après).

    Voici

    Code du 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
     
    Option Explicit
     
     
    Private Sub UserForm_Initialize()
    Dim TNumBox() As New ClassNumBox
    Dim ctrl As Control
    Dim T As Integer
     
    For Each ctrl In Me.Controls
         If TypeOf ctrl Is MSForms.TextBox Then
     
            Select Case ctrl.Tag
                Case Is = "1"
                    T = T + 1
                    ReDim Preserve TNumBox(1 To T)
                    Set TNumBox(T).NumBox = ctrl
            End Select
     
        End If
    Next ctrl
     
    End Sub
    Avec le module de classe ClassNumBox:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Public WithEvents NumBox As MSForms.TextBox
     
    Private Sub NumBox_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    If KeyAscii = 46 Then KeyAscii = 44
    End Sub
    dans l'idée, les textBox avec le tag "1" doivent être numérique, les autres non (je garde sous le coude différent type de numérique avec la modification du tag)

    Bon, et du coup... ça marche pas.

    Si quelqu'un pouvais me donner une piste de réflexion pour trouver mon erreur...

    Merci par avance

  2. #2
    Expert éminent
    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
    Points : 6 871
    Points
    6 871
    Par défaut
    Bonsoir,

    Il te faut juste déclarer ta variable en tête de module :
    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
     
    Dim TNumBox() As New ClassNumBox
     
    Private Sub UserForm_Initialize()
     
        Dim ctrl As Control
        Dim T As Integer
     
        For Each ctrl In Me.Controls
     
             If TypeOf ctrl Is MSForms.TextBox Then
     
                Select Case ctrl.Tag
     
                    Case Is = "1"
                        T = T + 1
                        ReDim Preserve TNumBox(1 To T)
                        Set TNumBox(T).NumBox = ctrl
     
                End Select
     
            End If
     
        Next ctrl
     
    End Sub
    Hervé.

  3. #3
    Candidat au Club
    Homme Profil pro
    Projeteur batiment
    Inscrit en
    Octobre 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Projeteur batiment
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2014
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Merci beaucoup, cela fonctionne parfaitement maintenant.

    par contre, pourrai tu m'expliquer pourquoi cette obligation pour cette variable?

  4. #4
    Invité
    Invité(e)
    Par défaut
    Salut,

    En reprenant le code de Theze (merci ), je te propose une autre solution (très légèrement plus lourde) qui permet de déporter l'évènement KeyPress au sein du UserForm, de sorte que le code de la classe soit générique (commun) et que le code de l'évenènement puisse être modifier de manière indépendante (le code de la classe est commun à tous les Userforms par exemple si plusieurs Userforms) de la classe etc...

    UserForm1:
    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
    31
    32
    33
    34
    35
     
    Dim TNumBox() As New ClassNumBox
    Dim WithEvents NumBoxEventHandler As ClassNumBox
     
    Private Sub NumBoxEventHandler_KeyPress(TextBox As MSForms.TextBox, KeyAscii As MSForms.ReturnInteger)
        MsgBox TextBox.Name
        If KeyAscii = 46 Then KeyAscii = 44
    End Sub
     
    Private Sub UserForm_Initialize()
     
        Dim ctrl As Control
        Dim T As Integer
     
        Set NumBoxEventHandler = New ClassNumBox
     
        For Each ctrl In Me.Controls
     
             If TypeOf ctrl Is MSForms.TextBox Then
     
                Select Case ctrl.Tag
     
                    Case Is = "1"
                        T = T + 1
                        ReDim Preserve TNumBox(1 To T)
                        TNumBox(T).InitializeEventHandler EventHandler:=NumBoxEventHandler
                        TNumBox(T).AddNumBoxEventHandler NumericBox:=ctrl
     
                End Select
     
            End If
     
        Next ctrl
     
    End Sub

    ClassNumBox:
    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
     
    Private WithEvents NumBox As MSForms.TextBox
    Private Caller As ClassNumBox
     
    Event KeyPress(TextBox As MSForms.TextBox, KeyAscii As MSForms.ReturnInteger)
     
     
    Public Sub InitializeEventHandler(EventHandler As ClassNumBox)
        If Not EventHandler Is Nothing Then
            If Caller Is Nothing Then
                Set Caller = EventHandler
            End If
        End If
    End Sub
     
    Public Sub AddNumBoxEventHandler(NumericBox As MSForms.TextBox)
        If Not NumericBox Is Nothing Then
            If NumBox Is Nothing Then
                Set NumBox = NumericBox
            End If
        End If
    End Sub
     
    Friend Sub OnKeyPress(TextBox As MSForms.TextBox, KeyAscii As MSForms.ReturnInteger)
        RaiseEvent KeyPress(TextBox, KeyAscii)
    End Sub
     
    Private Sub NumBox_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
        Call Caller.OnKeyPress(NumBox, KeyAscii)
    End Sub

    -------------------------------------------------------------------------

    EDIT : Version2 (Plus simple encore):

    ClassNumBox:
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    Private WithEvents NumBox As MSForms.TextBox
    Private Caller As ClassNumBox
     
    Event KeyPress(TextBox As MSForms.TextBox, KeyAscii As MSForms.ReturnInteger)
     
     
    'Public Sub InitializeEventHandler(EventHandler As ClassNumBox)
    '    If Not EventHandler Is Nothing Then
    '        If Caller Is Nothing Then
    '            Set Caller = EventHandler
    '        End If
    '    End If
    'End Sub
    Public Sub InitializeAndAddEventHandler(EventHandler As ClassNumBox, NumericBox As MSForms.TextBox)
        If Not EventHandler Is Nothing And Not NumericBox Is Nothing Then
            If Caller Is Nothing Then
                Set Caller = EventHandler
            End If
            If NumBox Is Nothing Then
                Set NumBox = NumericBox
            End If
        End If
    End Sub
    'Public Sub AddNumBoxEventHandler(NumericBox As MSForms.TextBox)
    '    If Not NumericBox Is Nothing Then
    '        If NumBox Is Nothing Then
    '            Set NumBox = NumericBox
    '        End If
    '    End If
    'End Sub
     
    Friend Sub OnKeyPress(TextBox As MSForms.TextBox, KeyAscii As MSForms.ReturnInteger)
        RaiseEvent KeyPress(TextBox, KeyAscii)
    End Sub
     
    Private Sub NumBox_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
        Call Caller.OnKeyPress(NumBox, KeyAscii)
    End Sub
    UserForm1:
    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
    31
    32
    33
    34
    35
    36
    37
    38
     
    Dim TNumBox() As New ClassNumBox
    Dim WithEvents NumBoxEventHandler As ClassNumBox
     
    Private Sub NumBoxEventHandler_KeyPress(TextBox As MSForms.TextBox, KeyAscii As MSForms.ReturnInteger)
        MsgBox TextBox.Name
        If KeyAscii = 46 Then KeyAscii = 44
    End Sub
     
    Private Sub UserForm_Initialize()
     
        Dim ctrl As Control
        Dim T As Integer
     
        Set NumBoxEventHandler = New ClassNumBox
     
        For Each ctrl In Me.Controls
     
             If TypeOf ctrl Is MSForms.TextBox Then
     
                Select Case ctrl.Tag
     
                    Case Is = "1"
                        T = T + 1
                        ReDim Preserve TNumBox(1 To T)
                        TNumBox(T).InitializeAndAddEventHandler _
                                EventHandler:=NumBoxEventHandler, _
                                NumericBox:=ctrl
                        'TNumBox(T).InitializeEventHandler EventHandler:=NumBoxEventHandler
                        'TNumBox(T).AddNumBoxEventHandler NumericBox:=ctrl
     
                End Select
     
            End If
     
        Next ctrl
     
    End Sub
    Dernière modification par Invité ; 01/10/2014 à 21h26.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Mise à jour Ultime:

    Le code est plus stricte parce que l'appel à la méthode OnKeyPress ne devrai pas être accessible de l'extérieur normalement, donc ici, on va passer par l'implémentation d'une classe abstraite et non instanciable au sein de la classe ClassNumBox. OnKeyPress est Private de la sorte.
    Tout ce qui doit être privée est maintenant privée et tout ce qui doit être Public est Public et contrôlable via des Méthodes (ce qui n'est pas le cas avec des champs Public).


    ClassNumBox
    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
     
    Implements IClassNumBoxEvents
     
    Private WithEvents NumBox As MSForms.TextBox
    Private Caller As IClassNumBoxEvents
     
    Event KeyPress(TextBox As MSForms.TextBox, KeyAscii As MSForms.ReturnInteger)
     
     
    Public Sub InitializeAndAddEventHandler(EventHandler As ClassNumBox, NumericBox As MSForms.TextBox)
        If Not EventHandler Is Nothing And Not NumericBox Is Nothing Then
            If Caller Is Nothing Then
                Set Caller = EventHandler
            End If
            If NumBox Is Nothing Then
                Set NumBox = NumericBox
            End If
        End If
    End Sub
     
     
    Private Sub IClassNumBoxEvents_OnKeyPress(TextBox As MSForms.IMdcText, KeyAscii As MSForms.IReturnInteger)
        RaiseEvent KeyPress(TextBox, KeyAscii)
    End Sub
     
    Private Sub NumBox_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
        Call Caller.OnKeyPress(NumBox, KeyAscii)
    End Sub

    IClassNumBoxEvents
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Private Sub Class_Initialize()
        Const E_NOTIMPL = &H80004001
        Err.Raise E_NOTIMPL
    End Sub
     
    Public Sub OnKeyPress(TextBox As MSForms.TextBox, KeyAscii As MSForms.ReturnInteger)
    End Sub

    Le code du UserForm ne change pas.

  6. #6
    Expert éminent
    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
    Points : 6 871
    Points
    6 871
    Par défaut
    Bonjour,

    par contre, pourrai tu m'expliquer pourquoi cette obligation pour cette variable?
    Tout simplement pour que sa durée de vie soit égale au temps d'ouverture de la Form. Si tu la laisse dans la proc "UserForm_Initialize", une fois cette dernière exécutée la variable est détruite, si elle est en tête du module elle sera détruite une fois que tu ferme la Form.

    Hervé.

  7. #7
    Candidat au Club
    Homme Profil pro
    Projeteur batiment
    Inscrit en
    Octobre 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Projeteur batiment
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2014
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    @ THEZE
    Merci de cette explication qui, à tête reposée, semble tellement logique qu'une envie de me flageller commence à faire son chemin ^^

    @Nouveau2
    En toute honnêteté, ton idée me semble très intéressante (même si j'avoue ne pas avoir tout compris dans ton code) mais me semble un peu trop évoluée pour mes besoins.
    Et comme je ne suis pas fan du "pompage" sans comprendre je prendrai le temps de l'analyser en détail.

    En tous les cas, merci a vos réponses!
    Bonne journée

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

Discussions similaires

  1. [VBA] Module de classe et évènement
    Par Caroline1 dans le forum Access
    Réponses: 9
    Dernier message: 20/03/2013, 23h23
  2. [Module de classe] Fonction non liée à l'instance?
    Par Caroline1 dans le forum Access
    Réponses: 6
    Dernier message: 07/04/2006, 20h13
  3. Réponses: 4
    Dernier message: 31/03/2006, 15h16
  4. Réponses: 8
    Dernier message: 22/02/2006, 15h09
  5. variables publiques ou module de classe ?
    Par niclalex dans le forum Access
    Réponses: 3
    Dernier message: 04/10/2005, 18h49

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