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 :

Comment accéder à plusieurs toggle button dans une frame ActiveX [XL-2010]


Sujet :

Macros et VBA Excel

  1. #1
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 5
    Points : 2
    Points
    2
    Par défaut Comment accéder à plusieurs toggle button dans une frame ActiveX
    Bonjour à tous et merci par avance pour l'aide que vous m'apportez.

    Evidemment, je suis un débutant...
    Je cherche à créer un groupe de contrôles ToggleButton mutuellement exclusifs dans une frame ActiveX sachant que je ne souhaite pas utiliser de Userform car je veux que mes éléments soient intégrés dans ma feuille de calcul.
    J'ai trouvé une réponse sur le site microsoft :
    http://support.microsoft.com/kb/166252

    Tout fonctionne à merveille mais uniquement avec un UserForm.
    Même si je suis sûr que la réponse est ultra simple, je bloque sur le code du module si je fais une frame ActiveX sans 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
    'Variable to hold name of ToggleButton that was clicked.
    Public Clicked As String
     
    Sub ExclusiveToggleButtons()
        Dim Toggle As Control
     
    'Loop through all of the ToggleButtons on Frame1
         For Each Toggle In UserForm1.Frame1.Controls
     
            'If Name of ToggleButton matches name of ToggleButton
               'that was clicked...  
                  If Toggle.Name = clicked Then   
                   '...select the button
                  Toggle.Value = True   
                  Else
                '...deselect the button
                  Toggle.Value = False   
                  End If   
             Next 
    End Sub
    En d'autres termes, je ne sais pas accéder à ma frame ActiveX qui n'est pas dans un Userform.

    Pouvez-vous m'aider ?
    De plus je ne sais pas où insérer ce bout de code. Toujours dans un module ?
    Et où insérer le code des event MouseUp des ToggleButton dans mon cas ?

    Merci !

  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
    Bonjour,

    Une piste, tu mets tes boutons bascule directement sur la feuille. Tu mes ce code dans un module standard :
    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
     
    Public Clicked As String
    Public Fe As Worksheet
     
    Sub ExclusiveToggleButtons()
     
        Dim Objet As OLEObject
        Dim Toggle As MSForms.ToggleButton
     
        'parcours les objets OLE
        For Each Objet In Fe.OLEObjects
     
            'évite l'erreur si le contrôle n'est pas
            'un bouton bascule
            On Error Resume Next
     
            'passe l'objet à la variable
            Set Toggle = Objet.Object
     
            'défini son état
            If Toggle.Name = Clicked Then
     
                Toggle.Value = True
     
            Else
     
                Toggle.Value = False
     
            End If
     
        Next Objet
     
    End Sub
    et ce code (celui de l'exemple du lien) dans le module de la feuille :
    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
     
    Private Sub ToggleButton1_MouseUp(ByVal Button As Integer, _
            ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
     
        Set Fe = Me
        Clicked = ToggleButton1.Name
        Application.OnTime Now, "ExclusiveToggleButtons"
     
    End Sub
     
    Private Sub ToggleButton2_MouseUp(ByVal Button As Integer, _
            ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
     
        Set Fe = Me
        Clicked = ToggleButton2.Name
        Application.OnTime Now, "ExclusiveToggleButtons"
     
    End Sub
     
     
    Private Sub ToggleButton3_MouseUp(ByVal Button As Integer, _
            ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
     
        Set Fe = Me
        Clicked = ToggleButton3.Name
        Application.OnTime Now, "ExclusiveToggleButtons"
     
    End Sub
    Je pense qu'il va te falloir te passer de Frame car apparemment, sur une feuille de calcul il n'est pas contenair ? A voir !!!

    Hervé.

  3. #3
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Merci pour cette réponse rapide Hervé.

    C'est effectivement une bonne première piste.
    La difficulté de cette méthode est la gestion de mes 264 boutons !
    Si je ne peux pas les regrouper en frames, je ne vais pas pouvoir m'y retrouver et le code va probablement être terrible.
    J'ai 6 parties dans ma feuille de calcul.
    Chaque partie contient 11 éléments et pour chaque élément, il y a 4 boutons...

    D'autres idées ?
    Dois-je me limiter à un UserForm ?

    Merci encore !
    David

  4. #4
    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
    Re,

    Vu le nombre de contrôles que tu veux utiliser, je pense qu'il serait mieux d'utiliser un UserForm mais à toi de voir.
    Je te poste un petit exemple pour un groupe de 11 x 4 contrôles (il t'en faut 6 de groupes !!!). J'ai utiliser un module de classe afin que les évènements soient communs à chaque bloc que forme 4 contrôles.
    Le chargement des contrôles dans les tableaux se fait sur l'évènement "Activate" de la feuille "Feuil1" donc, il suffit de sélectionner une autre feuille puis revenir sur "Feuil1" et tester

    Hervé.
    Fichiers attachés Fichiers attachés

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2009
    Messages : 652
    Points : 1 219
    Points
    1 219
    Par défaut
    Bonjour,

    Une piste avec l'exemple suivant qui construit dynamiquement des groupes d'OptionButton en fonction d'un questionnaire (situé ici en colonne A)
    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
    40
    41
    Dim Reponses As Variant
     
    Sub PlageDesQuestions()
    '### Du nombre de réponses dépend le nombre d'OptionButton
    '### Adapter le Array du variant ci-dessous en fonction des réponses
    Reponses = Array("Je n'aime pas", "J'aime un peu", "J'aime", "J'aime beaucoup")
    '###
     
    Dim C As Range
    If TypeName(Selection) <> "Range" Then Exit Sub
    If Selection.Columns.Count > 1 Then Exit Sub
     
    Application.ScreenUpdating = False
    For Each C In Selection
      Call MakeOptionButton(C, UBound(Reponses))
    Next C
    Application.ScreenUpdating = True
    End Sub
     
    Sub DeleteShapes()
    Dim SH As Shape
    For Each SH In ActiveSheet.Shapes
      SH.Delete
    Next SH
    End Sub
     
    Sub MakeOptionButton(CelluleQuestion As Range, NombreOptionButton As Long)
    Dim R As Range
    Dim i&
    Dim OL As OLEObject
    Dim OB As MSForms.OptionButton
    '---
    For i& = 0 To NombreOptionButton
      Set R = CelluleQuestion.Offset(0, i& + 1)
      Set OL = ActiveSheet.OLEObjects.Add(ClassType:="Forms.OptionButton.1", Link:=False, DisplayAsIcon:=False, _
        Left:=R.Left, Top:=R.Top, Width:=R.Width, Height:=R.Height)
      Set OB = OL.Object
      OB.Caption = Reponses(i&)
      OB.GroupName = CelluleQuestion
    Next i&
    End Sub
    Je mets l'exemple en pièce jointe pour plus de facilité.

  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,

    Une autre piste et bien plus légère en terme de poids et de code.
    Utiliser une fonte qui permet d'afficher une coche dans la cellule (fonte Webdings) sur laquelle on viens de cliquer tout en vidant les autres cellules de la même ligne (exclusivité). Je te poste un autre classeur pour que tu puisse tester.

    Hervé.
    Fichiers attachés Fichiers attachés

  7. #7
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Bonjour à tous,

    merci à tous pour ces pistes de résolution, toutes aussi intéressantes les unes que les autres.
    Je vois aussi qu'il ne semble pas exister de solution simple d'intégrer mes toggle buttons dans des frames Active X

    Il me faut donc m'adapter pour trouver une réponse alternative à mon besoin. Et vous me donnez de nombreuses pistes pour ça !


    J'ai donc du pain sur la planche...

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2009
    Messages : 652
    Points : 1 219
    Points
    1 219
    Par défaut
    Je vois aussi qu'il ne semble pas exister de solution simple d'intégrer mes toggle buttons dans des frames Active X
    Aïe !
    J'ai confondu ToggleButton et OptionButton.
    Je pense que, dans la logique MicroSoft, la faisabilité de construire des ToggleButton est la même que celle des OptionButton. Je regarde prochainement.
    Bonne soirée et à plus.

  9. #9
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    rebonjour,

    je viens de trouver ceci qui démontre que mon objectif initial ne pouura être atteint :
    Ok, that explains it. A frame control is what's called a container control.
    This means it's capable of hosting other ActiveX controls in the same way that a
    UserForm or a Worksheet can. When you place a container control that is
    currently hosting ActiveX controls (like your Frame control and its option
    buttons) inside another container control (your worksheet), the second container
    control must support a set of interfaces required for the first container
    control to relay information about the objects it contains.
    Unfortunately, the Worksheet object lacks those interfaces. So while you can
    place a Frame control on a Worksheet, no ActiveX controls that you place inside
    that Frame control will be visible to the Worksheet object.
    You can create a pretty good approximation of the look of a frame control
    using the various shapes available on the drawing toolbar. I think that's
    probably the best workaround.

    la google traduction :
    Ok, ça explique tout. Un contrôle de trame est ce qu'on appelle un contrôle conteneur.
    Cela signifie qu'il est capable d'héberger d'autres contrôles ActiveX de la même manière qu'un
    UserForm ou une feuille de calcul possible. Lorsque vous placez un contrôle conteneur qui est
    Les contrôles ActiveX actuellement d'hébergement (comme votre contrôle Frame et son option
    boutons) à l'intérieur d'un autre contrôle conteneur (votre feuille de calcul), le second conteneur
    contrôle doit prendre en charge un ensemble d'interfaces requis pour le premier récipient
    contrôle de relayer l'information sur les objets qu'il contient.
    **** Malheureusement, l'objet feuille de manque de ces interfaces. Ainsi, alors que vous pouvez
    placer un contrôle Frame sur une feuille de calcul, pas de contrôles ActiveX que vous placez à l'intérieur
    qui contrôle Frame sera visible à l'objet feuille de calcul.
    **** Vous pouvez créer une assez bonne approximation de l'apparence d'un contrôle de trame
    en utilisant les différentes formes disponibles sur la barre d'outils de dessin. Je pense que c'est
    probablement la meilleure solution.
    Je considère donc le sujet clos et c'est maintenant à moi de trouver un choix alternatif satisfaisant !
    Merci à tous !

    David

  10. #10
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Theze Voir le message
    Bonjour,

    Une autre piste et bien plus légère en terme de poids et de code.
    Utiliser une fonte qui permet d'afficher une coche dans la cellule (fonte Webdings) sur laquelle on viens de cliquer tout en vidant les autres cellules de la même ligne (exclusivité). Je te poste un autre classeur pour que tu puisse tester.

    Hervé.
    Merci Hervé, ton alternative me paraît à la fois simple et répondre à l'objectif final !
    C'est juste génial d'avoir une telle expertise à portée de doigts !

    Bien cordialement,
    David

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2009
    Messages : 652
    Points : 1 219
    Points
    1 219
    Par défaut Création dynamique de pseudo groupes de ToggleButtons s'excluant mutuellement
    Bonjour,
    Je pense que, dans la logique MicroSoft, la faisabilité de construire des ToggleButton est la même que celle des OptionButton. Je regarde prochainement.
    Je suis arrivé à un résultat concluant mais cela a été difficultueux et la solution est plutôt tarabiscotée (j'ai été obligé de passer par un module de classe et n'ai pas réussi à faire plus simple). Pour le fun, je la fais paraître.
    Si cela n'est pas trop rébarbatif, vous pouvez atteindre le but initial que vous vous étiez fixé.

    1) copiez le code suivant dans un module standard
    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    Public myCollection As Collection
     
    Sub PlageDesQuestions()
    Dim Reponses As Variant
    '### Du nombre de réponses dépend le nombre de ToggleButton
    '### Adapter le Array du variant ci-dessous en fonction des réponses
    Reponses = Array("Je n'aime pas", "J'aime un peu", "J'aime", "J'aime beaucoup")
    '###
     
    Dim C As Range
    If TypeName(Selection) <> "Range" Then Exit Sub
    Application.ScreenUpdating = False
    Call DeleteToggle(AfficherResultats:=False)
    For Each C In Selection
      If C <> "" Then Call MakeToggleButton(C, Reponses)
    Next C
    Application.ScreenUpdating = True
    '--- Nécessité de différer l'initialisation ---
    Application.OnTime Now + TimeValue("00:00:00"), "InitToggle"
    End Sub
     
    Sub DeleteToggle(AfficherResultats As Boolean)
    Dim OL As OLEObject
    For Each OL In ActiveSheet.OLEObjects
      If TypeOf OL.Object Is MSForms.ToggleButton Then
        If AfficherResultats Then OL.TopLeftCell = OL.Object.Value
        OL.Delete
      End If
    Next OL
    End Sub
     
    Sub MakeToggleButton(CelluleQuestion As Range, Reponses As Variant)
    Dim R As Range
    Dim i&
    Dim OL As OLEObject
    Dim TG As MSForms.ToggleButton
    '---
    For i& = 0 To UBound(Reponses)
      Set R = CelluleQuestion.Offset(0, i& + 1)
      Set OL = ActiveSheet.OLEObjects.Add(ClassType:="Forms.ToggleButton.1", Link:=False, DisplayAsIcon:=False, _
        Left:=R.Left + 2, Top:=R.Top + 2, Width:=R.Width - 4, Height:=R.Height - 4)
      OL.Placement = xlMoveAndSize
      Set TG = OL.Object
      '--- Le nom du ToggleButton servira, dans la classe, à identifier le pseudo groupe (ex : GR5_CT4_ID)
      '--- ainsi que le nombre d'items dans le pseudo groupe (ex : 4 est le nombre situé entre _CT [count] et _ID)
      TG.Name = "GR" & R.Row & "_CT" & UBound(Reponses) + 1 & "_ID" & i& + 1
      TG.Caption = Reponses(i&)
    Next i&
    End Sub
     
    Sub InitToggle()
    Dim OL As OLEObject
    Dim TG As MSForms.ToggleButton
    Dim myClasse As cls_GroupeToggleButton
    '---
    Set myClasse = Nothing
    Set myCollection = New Collection
    For Each OL In ActiveSheet.OLEObjects
      If TypeOf OL.Object Is MSForms.ToggleButton Then
        Set TG = OL.Object
        Set myClasse = New cls_GroupeToggleButton
        Set myClasse.myToggleButton = TG
        myCollection.Add myClasse
      End If
    Next OL
    End Sub
    2) créez un module de classe, renommez le "cls_GroupeToggleButton" puis copiez le code suivant
    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
    Public WithEvents myToggleButton As MSForms.ToggleButton
     
    Private Sub myToggleButton_Click()
    Dim OL As OLEObject
    Dim TG As MSForms.ToggleButton
    Dim boolValue As Boolean
    Dim A$
    Dim B$
    Dim ItemsCount&
    Dim i&
    '---
    boolValue = myToggleButton.Value
    With myToggleButton
      '--- Nombre de ToggleButtons du pseudo groupe (ex : GR5_CT4_ID4 le nombre est 4 situé entre _CT et _ID) ---
      A$ = Mid(.Name, InStr(.Name, "T") + 1)
      ItemsCount& = CLng(Mid(A$, 1, InStr(A$, "_") - 1))
      '--- Suffixe du nom des ToggleButtons du même pseudo groupe (ex : GR5_CT4_ID4 donne GR5_CT4_ID)
      B$ = Mid(.Name, 1, InStr(1, .Name, "D"))
    End With
    '--- Par défaut, tous les ToggleButtons du pseudo groupe à False ---
    For i& = 1 To ItemsCount&
      Set OL = ActiveSheet.OLEObjects(B$ & i&)
      Set TG = OL.Object
      TG.Value = False
      TG.BackColor = RGB(255, 102, 153) 'couleur du fonds
    Next i&
    '--- Le ToggleButton qui a été cliqué ---
    If boolValue Then
      With myToggleButton
        .Value = boolValue
        .BackColor = vbGreen
      End With
    End If
    End Sub
    3) tapez quelques questions dans plusieurs cellules d'une feuille (ex : "A5:A10"), sélectionnez ces cellules puis lancez la macro "PlageDesQuestions"

    Je mets le classeur exemple en pièce jointe pour faciliter.

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

Discussions similaires

  1. Comment accéder à plusieurs comptes à partir d'une seule interface
    Par phplover_2010 dans le forum Général Conception Web
    Réponses: 2
    Dernier message: 21/07/2010, 12h57
  2. comment accéder au tel pixel dans une image
    Par yassertkd dans le forum Images
    Réponses: 4
    Dernier message: 11/09/2009, 09h12
  3. [VB6] Comment accéder à la colonne 0 dans une listview ?
    Par jfdmagic dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 04/05/2009, 15h16
  4. Comment ajouter un 2eme MenuBar dans une frame ?
    Par melanoche dans le forum AWT/Swing
    Réponses: 3
    Dernier message: 02/05/2007, 17h33
  5. comment mettre du texte formaté dans une frame?
    Par afrikha dans le forum GTK+ avec C & C++
    Réponses: 5
    Dernier message: 09/10/2005, 15h55

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