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 :

Appeler une fonction depuis un autre module


Sujet :

Macros et VBA Excel

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 75
    Points : 42
    Points
    42
    Par défaut Appeler une fonction depuis un autre module
    Bonsoir à tous, je viens une nouvelle fois faire appel à toutes les lumières de Developpez. Je cherche à faire appel à une fonction présente dans une feuille xla.

    Je vais essayer d'être le plus clair possible. J'ai télécharger un module (feuille XLA) sur Internet permettant de récupérer les données de notre CRM (Salesforce) sur Excel. Celui fonctionne à merveille et permet de faire des requêtes relativement puissantes. J'ai paramété mes requêtes et celles-ci fonctionne très bien.

    Maintenant dans un classeur, je développe en VBA un module permettant la mise en forme de données assez simple. Cependant, je souhaiterai pouvoir faire appel à une fonction contenue dans cette feuille xla (qui officiellement ne contient qu'un menu). J'ai essayé un faisant un call bête et méchant mais sans succès...

    Avis à toutes les bonnes volontés qui pourraient m'éclairer.

    Ps : j'ai essayé d'être le plus clair possible. N'hésitez pas à me faire part de votre incompréhension totale

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour

    Déjà, je pense qu'il y a un petit problème de vocabulaire.

    On appelle pas une fonction avec un Call, cela est pour les routines (sub). Une fonction reçoit en général des paramètres (comme une routine), mais retourne une valeur (chaine ou nombre par exemple).

    Comment sais-tu que cette fonction existe, car tu n'as pas accès au code ?

    Il faudrait donc que tu donnes plus de détails.

    Philippe

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 75
    Points : 42
    Points
    42
    Par défaut
    Bonjour Philippe, merci de ta réponse. Effectivement, au niveau clarté c'est pas facile à expliquer.
    J'ai effectivement accès au code de toutes les fonctions présentes dans l'add-in Salesforce pour Excel. Quand j'ouvre la feuille, xla, je l'ajoute comme compléments aux macros d'excel. L'ensemble du code dans VBA est au dessus de VBA Projet dans une autre ensemble salesforces. Dedans, il y'a tous les codes permettant la création du menu, la connexion au CRM, l'ajout de requête,...

    Pour te donner un exemple, voici l'architecture en photo. Je veux faire appel à la fonction sfQueryAll qui est bien présente dans cette feuille et dont voici le code. Je voulais éviter d'avoir a faire un copier coller de l'ensemble du code, car cette fonction fait appel à une autre,... Je pense qu'il y'a plus simple...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Sub sfQueryAll(Optional silent)
      Dim old_pos As Range: Set old_pos = ActiveCell
      Dim used As Range
      Set used = Range("A1", ActiveCell.SpecialCells(xlLastCell).Address)
      If used.Count = 1 Then GoTo done ' nothing on this sheet
      used.Find("*", LookIn:=xlValues).CurrentRegion.Select
     
    '..........  
     
    done:
      old_pos.Select
    End Sub


    Merci à toi pour cet aide.
    Images attachées Images attachées  

  4. #4
    Membre émérite Avatar de Godzestla
    Homme Profil pro
    Chercheur de bonheur
    Inscrit en
    Août 2007
    Messages
    2 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chercheur de bonheur
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2007
    Messages : 2 392
    Points : 2 985
    Points
    2 985
    Par défaut
    Bonjour,

    à toutes fins utiles, il y avait cette discussion, qui est une étape préalable nécessaire.

    Vu que tu appelles une routine à l''extérieur de ton code, il te faut préciser dans ton appel où accéder à cette routine.

    La syntaxe pour appeler cette routine est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application.Run("NomDuProjetVba!Nomdelaroutine", Parametre1,Parametre2,...)
    Donc dans ton cas qqchose du genre (pas testé évidement)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application.Run("TonAddinSalesForce.xla!sfQueryAll", VarSilent)

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 75
    Points : 42
    Points
    42
    Par défaut
    Bonsoir Godzestla,

    Je te remercie vivement pour ta réponse. Désolé, ayant fait le pont, j'avoue avoir bien déconnecté, ceci expliquant ma réponse tardive. Cette solution fonctionne effectivement en appelant la routine (j'aurai appris le vocabulaire indispensable). Par contre, je n'arrive pas à la passer en mode silence.

    Quand j'utilise ta syntaxe, VB me dit attendre :=
    Je ne suis pas assez calé malheureusement pour essayer de passer outre... Si tu as une idée, je suis bien évidemment preneur. Merci encore à toi...

  6. #6
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Points : 12 068
    Points
    12 068
    Billets dans le blog
    8
    Par défaut heu!!!
    bonjour

    si la référence a ton xla est coché dans outil /références
    dans l'éditeur VBA tu n'a cas écrire le nom de la fonction pour l'appeler comme si elle était dans le même projets

    cela dis pour etre sur le!! """application .run """ fonctionne tres bien


    au plaisir

  7. #7
    Membre émérite Avatar de Godzestla
    Homme Profil pro
    Chercheur de bonheur
    Inscrit en
    Août 2007
    Messages
    2 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chercheur de bonheur
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2007
    Messages : 2 392
    Points : 2 985
    Points
    2 985
    Par défaut
    Bonjour,

    Salut Patrick !

    Par contre, je n'arrive pas à la passer en mode silence.
    Avec le peu de code que tu as donné, je ne sais pas ce que fait ou est censé faire le mode silence.
    Je vois juste que le paramêtre est optional.... !

    Peux-tu montrer toute la routine ? merci.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 75
    Points : 42
    Points
    42
    Par défaut
    Bonjour a tous les deux,

    Voici le code complet de la routine. Un peu long, pour cela que je voulais pas tout le mettre au départ :

    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
    Sub sfQueryAll(Optional silent)
      Dim old_pos As Range: Set old_pos = ActiveCell
      Dim used As Range
      Set used = Range("A1", ActiveCell.SpecialCells(xlLastCell).Address)
      If used.Count = 1 Then GoTo done ' nothing on this sheet
      used.Find("*", LookIn:=xlValues).CurrentRegion.Select
     
      Dim r1, c As Range: Set r1 = Selection
      Application.ScreenUpdating = False ' (5.04) quite a show if we dont do this
      For Each c In used.Cells ' include non blank in this range
      If c.Text <> "" Then ' this is not exactly fast, but it works
        Union(r1, c.CurrentRegion).Select
        Set r1 = Selection
      End If
      Next c
      Application.ScreenUpdating = True
     
      If Not IsMissing(silent) Then GoTo ready
     
      Dim msg ' warn the user that they are writing to their worksheet 5.04
      msg = "You are about to QUERY: " & CStr(Selection.Areas.Count) & _
        " tables in the current worksheet, this will overwrite the data in each table"
      If (MsgBox(msg, vbApplicationModal + vbOKCancel + vbExclamation + vbDefaultButton1, _
           "-- Ready to Query Salesforce.com --") = vbCancel) Then GoTo done
     
    ready:
     ' sometimes the areas are not sorted, to be consistent, sort them
     ' start by saving the address of each area 5.21
     Dim myareas() As String: ReDim myareas(Selection.Areas.Count - 1)
     Dim idx%: idx = 0: For Each r1 In Selection.Areas
        myareas(idx) = r1.AddressLocal: idx = idx + 1
     Next r1
     
     ' sort my areas, by their address, puts the left most range first 5.21
     Dim SwapValue, ix, jx   ' sort the list
     For ix = LBound(myareas) To UBound(myareas) - 1
        For jx = ix + 1 To UBound(myareas)
         Dim ixr As Range: Set ixr = Range(myareas(ix))
         Dim jxr As Range: Set jxr = Range(myareas(jx))
         If ixr.Column > jxr.Column Then ' compare addresses note, $B$1 < $AB$1
          SwapValue = myareas(ix): myareas(ix) = myareas(jx): myareas(jx) = SwapValue
          End If
        Next
     Next
     
     'For ix = LBound(myareas) To UBound(myareas): Debug.Print myareas(ix): Next ix
     
      Dim entnames: entnames = s_force.EntityNames
      For ix = LBound(myareas) To UBound(myareas) ' 5.21
        'Debug.Print myareas(ix)
        Dim ar As Range: Set ar = Range(myareas(ix)) ' make the string back into a range
        ' queryall needs to be smart enough to run on workbooks with other
        ' information (not queries) present,
        ' so we check cell(1,1) for a valid entity
        Dim e: For Each e In entnames
          If (LCase(e) = LCase(ar.Cells(1, 1).value)) Then
            ar.Select: Call sfQuery ' what could be easier...
            End If
          Next e
      Next ix
     
    done:
      old_pos.Select
    End Sub
    D'après ce que je comprenais du code, il me semblait que le mode silence permettait d'éviter le message d'alerte. Encore merci de votre aide.

  9. #9
    Membre émérite Avatar de Godzestla
    Homme Profil pro
    Chercheur de bonheur
    Inscrit en
    Août 2007
    Messages
    2 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chercheur de bonheur
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2007
    Messages : 2 392
    Points : 2 985
    Points
    2 985
    Par défaut
    Re,

    d'après ce que je comprend le mode silence est activé si le paramètre est présent (If not ismissing(Silent)). dans ce cas, on saute le msgbox avec demande de confirmation/cancel.

    Essaie de faire l'appel sans ce paramètre et puis avec une quelconque valeur pour voir la différence.

    Donc un truc du genre :

    avec (silence)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application.Run("TonAddinSalesForce.xla!sfQueryAll", "Silence")
    sans (pas de silence)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application.Run("TonAddinSalesForce.xla!sfQueryAll")
    Je n'ai pas testé !!!!!!!!!!!!!

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 75
    Points : 42
    Points
    42
    Par défaut
    Effectivement c'est bien comme cela que je l'avais compris. L'appel a la routine fonctionne sans problème. Mais je voudrais justement supprimer le message d'alerte.

    Mais le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application.Run("TonAddinSalesForce.xla!sfQueryAll", "silent")
    Il me met l'erreur suivante : Erreur de compilation. Attendu :=

    Bon au pire des cas, ce ne sera pas dramatique. Mes collaborateurs cliqueront sur OK. Mais pour plus de simplicité, je voulais sauter cette étape.

  11. #11
    Membre émérite Avatar de Godzestla
    Homme Profil pro
    Chercheur de bonheur
    Inscrit en
    Août 2007
    Messages
    2 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chercheur de bonheur
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2007
    Messages : 2 392
    Points : 2 985
    Points
    2 985
    Par défaut
    Il faut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     variable = application.run ......
    J'ai testé avec ce code. cela fonctionne.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Sub sfQueryAll(Optional silent)
     
      If Not IsMissing(silent) Then
         MsgBox ("present")
        Else
        MsgBox ("absent")
    End If
     
    End Sub
    Sub test_sfq()
    Dim lapin
    lapin = Application.Run(ThisWorkbook.Name & "!sfQueryAll", "yeap")
    lapin = Application.Run(ThisWorkbook.Name & "!sfQueryAll")
    End Sub

    A propos, j'espère que tu n'as pas écrit littéralement ce que tu me montres, à savoir ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application.Run("TonAddinSalesForce.xla!sfQueryAll", "silent")
    car évidement il faut adapter

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 75
    Points : 42
    Points
    42
    Par défaut
    Effectivement cela fonctionne en passant par une variable. Ne t'inquiète pas, je n'avais pas recopié le code tel quel. Par ailleurs, je l'ai ajouté aux références pour plus de simplicités. Pourquoi passer par une variable ? Je ne comprends pas le principe.

  13. #13
    Membre émérite Avatar de Godzestla
    Homme Profil pro
    Chercheur de bonheur
    Inscrit en
    Août 2007
    Messages
    2 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chercheur de bonheur
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2007
    Messages : 2 392
    Points : 2 985
    Points
    2 985
    Par défaut
    Bonjour,
    Pourquoi passer par une variable ? Je ne comprends pas le principe.
    D'après l'aide de Application.run :
    Runs a macro or calls a function. This can be used to run a macro written in Visual Basic or the Microsoft Excel macro language, or to run a function in a DLL or XLL.

    expression.Run(Macro, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10, Arg11, Arg12, Arg13, Arg14, Arg15, Arg16, Arg17, Arg18, Arg19, Arg20, Arg21, Arg22, Arg23, Arg24, Arg25, Arg26, Arg27, Arg28, Arg29, Arg30)
    expression Required. An expression that returns an Application object.
    J'en déduit que VBA ne sait pas interpréter ce que tu exécutes via .run (Procédure, fonction, dll) et donc en standard il exige une expression avec variable de retour pour pouvoir récupérer ce que le .run renvoi, comme indiqué dans l'aide :
    The Run method returns whatever the called macro returns
    .

    Ce n'est pas bien gênant quand on le sait.

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

Discussions similaires

  1. Appel à une fonction d'un autre module
    Par noftal dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 02/09/2013, 12h14
  2. appel d'une fonction depuis un autre fichier?
    Par cortex59 dans le forum C++
    Réponses: 1
    Dernier message: 13/03/2009, 16h19
  3. Appeller une fonction depuis un autre site
    Par ProgVal dans le forum Langage
    Réponses: 3
    Dernier message: 03/12/2008, 19h01
  4. Appeler une dll ou un autre module vba depuis une macro excel vba
    Par technobiz dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 20/11/2008, 15h24
  5. Appel d'une callback depuis un autre module
    Par Bayard dans le forum Général Python
    Réponses: 6
    Dernier message: 08/06/2008, 18h47

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