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 :

Utilisation de la méthode run dans un module classe


Sujet :

Macros et VBA Excel

  1. #1
    Candidat au Club
    Utilisation de la méthode run dans un module classe
    Bonjour à tous,
    La question est : Y a-t-il quelque chose de particulier à faire pour pouvoir utiliser la méthode run dans un module de classe ?

    Dans un module cela fonctionne très bien:

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Sub macroCall()
    Dim nom As String
     
    call test()
    nom = "test"
     
    Application.Run (nom)
    End Sub
     
    private sub test()
        debug.print "Bonjour"
    endsub


    La fonction test est exécutée 2 fois.
    Par contre lorsque je suis dans un module de classe, le call passe mais l'application.run retourne toujours l'erreur:

    Erreur d'exécution '1004':
    Impossible d'exécuter la macro 'test'. il est possible qu'elle ne soit pas disponible dans ce classeur ou que toutes les macros soient désactivées.


    Merci de votre aide

  2. #2
    Membre expérimenté
    Bonjour,
    Citation Envoyé par Marcouille34 Voir le message
    La question est : Y a-t-il quelque chose de particulier à faire pour pouvoir utiliser la méthode run dans un module de classe
    Pas sûr que ton erreur vienne de ton module de classe car tu as créé 'private sub test' donc son domaine est le module.

    Si tu écris dans ton module de classe
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    nom = "module1.test"

    cela devrait mieux fonctionner.

  3. #3
    Candidat au Club
    Bonjour anasecu,
    Cela ne fonctionne pas et c'est compréhensible:
    - pour moi la syntaxe "call moduleX.fonction" permet d'appeler "fonction" à partir d'un autre module ... moduleY par exemple.
    - "fonction" doit être déclarée public. En interne cela n'a pas lieu d'être.
    - Cette syntaxe ne fonctionne pas pour un module de classe. Sauf si la classe à été instanciée:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    dim toto as new classe1
    toto.fonction
     
    classe1.fonction ' retourne variable non définie


    Mais ce n'est pas ce que je veux ... Il faudrait que tout soit en local, donc les fonctions déclarées "private"
    En tout cas merci pour ton temps
    Bonne journée

  4. #4
    Expert confirmé
    Bonjour,

    Je ne comprends pas ce que tu veux faire : un module de classe est un objet personnel.
    Comme tout objet, il peut posséder des propriétés, des méthodes et des évènements.
    Si tu veux exécuter une de ses méthodes, il faut que l'objet existe (qu'il soit instancié).
    Cordialement,
    Patrice
    Personne ne peut détenir tout le savoir, c'est pour ça qu'on le partage.

    Pour dire merci, cliquer sur et quand la discussion est finie, penser à cliquer sur

  5. #5
    Candidat au Club
    Citation Envoyé par Patrice740 Voir le message
    Bonjour,

    Je ne comprends pas ce que tu veux faire : un module de classe est un objet personnel.
    Comme tout objet, il peut posséder des propriétés, des méthodes et des évènements.
    Si tu veux exécuter une de ses méthodes, il faut que l'objet existe (qu'il soit instancié).
    Bonjour Patrice,
    Voilà en pièce jointe ce que je voudrais.
    En fait dans ce cas j'ai toujours l'erreur d'exécution 1004 (en mode mole et module de classe) alors que sur mon projet je n'ai cette erreur qu'en mode module de classe!!! Je m'y perds moi-même ...

    Bref ... si je n'avais plus d'erreur cela serait parfait

    Merci
    Cordialement

  6. #6
    Expert confirmé
    Re,

    Comme de nombreux contributeurs n'ouvrent pas les fichiers joints, en particulier lorsqu'ils contiennent des macros,
    pour les raisons indiquées ici : Fichier joint dans vos discussions

    Publies ton code et exposes ton problème clairement, si besoin joins un fichier xlsx (sans macro).

    Note : Un module de classe sert à définir un objet, ce n'est pas un conteneur de procédure ou de fonction, pour ça il faut utiliser un module standard.
    Voir : Classes personnalisées en VB(A)
    Et : Office et les modules de classes
    Cordialement,
    Patrice
    Personne ne peut détenir tout le savoir, c'est pour ça qu'on le partage.

    Pour dire merci, cliquer sur et quand la discussion est finie, penser à cliquer sur

  7. #7
    Candidat au Club
    D'accord pour ta remarque, dans mon projet les module de classe est un automate d'état et selon un événement on exécute une fonction associé d'où mon application.run ...

    Ci-dessous Module1
    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
    Sub main()
       Dim toto As New Classe1
       Dim fct As String
     
       fct = "fct1"
       Call fct1
       Application.Run (fct)
       toto.main (fct)
     
    End Sub
     
    Private Sub fct1()
       Debug.Print "fct1"
    End Sub
    Private Sub fct2()
       Debug.Print "fct2"
    End Sub
    Private Sub fct3()
       Debug.Print "fct3"
    End Sub
    Private Sub fct4()
       Debug.Print "fct4"
    End Sub


    Et là le module de classe Classe1
    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 main(s As String)
       Application.Run (s)
    End Sub
     
     
     
    Private Sub fct1()
       Debug.Print "fct1"
    End Sub
    Private Sub fct2()
       Debug.Print "fct2"
    End Sub
    Private Sub fct3()
       Debug.Print "fct3"
    End Sub
    Private Sub fct4()
       Debug.Print "fct4"
    End Sub


    Merci

  8. #8
    Expert confirmé
    Je répète :
    Citation Envoyé par Patrice740 Voir le message
    Un module de classe sert à définir un objet, ce n'est pas un conteneur de procédure ou de fonction, pour ça il faut utiliser un module standard.
    [...]
    Un module de classe est un objet avec des méthodes, des propriétés et des évènements. Il ne contient ni procédure, ni fonction comme un module standard.
    Dans l'aide VBA :
    Application.Run, méthode
    Cette méthode exécute une macro ou appelle une fonction. Elle peut être utilisée pour exécuter une macro écrite en Visual Basic ou dans le langage de macro de Microsoft Excel, ou pour exécuter une fonction dans une DLL ou une XLL.
    Cordialement,
    Patrice
    Personne ne peut détenir tout le savoir, c'est pour ça qu'on le partage.

    Pour dire merci, cliquer sur et quand la discussion est finie, penser à cliquer sur

  9. #9
    Membre émérite
    Bonjour,

    2 possibilités.

    1- tu peux passer les méthodes de ta classe en public (au lieu de Private).
    Alors, utilise CallByName :
    Code Module1 :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Sub main()
       Dim toto As New Classe1
       Dim fct As String
       fct = "fct3"
       toto.main (fct)
    End Sub

    Code Module de classe Classe1 :
    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
    Option Explicit
     
    Sub main(s As String)
       CallByName Me, s, VbMethod
    End Sub
    Sub fct1()
       Debug.Print "fct1"
    End Sub
    Sub fct2()
       Debug.Print "fct2"
    End Sub
    Sub fct3()
       Debug.Print "fct3"
    End Sub
    Sub fct4()
       Debug.Print "fct4"
    End Sub


    2- tu ne peux pas passer les méthodes de ta classe en public.
    Utilises un Select Case et Call.
    Code Module1 :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Sub main()
       Dim toto As New Classe1
       Dim fct As String
       fct = "fct3"
       toto.main (fct)
    End Sub

    Code Module de classe Classe1 :
    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
    Option Explicit
     
    Sub main(s As String)
       Select Case s
        Case "fct1": Call fct1
        Case "fct2": Call fct2
        Case "fct3": Call fct3
        Case "fct4": Call fct4
       End Select
    End Sub
    Private Sub fct1()
       Debug.Print "fct1"
    End Sub
    Private Sub fct2()
       Debug.Print "fct2"
    End Sub
    Private Sub fct3()
       Debug.Print "fct3"
    End Sub
    Private Sub fct4()
       Debug.Print "fct4"
    End Sub


    EDIT :
    les module de classe est un automate d'état et selon un événement on exécute une fonction associé
    Quel est cet événement?
    Cordialement,
    Franck

  10. #10
    Candidat au Club
    Bonjour Franck,
    J'ai testé ta première possibilité et j'ai l'erreur d'exécution 438, et d'après ce tuto cela semble normal, en fait l'objectif de mes "fct" est d'initialiser des variables qui seront ensuite retournées via des propriétés.
    En ce qui concerne la deuxième possibilité, c'est ainsi que le code est fait aujourd'hui . Et comme j'avais un peu de temps (confinement oblige) et que la méthode run fonctionne dans un de mes modules, je voulais l'utiliser aussi dans un module de classe … le but: gain de code et effet de style … et pour voir si ça marche!

    Pour répondre à ta dernière question, mon automate est un analyseur de trace en temps réel et les événements peuvent être soit des commandes, soit leurs traces ou leurs résultats.
    Merci pour ton temps

  11. #11
    Membre émérite
    Bonjour,

    L'erreur 438 est due aux déclarations des méthodes de ta classe en "Private".
    Déclare les en "Public" et tu n'auras plus d'erreur avec CallByName.
    Cordialement,
    Franck