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 :

Evaluation d'une variable en saisisant son nom


Sujet :

Macros et VBA Excel

  1. #1
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2011
    Messages : 38
    Par défaut Evaluation d'une variable en saisisant son nom
    Bonjour,

    Je cherche à coder un module générique à mes macros.
    Je dois pouvoir evaluer certaines constantes (qui n'existent pas systématiquement dans toutes mes macros).

    L'option explicit bloque la compilation car il ne reconnait pas les variables inconnues ce qui est normal, et je veux conserver l'option explicit.

    Avez vous une solution pour évaluer une variable en fonction de son nom?

    Exemple :
    Evaluer("MaVariable") permettrait de retourner la valeur de ma constante MaVariable si elle existe et rien si il n'existe pas dans ma macro.

    J'ai cherché du côté de la fonction Evaluate mais j'ai toujours Type incompatible...

    Merci pour votre aide.

    Bien cordialement,
    batseb

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

    Pourrais-tu être plus clair s'il te plait.

    Même si je ne doute pas que certains t'es compris, je ne vois pas exactement ce que tu veux dire par:
    Je dois pouvoir evaluer certaines constantes (qui n'existent pas systématiquement dans toutes mes macros).
    @+

  3. #3
    Expert éminent
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Par défaut




    Bonjour,

    de toute manière en conservant l'instruction Option Explicit il faut donc tout définir …


  4. #4
    Expert éminent Avatar de Menhir
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2007
    Messages
    16 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 16 037
    Par défaut
    Peut-être qu'en allant fouiller dans Application.VBE.VBProject(s), il est possible d'accéder à la liste des variables.
    Désolé, je n'ai pas le temps d'aller fouiller plus loin, je me contente de fournir cette piste potentielle.

  5. #5
    Membre expérimenté
    Inscrit en
    Décembre 2008
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 115
    Par défaut
    Bonjour

    L'option Explicit oblige à déclarer la variable, pas le type de celle-ci.
    Avec TypeName et VarType on peux savoir le type de la variable (Voir l'aide VBA)
    Après c'est de la gestion de variable
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Dim my Var
    ...
    If myVar Is Nothing Then...
    Si ce n'est pas ça, retour à la question de Nouveau2.


    Cordialement

  6. #6
    Inactif  

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2012
    Messages
    4 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 4 903
    Billets dans le blog
    36
    Par défaut
    Bonjour,

    Donc, tu veux que la variable alpha de ta sub générique1() devienne l'équivalent de ta constante (ou ta variable) Alexandre de ta sub noms() et prenne automatiquement sa valeur ?

    Au final tu voudrais quelque chose qui ressemblerait, si on peut dire à cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    sub noms()
      Alexandre = 10
    end sub
     
    sub générique1()
       alpha = noms.Alexandre
       beta = alpha * alpha 'par exemple
       msgbox (beta)
    end sub
    et tu verrais apparaître 100 dans le msgbox

    Si c'est cela que tu veux, tu peux passer par l'utilisation de paramètres

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    sub noms()
      Alexandre = 10
      générique1(Alexandre)
    end sub
     
    sub générique1(paramètre_quelconque as integer)
       alpha = paramètre
       beta = alpha * alpha 'par exemple
       msgbox (beta)
    end sub

  7. #7
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2011
    Messages : 38
    Par défaut
    Bonjour à tous,

    Tout d'abord, merci pour votre aide.

    Je précise ma demande : j'ai développé 5 modules communs qui sont utilisés dans près de 150 macros. Chaque module a une constante publique qui identifie la version de celui-ci.

    Mon but est de développer un 6eme module qui récupère la version de chacun des autres modules dans la macro en question pour pouvoir ensuite la comparer avec le référentiel et informer le développeur si ces modules ne sont pas à jour.

    Exemple :
    Macro1
    Module1 - constante Module1Version = "20140821"
    Module2 - constante Module2Version = "20140801"

    Macro2
    Module1 - constante Module1Version = "20140701"
    Pas de module 2

    Un module 3 doit lister le module 1 et 2 et tester la valeur de chacune des constantes.
    Un option explicit me bloquerait dans la macro2 car la constante du module2 n'existe pas.
    Je connais la liste des modules à analyser.
    Je connais la liste des constantes à tester.

    Merci pour vos retours.

  8. #8
    Expert éminent


    Profil pro
    Inscrit en
    Juin 2003
    Messages
    14 008
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 14 008
    Par défaut
    bonjour,

    je comprends toujours pas ton besoin d'évaluation ...

    montre nous le code que tu envisage tu envisage utiliser avec une fonction fictive EvalueVariable .. pour comprendre l'utilité de cette évaluation...

  9. #9
    Rédacteur
    Avatar de Philippe Tulliez
    Homme Profil pro
    Formateur, développeur et consultant Excel, Access, Word et VBA
    Inscrit en
    Janvier 2010
    Messages
    13 171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur, développeur et consultant Excel, Access, Word et VBA

    Informations forums :
    Inscription : Janvier 2010
    Messages : 13 171
    Billets dans le blog
    53
    Par défaut
    Bonjour,
    Peut--être qu'avec une variable tableau et les variables énumérées tu pourrais trouver ton bonheur
    Exemple
    Code à placer en tête de module
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Option Explicit
    Public NumVersion(3) As Double
    Public Enum Procedure
     Application = 0
     Module_1 = 1
     Module_2 = 2
     Module_3 = 3
    End Enum
    Code de la procédure de démarrage
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Sub Main()
     NumVersion(Procedure.Application) = 3.2
     Module1
    End Sub
    Code à placer dans les modules concernés (Ici on teste la valeur entière du n° de version)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Sub Module1()
     NumVersion(Procedure.Module_1) = 2.3
     If Int(NumVersion(Procedure.Module_1)) < Int(NumVersion(Procedure.Application)) Then
      MsgBox "Version de l'application " & NumVersion(Procedure.Application) & " supérieure au module1 "
     End If
    End Sub
    [EDIT]
    Sinon tu seras obligé de passer par WorkBook.VBProject.VBComponents mais tu vas construire une usine à gaz.
    Philippe Tulliez
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
    Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
    Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
    Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier

  10. #10
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2011
    Messages : 38
    Par défaut
    Re,

    Merci Philippe, la solution tableau est une piste très intéressante mais je veux pousser la discussion pour savoir si on peut travailler directement avec les constantes des modules. De plus, les modules étant déjà en place sur les 150 macros, je souhaite trouver une solution qui fonctionne dès maintenant sans avoir à recompiler les 150 macros avec les nouveaux modules.

    bbil, je vais te montrer en VBA ce que je souhaite obtenir :

    Module1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Public Const Module1Version = "20140821001" as string
    Module2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Public Const Module2Version = "20140701001" as string
    Module Générique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    private function GetVersion(ByVal Module as string) as string 
    Select case Ucase(Module)
    Case "MODULE1" : GetVersion = Module1Version 
    Case "MODULE2" : GetVersion = Module2Version 
    Case else : GetVersion = ""
    End select
    end function
    Dans le cas où ma macro ne contiendrait que le module 1 (et pas le module2), la compilation plante à cause de Module2Version non déclaré.
    Je cherche donc si il y a une solution avec une fonction qui s'appellerait EvaluerVariable qui permettrait d'évaluer la valeur d'une variable en fonction de son nom.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    private function GetVersion(ByVal Module as string) as string 
    Select case Ucase(Module)
    Case "MODULE1" : GetVersion = EvaluerVariable("Module1Version")
    Case "MODULE2" : GetVersion = EvaluerVariable("Module2Version") 
    Case else : GetVersion = ""
    End select
    end function
    Est-ce plus clair?

    Cordialement,
    Sébastien

  11. #11
    Rédacteur
    Avatar de Philippe Tulliez
    Homme Profil pro
    Formateur, développeur et consultant Excel, Access, Word et VBA
    Inscrit en
    Janvier 2010
    Messages
    13 171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur, développeur et consultant Excel, Access, Word et VBA

    Informations forums :
    Inscription : Janvier 2010
    Messages : 13 171
    Billets dans le blog
    53
    Par défaut
    Bonjour,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Public Const Module1Version = "20140821001" as string
    Je ne sais pas qu'elle version de VBA tu utilises mais la syntaxe que tu affiches ne devrait pas fonctionner
    Ceci est correct
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Public Const Module1Version As String = "20140821001"
    Philippe Tulliez
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
    Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
    Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
    Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier

  12. #12
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2011
    Messages : 38
    Par défaut
    Oui Philippe, tu as raison.

    J'ai écris le code directement sur le forum...

  13. #13
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par batseb Voir le message
    J'ai écris le code directement sur le forum...
    Je m'en serais douté, ça m'arrive aussi.

    Sinon, bien que tu es répondu à bbil, je ne vois toujours pas l'intérêt ou la finalité.

    Peux-tu décrire (même sommairement) ton projet avec une vue d'ensemble sans donner le code à l'intérieur des fonctions, pour voir comment sont disposé tes projets/Modules/Fonctions, please ? Tu n'utilise pas de fichiers .XLAM par exemple ? Toutes tes 150 macros sont regroupées dans 1 module ? Plusieurs modules dans un seul projet ? Plusieurs modules réparties dans plusieurs projets ? Tu importe tes modules directement dans un projet existant (clique droit => importer un module ?, Par code peu importe) ?

    Je suis presque convaincu que la méthode adoptée n'est pas la bonne.

    Lorsque qu'une variable est codé en dur dans un code, tu y accède en utilisant une liaison anticipée. Si la variable n'existe pas, tu obtient une erreur de compilation qui intervient lors de la rentrée dans une Sub/Function/Property contrairement aux erreurs d'exécution (qui n'échoue pas en rentrant dans la Sub) qui interviennent lors de l'exécution d'une l'instruction quelconque.
    On Error Resume/Goto intervient au dessus de la couche de compilation et ne peut malheureusement rien faire contre les erreurs de compilation.

    En Visual Basic, c'est différent parce que le .NET a été pensé/repensé de A à Z et grâce à la réflexion (System.Reflection), il y a moyen d'accéder/modifier/lire des Variables même avec portées Privées en liaison tardive en passant des chaines de type String, mais en VBA, il vaut mieux adopter une autre méthode.

    Tu as la possibilité d'utiliser Excel.Run qui demande le nom d'une Sub/Function sous la forme d'une chaine String. Tu peux utiliser une VBA.Collection.
    Dans la mesure où tu n'as pas besoin d'écrire mais de lire uniquement, seul une Property Get/Function (variable donc, contrairement aux constantes) devrai être correcte par principe.

    Mais vu qu'on (moi en tout cas) n'y vois pas clair dans ce que tu veux vraiment faire ...

  14. #14
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2011
    Messages : 38
    Par défaut
    Bonjour Nouveau2,

    J'ai 150 classeurs xlsm différents.
    Chaque classeur contient des modules spécifiques et des modules communs.

    A chaque evolution d'un classeur, j'applique les évolutions demandées dans les modules spécifiques et j'importe les nouvelles versions des modules communs utilisés dans celui-ci (importer un module - versions stockées sur le serveur).
    Je n'utilise pas les xlam car nous ne sommes pas autorisés à déployer en automatique ce fichier sur les PCs des 230 utilisateurs... et pas question qu'on le centralise sur le serveur car il faut que la macro puisse tourner en session déconnectée.

    Le but de ma demande est d'avertir le développeur quand on ouvre une macro et de tester les versions des modules communs présents.

    Je ne peux pas être plus clair...

    Bonne journée,

  15. #15
    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,

    Je ne sais pas si j'ai bien compris alors, je vais peut être dire une bêtise mais dans le post #7 tu dis :
    Je précise ma demande : j'ai développé 5 modules communs qui sont utilisés dans près de 150 macros. Chaque module a une constante publique qui identifie la version de celui-ci.
    Pourquoi ne pas concaténer le numéro de version au nom du module comme ceci par exemple : "Module1_20140821001" ?
    Ensuite, tu parcours les modules et tu extrait le numéro de version pour en connaître la valeur :
    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
     
    Sub test()
     
        Dim I As Integer
        Dim J As Integer
     
        With Application.VBE
     
            For I = 1 To .VBProjects.Count
     
                If .VBProjects(I).Name = "Classeur2" Then
     
                    With .VBProjects(I)
     
                        For J = 1 To .VBComponents.Count
     
                            If InStr(.VBComponents(J).Name, "_") <> 0 Then
     
                                MsgBox "La version du module est '" & Split(.VBComponents(J).Name, "_")(1) & "'"
     
                            End If
     
                        Next J
     
                    End With
     
                End If
     
            Next I
     
        End With
     
    End Sub
    Hervé.

    Petite précision, le nom du projet VBA dans mon exemple est "Classeur2" qu'il faut modifier dans "Outils" -> "Propriétés de VBAProject..." (VBAProject étant le nom par défaut).

    Hervé.

  16. #16
    Membre Expert
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 2 266
    Par défaut
    Bonjour,

    Une idée comme ça mais pas le temps de tester.
    Tu mets ta constante en nom à l'ouverture du module, ensuite tu testes si ce nom existe avec une gestion d'erreur.

    eric

  17. #17
    Inactif  

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2012
    Messages
    4 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 4 903
    Billets dans le blog
    36
    Par défaut
    Bonjour,

    Puisque les classeurs ont une propriété Commentaires; tu pourrais l'utiliser pour y mettre la liste et la version des procédures. Ensuite, il te suffirait de lire la valeur de la propriété. Pour peu que tu aies un répertoire à jour de tes modules dans une feuille Excel; il te suffirait de comparer le contenu de la propriété et de la liste. Ensuite, une macro pourrait enlever le vieux module, importer le nouveau et mettre la propriété à jour.

    Même que tu ajouter des propriétés personnalisées.

Discussions similaires

  1. Réponses: 7
    Dernier message: 11/12/2008, 18h45
  2. [EVAL] utiliser la valeur d'une variable à partir de son nom
    Par Julien Dufour dans le forum VBA Access
    Réponses: 0
    Dernier message: 24/04/2008, 13h15
  3. Récuperer la valeur d'une variable à partir de son nom
    Par Etanne dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 20/10/2007, 18h04
  4. Récupérer une variable à partir de son nom ...
    Par CynO dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 13/10/2005, 16h59

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