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 :

Ôter les crochets [] [Toutes versions]


Sujet :

Macros et VBA Excel

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Mai 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chargé d'affaire
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2012
    Messages : 25
    Points : 25
    Points
    25
    Par défaut Ôter les crochets []
    Bonjour, après avoir lu le billet d’humeur de l’excellent Pierre Fauconnier :
    VBA-Excel: Notation raccourcie d'une plage, une fausse bonne idée! - Blogs - Forum du club des développeurs et IT Pro (developpez.net)

    J’ai compris l’erreur que je commettais depuis longtemps.
    Je tiens à préciser que je ne fais pas partie des initiés mais plutôt des ploucs et que j’utilisais cette syntaxe parce que visuellement cela me permettait de repérer mes shapes et plages plus facilement.

    J’ai commencé l’épurage de mes scripts mais il me reste un point sur lequel j’achoppe : les ListBox.

    Je sèche sur ç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
    Sub PropLBX()
     
        Dim i  As Byte
        Dim NoLgn As Byte
        Dim NbLgn As Byte
        Dim ValLgn As String
     
        NoLgn = [ListBox].ListIndex 'N° de ligne active
        NbLgn = [ListBox].ListCount 'Nombre de lignes
     
        For i = 1 To [ListBox].ListCount 'Selectionne chaque valeur une a une
     
            [ListBox].ListIndex = i 'Selectionne une ligne
            ValLgn = [ListBox].List([ListBox].ListIndex) ' Valeur de la ligne active
     
        Next
     
    End Sub
    Si quelqu’un peu me donner une direction pour corriger, je lui en serais plus que reconnaissant.

    ListBox.xlsm

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 128
    Points : 55 940
    Points
    55 940
    Billets dans le blog
    131
    Par défaut
    Salut.

    Ton code avec crochets fonctionne sans soucis. Mais... Si j'enlève les crochets, ça bugue => normal. Je remets les crochets => ça continue à buguer. Rigolo, non?*


    Perso, voici comment j'adresse un contrôle de formulaire placé sur une feuille:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    NoLgn = Shapes("Listbox").OLEFormat.Object.ListIndex
    Pour éviter la répétition de tout l'adressage de l'objet sur chaque ligne, tu peux le mettre en variable en début de code et le supprimer à la fin.

    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
    Sub PropLBX()
     
        Dim i  As Byte
        Dim NoLgn As Byte
        Dim NbLgn As Byte
        Dim ValLgn As String
        Dim lb As Object
     
        Set lb = Shapes("Listbox").OLEFormat.Object
        NoLgn = lb.ListIndex 'N° de ligne active
        NbLgn = lb.ListCount 'Nombre de lignes
     
        For i = 1 To lb.ListCount 'Selectionne chaque valeur une a une
            lb.ListIndex = i 'Selectionne une ligne
            ValLgn = lb.List(lb.ListIndex)  ' Valeur de la ligne active
        Next
     
        Set lb = Nothing
    End Sub

    * Je tire comme conclusion de cette bizarrerie une raison supplémentaire de ne pas utiliser cette notation

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Mai 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chargé d'affaire
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2012
    Messages : 25
    Points : 25
    Points
    25
    Par défaut
    Merci beaucoup de t’être occupé de mon cas.
    C’est absolument parfait.

    Maintenant il faut que j’apprenne à me servir de l’instruction : Set

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 128
    Points : 55 940
    Points
    55 940
    Billets dans le blog
    131
    Par défaut
    Juste deux mots sur le Set

    Set sert à affecter une valeur à une variable de type Objet. VBA qui n'est pas un langage totalement orienté objet et qui est en plus très permissif, utilise des variables primaires et des variables Objet. Les variables primaires sont les string, les numériques (single, double, long, integer, byte), les booléens (True et False), les dates (date et heure), ainsi que les types personnalisés (Type... End Type). Les variables primaires sont affectées sans utiliser Set. Pour toutes les autres variables, tu dois utiliser Set pour indiquer à VBA que tu prends bien l'objet et non sa valeur par défaut, qui pourrait être une valeur d'un type primaire.

    Si tu regardes l'illustration suivante, tu vois que le mot set revêt toute son importance puisque, alors que A et B sont déclarés sans type (=> ils sont alors de type Variant), a reçoit la valeur de la cellule alors que b reçoit la cellule en tant qu'objet. Omettre le Set devant b ne lèverait pas d'erreur mais tu ne récupèrerais pas l'objet.

    Nom : 2021-07-01_100523.png
