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 tester si un contrôle existe?


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Employé
    Inscrit en
    Mai 2017
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Employé

    Informations forums :
    Inscription : Mai 2017
    Messages : 37
    Par défaut Comment tester si un contrôle existe?
    Bonjour,

    Un autre problème que je n'arrive pas à résoudre par moi même malgré mes recherches sur les forums... je n’arrive pas à trouver comment faire pour vérifier qu’un contrôle existe.

    Dans mon formulaire, les boutons d’options (nommés « OB » & i dans mon code) ont un numéro attribué en fonction de ce qu’ils représentent, important pour moi pour me repérer. De manière générale, les chiffres pairs sont pour des valeurs « bonnes » et les chiffres impaires pour des valeurs « mauvaises ».

    Je voudrais que si une des valeurs est « mauvaise » dans une série de contrôle donnée, un message s’affiche. Jusque-là pas de problème, sauf lorsqu’il y a des trous parce qu’un contrôle n’existe pas (de 250 à 259 dans la série de 233 à 249 du code ci-dessous). A ce moment-là, la condition devient automatiquement vrai et le message s’affiche alors qu’il ne le devrait pas puisque tous mes contrôles existants ont une « bonne » valeur.

    Bien sûr, je pourrais séparer cela en deux formules (de 233 à 249 et de 261 à 271) mais lorsque que la série de chiffre est importante et les trous nombreux, cela est plutôt embêtant.
    Je cherche donc à inclure un truc du genre if « OB » & i n’existe pas, then next i
    Mais je n’y arrive pas.

    PS: Lorsque j'enlève le "On error resume next" le code ne fonctionne pas.

    Merci pour votre aide.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    For i = 233 To 271 Step 2
    On Error Resume Next
    If Me.Controls("OB" & i).Value = True Then
            MsgBox "TEST"
            Exit Sub
        End If
    End If
    Next i

  2. #2
    Membre Expert
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 817
    Billets dans le blog
    10
    Par défaut
    Bonjour,

    Il ne faut jamais annuler une erreur par On Error Resume, mais plutôt s'en servir pour traiter l'erreur.
    Pour cela tu peux, par exemple, utiliser l'objet Err.
    Par exemple :
    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
    Dim b As Boolean
    On Error Resume Next
    For i = 233 To 271 Step 2
    'on teste l'existence du contrôle par n'importe laquelle de ces propriétés
        b = Me.Controls("OB" & i).Value
    'si la ligne précédente renvoie une erreur, le contrôle n'existe pas
        If Err <> 0 Then
            'ton contrôle n'existe pas
            On Error GoTo 0
        Else
            'ton contrôle existe
            If Me.Controls("OB" & i).Value = True Then
                MsgBox "TEST"
                Exit Sub
            End If
        End If
    Next i

  3. #3
    Expert confirmé

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 169
    Billets dans le blog
    5
    Par défaut
    Bonjour,

    tu n'indiques pas s'il existe d'autres optionbutton qu'il faut exclure

    ici, une méthode où il faudra borner les numéros d'optionbutton si besoin

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Private Sub CommandButton1_Click()
    Dim MonOptionButton As Control
        ' boucle sur les contrôles
        For Each MonOptionButton In Me.Controls
            ' si c'est un optionbutton
            If TypeOf MonOptionButton Is MSForms.OptionButton Then
                ' si le nom est un nombre pair         ET que l'optionbutton est coché : on affiche le message
                If Val(Split(MonOptionButton.Name,".")(1)) Mod 2 = 0 And MonOptionButton Then MsgBox MonOptionButton.Name & " est coché"
            End If
        Next MonOptionButton
    End Sub
    Ca évite d'utiliser la gestion d'erreur ... même si une solution avec existe

  4. #4
    Membre averti
    Homme Profil pro
    Employé
    Inscrit en
    Mai 2017
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Employé

    Informations forums :
    Inscription : Mai 2017
    Messages : 37
    Par défaut
    Merci pour ces réponses rapides...

    A pijaky: je comprend ton code, mais il me signale une erreur lors de son exécution "objet spécifié introuvable" avec la ligne b = Me.Controls("OB" & i).Value surlignée.


    A joe.levrai: j'arrive à comprendre la majeur partie du code, enfin je crois... juste cette partie me pose problème

    If Val(MonOptionButton.Name) Mod 2 = 0 And MonOptionButton

    Peux-tu me l'expliquer un peux plus en détail (signification de Val ... Mod 2 = 0 et pourquoi tu ajoute "and MonOptionButton".

    Merci à vous deux

  5. #5
    Expert confirmé

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 169
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par RemyA56 Voir le message
    A joe.levrai: j'arrive à comprendre la majeur partie du code, enfin je crois... juste cette partie me pose problème

    If Val(MonOptionButton.Name) Mod 2 = 0 And MonOptionButton

    Peux-tu me l'expliquer un peux plus en détail (signification de Val ... Mod 2 = 0 et pourquoi tu ajoute "and MonOptionButton".

    Reprenons déjà le commentaire que j'avais mis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    'si le nom est un nombre pair         ET que l'optionbutton est coché : on affiche le message
    If Val(Split(MonOptionButton.Name,".")(1)) Mod 2 = 0 And MonOptionButton Then MsgBox MonOptionButton.Name & " est coché"
    J'ai ainsi constaté avoir recopié mon premier test et pas le définitif, j'ai mis à jour mon message
    En effet, j'ai ajouté un Split sur le nom de ton contrôle. Split permet de découper une chaine en fonction d'un séparateur.
    Ici, j'ai découpé la chaine en deux portions, en fonction du point "." du nom de ton contrôle, et d'obtenir une sous-chaine qui commence par les numéros à tester

    La fonction Val() récupère, au sein d'une chaine de caractère, la partie numérique en partant du début de la chaine, jusqu'à trouver le premier caractère non numérique.
    https://msdn.microsoft.com/fr-fr/lib...ffice.15).aspx
    Exemple : Val("Toto14") donne 0 /// Val("12toto17") donne 12 // Val("toto14titi12") donne 0

    L'opérateur Mod, c'est celui qui permet de calculer le reste d'une division
    https://msdn.microsoft.com/fr-fr/lib...ffice.15).aspx

    X mod Y = Z
    X = le dividende (numérateur)
    Y = le diviseur (dénominateur)
    Z = le reste de la division de X par Z

    X/Y = Z

    Ainsi, tester un numbre en mod 2 permet de savoir si un nombre est pair (si le résultat vaut 0) ou impair (si le résultat vaut 1)


    Val() va donc extraire la partie numérique de ton nom de contrôle, et Mod détecter si c'est pair ou impair

  6. #6
    Invité
    Invité(e)
    Par défaut
    bonjour,
    ce que je ne comprend pas! c'est que tu ne connaisses le nombre d’option de ton formulaire!

    j’aurai tendance à croire que tu le génère dynamiquement! si c'est le cas tu les connais forcément! donc ce qui devrait nous préoccuper ce n'est pas comme je s'ais qu'ils existent mais comment je les génères!

  7. #7
    Membre averti
    Homme Profil pro
    Employé
    Inscrit en
    Mai 2017
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Employé

    Informations forums :
    Inscription : Mai 2017
    Messages : 37
    Par défaut
    Les boutons d'options ne sont pas générés automatiquement, et je connais leur nombre. A la limite, ce serait ma nomenclature qu'il y aurai à changer pour simplifier les choses, mais elle me sert m'y retrouver plus facilement. C'est à cause de cela qu'il y a des trous et des numéros de boutons d'option qui n'existent pas.

  8. #8
    Invité
    Invité(e)
    Par défaut
    tes boutons sont dans un formulaire ou une feuille excel?

  9. #9
    Membre averti
    Homme Profil pro
    Employé
    Inscrit en
    Mai 2017
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Employé

    Informations forums :
    Inscription : Mai 2017
    Messages : 37
    Par défaut
    Les boutons sont dans le formulaire.

  10. #10
    Membre Expert
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 817
    Billets dans le blog
    10
    Par défaut
    Pardon, mauvais emplacement de On Error Resume Next :

    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
    Dim b As Boolean, i As Integer
    For i = 1 To 10
        On Error Resume Next
    'on teste l'existence du contrôle par n'importe laquelle de ces propriétés
        b = Me.Controls("OB" & i).Value
    'si la ligne précédente renvoie une erreur, le contrôle n'existe pas
        If Err <> 0 Then
            'ton contrôle n'existe pas
            On Error GoTo 0
        Else
            'ton contrôle existe
            If Me.Controls("OB" & i).Value = True Then
                MsgBox "TEST"
                Exit Sub
            End If
        End If
    Next i

  11. #11
    Invité
    Invité(e)
    Par défaut
    donc un vas créer un module de classe!
    Code Classe1 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Public WithEvents Chk As MSForms.OptionButton
    Private Sub Chk_Click()
    If UCase(Left(Chk.Name, 2)) = "OB" And Replace(Chk.Name, Left(Chk.Name, 2), "") Mod 2 <> 0 Then MsgBox "Test"
    End Sub

    maintenant on vas implémenter une variable tableau à l’initialisation de ton formulaire!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Dim Cks() As New Classe1
    Private Sub UserForm_Initialize()
    ReDim Cks(0)
    For i = 0 To Me.Controls.Count - 1
    If TypeName(Me.Controls(i)) = "OptionButton" Then
        ReDim Preserve Cks(UBound(Cks) + 1)
       Set Cks(UBound(Cks)).Chk = Me.Controls(i)
    End If
    Next
    End Sub
    maintenant seule le contrôle qui existe seront pris en compte dans l’événement Chk_Click de ton module de classe donc tu sais quoi en faire!

    indépendamment de ça,tu sais maintenant que de Cks(1) à Cks(ubound(Cks)) les options existent!
    Dernière modification par Invité ; 02/05/2017 à 15h21.

  12. #12
    Membre averti
    Homme Profil pro
    Employé
    Inscrit en
    Mai 2017
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Employé

    Informations forums :
    Inscription : Mai 2017
    Messages : 37
    Par défaut
    A pijaku: Effectivement, cela fonctionne très bien maintenant. Merci beaucoup.

    A dysorthographie: Cela sort très largement de mes petites compétences... je pourrais faire un copier/coller du code bêtement mais je ne comprendrais pas ce que je ferais. Si jamais tu voulais prendre le temps de m'expliquer ton code, je lirai cela volontiers (même si je ne suis pas sur de comprendre toutes tes explications...). Sinon merci quand même pour ton aide, je garde ça dans un coin et quand je serais un peu (beaucoup) meilleur j'essaierais de comprendre un peu plus.

  13. #13
    Membre Expert
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 817
    Billets dans le blog
    10
    Par défaut
    Une autre solution consiste à placer, manuellement, dans la propriété Tag des boutons d'option concerné : "OK" (par exemple).
    Puis, boucler sur tous les contrôles et tester uniquement si le Tag = "OK" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Dim C As Control
     
        For Each C In Me.Controls
            If TypeOf C Is MSForms.OptionButton Then
                If C.Tag = "OK" Then
                    If C.Value = True Then MsgBox C.Name
                End If
            End If
        Next C

  14. #14
    Invité
    Invité(e)
    Par défaut
    un module de classe est une variable objet, plus précisément c'est un modèle de variable objet! on parle d'objet et pas de variable car il n'est pas seulement question d'y affecter une valeur mais un module de classe est capable d’effectuer des actions!

    WithEvents indique que la variable objet Chk peut intercepter les événement du contrôle qui lui es lier comme le Click!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    PublicWithEvents Chk As MSForms.OptionButton 'permet d'affecter une OptionButton de ton formulaire à ton module de classe!
    Private Sub Chk_Click() 'ici on retrouve le Click ausi surement que si tu le définisais dans ton formulaire!
    If UCase(Left(Chk.Name, 2)) = "OB" And Replace(Chk.Name, Left(Chk.Name, 2), "") Mod 2 <> 0 Then MsgBox "Test"  'ici on vérifie si le nom de l'OptionButton commence par "OB" et vue que for i = 233 To 271 Step 2 tu ne t’intéresse qu'au option N° impaire! 
    End Sub
    Code Exemple : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    2 mod 2 =0
    3 mod 2 =1
    4 mod 2=0 
    5 mod 2 =1
    etc mod 2= 1 ou 0
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Dim Cks() As New Classe1 'ici on défini un variable tableau basé sur le modèle du module de classe1
    Private Sub UserForm_Initialize() 'ce produit à l'ouverture du formulaire!
    ReDim Cks(0) on initialise le tableau avec une variable un valeur pour rien!
    For i = 0 To Me.Controls.Count - 1 'on compte les contrôle du formulaire
    If TypeName(Me.Controls(i)) = "OptionButton" Then 'on vérifie qu'il s'agit bien d'un OptionButton 
        ReDim Preserve Cks(UBound(Cks) + 1) 'on redimensionne le tableau pour lui fournir une nouvelle OptionButton
         Set Cks(UBound(Cks)).Chk = Me.Controls(i) 'on affecte l'OptionButton 
    End If
    Next
    End Sub
    maintenant Cks contient toutes les OptionButton du formulaire

  15. #15
    Membre averti
    Homme Profil pro
    Employé
    Inscrit en
    Mai 2017
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Employé

    Informations forums :
    Inscription : Mai 2017
    Messages : 37
    Par défaut
    A pikaju: Merci pour cette autre solution, cela me servira surement pour autre chose.

    A dysorthographie: Merci beaucoup d'avoir pris le temps de m'expliquer, même si comme je le pensais, il me faudra encore du temps avant d'arriver à comprendre tout cela.

    Merci à tous pour votre aide.

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 25/09/2008, 18h53
  2. [FTP] Comment tester si un dossier existe sur un ftp ?
    Par speed034 dans le forum Langage
    Réponses: 5
    Dernier message: 04/06/2008, 14h40
  3. comment tester qu'un fichier existe bien
    Par adilou1981 dans le forum Langage
    Réponses: 2
    Dernier message: 05/06/2007, 09h57
  4. [C#][2.0] Comment tester si un fichier existe?
    Par just1980 dans le forum ASP.NET
    Réponses: 2
    Dernier message: 08/12/2006, 12h22
  5. Comment tester si un dossier existe ou pas?
    Par Hamdi Hedhili dans le forum C++
    Réponses: 2
    Dernier message: 06/12/2005, 09h44

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