Affichages : 95
Taille : 23,2 Ko

    C'est pourquoi, lorsque l'on n'est pas certain du type de la valeur que l'on va récupérer, il est préférable de typer en Variant pour les types primaires (ou de ne pas typer ce qui revient au même) et de typer en Object une variable qui doit recevoir un objet lorsque l'on n'est pas certain du type de l'objet que l'on va récupérer... Ainsi, si on oublie le Set, on plantera à la compilation:

    Nom : 2021-07-01_100453.png
Affichages : 90
Taille : 8,5 Ko

    Nom : 2021-07-01_100719.png
Affichages : 90
Taille : 8,7 Ko

    Pour lever toute ambiguïté, je préfère ne pas utiliser la propriété par défaut et la spécifier dans mon code de manière explicite:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Sub Test()
      Dim a
      Dim b As Object
     
      a = Range("a1").Value
      Set b = Range("a1")
    End Sub


    Il est de toute façon préférable selon mes bonnes pratiques de:








    (*) Cela rejoint d'ailleurs l'esprit du billet que tu as cité précédemment. J'attache de l'importance à ce que mon code soit lisible et compréhensible même par une personne ne connaissant pas les finesses du langage. Je trouve donc qu'il est plus utile de lui permettre de comprendre directement que l'on affecte la valeur de la cellule (a = Range("a1").Value) plutôt que de lui laisser supposer que Range("a1") vers une variable "non object" va transférer la propriété .Value (et pas .Text ou .Value2 ou n'importe quelle autre propriété).

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 128
    Points : 55 940
    Points
    55 940
    Billets dans le blog
    131
    Par défaut
    Encore un petit truc sur le Set et la propriété par défaut (d'un objet Range, dans ce cas-ci)

    Lorsque l'on affecte un objet à une propriété d'un autre objet, on a deux choix, selon la façon dont la classe a été écrite, et on va voir que le code peut vraiment être ambigu.


    Voici le code d'une classe nommée Perso. Elle est très simple puisqu'elle contient deux propriétés publiques autoimplémentées. Ce code se place dans un module de classe nommé Perso.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Option Explicit
     
    Public Content As Variant
    Public Range As Range
    Si je veux manipuler un objet issu de cette classe, je vais devoir mettre un Set sur la ligne d'affectation de la propriété Range de mon objet. Si j'utilise la propriété par défaut de Range("a1") pour la propriété Value de l'objet myPerso, il n'y a pas trop d'ambiguïté puisque pour affecter la propriété Range de l'objet, je dois utiliser Set:
    Nom : 2021-07-01_210201.png
Affichages : 78
Taille : 10,0 Ko


    Si maintenant je crée la propriété Range de mon objet avec un Setter, le code à l'intérieur de la classe va devoir utiliser Set pour affecter la valeur de la propriété publique à la variable privée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Option Explicit
     
    Public Content As Variant
    Private mRange As Range
     
    Property Let Range(Value As Range)
      Set mRange = Value
    End Property
     
    Property Get Range() As Range
      Set Range = mRange
    End Property
    Du coup, comme il est déjà mis dans la classe, je ne peux pas le remettre lors de l'affectation sous peine de lever une erreur. Le code qui utilise un objet de cette classe va créer une ambiguïté puisque l'on va voir deux lignes identiques, la première affectant la valeur de A1 et la seconde affectant la cellule A1 en tant qu'objet.

    Nom : 2021-07-01_210846.png
Affichages : 74
Taille : 11,5 Ko


    C'est pour lever cette ambiguïté que je préconise de toujours utiliser le nom de la propriété, même lorsque l'on manipule la propriété par défaut:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Sub Test()
      Dim myPerso As Perso
     
      Set myPerso = New Perso
      myPerso.Content = Range("a1").Value
      myPerso.Range = Range("a1")
      Debug.Print myPerso.Range.Address
    End Sub

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

Discussions similaires

  1. Raccourci plus faciles pour les crochets
    Par coyotte507 dans le forum Mac OS X
    Réponses: 1
    Dernier message: 02/08/2011, 20h32
  2. Liste d'arguments sans les crochets
    Par Spitfire 95 dans le forum Général Python
    Réponses: 7
    Dernier message: 22/03/2010, 21h46
  3. Egrep et les crochets
    Par Empty_body dans le forum Shell et commandes GNU
    Réponses: 4
    Dernier message: 02/06/2009, 11h54
  4. Eliminer les crochets sans split
    Par narmika dans le forum Langage
    Réponses: 8
    Dernier message: 02/10/2007, 13h13
  5. [WebMacro] Les crochets s'invitent!
    Par Twofy dans le forum Développement Web en Java
    Réponses: 1
    Dernier message: 04/08/2004, 14h22

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