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 :

Appel de fonction et de procédure [Toutes versions]


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
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 24
    Par défaut Appel de fonction et de procédure
    Bonjour,

    D'après mes tests et mes recherches, on peut appeler une procédure / fonction de plusieurs manières.

    Est-ce que certaines sont plus "propres" que d'autres, est-ce que certaines sont à éviter ?
    Y a-t-il d'autres moyens d’appeler une fonction / procédure que j'aurais omis dans le code ci-dessous ?

    Cas 1 : procédure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Sub MaProcedure()
    'mon code
    End Sub
     
    Sub MacroPrincipale
    MaProcedure 'Methode 1
    Call MaProcedure 'Methode 2
    End Sub
    Cas 2 : fonction sans argument
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Function MaFonction() As Integer
    'mon code
    End Function
     
    Sub MacroPrincipale
    MaFonction 'Methode 1
    Call MaFonction 'Methode 2
    i = MaFonction 'Methode 3
    End Sub
    Cas 3 : fonction avec arguments
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Function MaFonction(argu As Integer) As Integer
    'mon code
    End Function
     
    Sub MacroPrincipale
    MaFonction 47 'Methode 1
    Call MaFonction(47) 'Methode 2
    i = MaFonction(47) 'Methode 3
    End Sub
    Merci d'avance pour vos réponses.

  2. #2
    Expert confirmé
    Avatar de kiki29
    Homme Profil pro
    ex Observeur CGG / Analyste prog.
    Inscrit en
    Juin 2006
    Messages
    6 132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : ex Observeur CGG / Analyste prog.

    Informations forums :
    Inscription : Juin 2006
    Messages : 6 132
    Par défaut
    Salut, à lire, entre autres : Les syntaxes de base Initiation au VBA Office

  3. #3
    Membre chevronné Avatar de pasdechances
    Homme Profil pro
    Alternant, Ingénieur en systèmes Informatiques et Industriels
    Inscrit en
    Septembre 2015
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Alternant, Ingénieur en systèmes Informatiques et Industriels
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Septembre 2015
    Messages : 218
    Par défaut
    Bonjour,

    Tout dépend de l'utilisation que tu veux en faire.

    les méthodes que tu as la sont toutes correctes.(homris le i = mafonction quand tu retourne rien le i est vide)
    Dire si elles sont plus propre je ne sais pas.
    pense juste a ton besoin, si tu a besoin d'une fonction qui a une valeur en entrée et 0 en sortie tu fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Function MaFonction(argu As Integer)
    et si c'est l'inverse,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Function MaFonction()as integer
    'tu doit retourner la valeur en gros dire se que vaut ta fonction ^^ sa marche aussi pour ton cas 3 tu l'avais pas mis
    MaFonction = 1
    end function

  4. #4
    Membre Expert
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Septembre 2013
    Messages
    783
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2013
    Messages : 783
    Par défaut
    Bonjour,

    J'y vais sans complètement vérifier:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MaProcedure 'Methode 1
    Call MaProcedure 'Methode 2
    => Les deux sont équivalents

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Function MaFonction() As Integer
    'mon code
    End Function
     
    Sub MacroPrincipale
    MaFonction 'Methode 1
    Call MaFonction 'Methode 2
    i = MaFonction 'Methode 3
    End Sub
    Call MaFonction ne retourne rien ... donc je ne vois pas vraiment l'intérêt
    i = MaFonction: correct (i integer)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Function MaFonction(argu As Integer) As Integer
    'mon code
    End Function
     
    Sub MacroPrincipale
    MaFonction 47 'Methode 1
    Call MaFonction(47) 'Methode 2
    i = MaFonction(47) 'Methode 3
    End Sub
    Attention: si vous ne spécifiez rien, les arguments sont passés par référence et non pas par valeur

    ByVal : tout changement fait sur les arguments seront perdus
    ByRef Any: le contraire, les arguments peuvent être modifiés par la procédure

    MaFonction 47 ne retourne rien, Call MaFonction(47) devrait je pense générer une erreur
    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Msgansw = MsgBox("La feuille " & wsname & " n'existe pas dans " & wbk.Name & vbCrLf & _
                    "Voulez-vous la créer?", vbExclamation + vbOKCancel, Funcname)
    ' On récupère le retour de la Msgbox
     
    MsgBox "Error: " & Err.Number & vbCrLf & Err.Description, vbCritical, Funcname
    'Mais pas ici (sans parenthèses)
    N'oubliez pas que vous pouvez définir des arguments optionnels ou définir des valeur par défaut

    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
    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
    Function Exist_sheet(wsname As String, Optional prompt_ifN_exisit As Boolean = False, Optional wbk As Variant) As Boolean
    '=============================================================================
    ' Check if a sheet exists in the specified workbook (ThisWorkbook by default)by an access and create it if not (optional)
    ' This function could replace the 2 previous functions: chk_exist_sheet and create_sheet
     
        Funcname = "Func: Exist_sheet"
     
        Dim Msgansw As String, Wsh As Worksheet
     
        On Error GoTo Err_notexist
     
            ' Set the default values
        Exist_sheet = False
        If IsMissing(wbk) Then Set wbk = ThisWorkbook
     
            ' Test by access to the sheet, return true if succeeded, or test the Error 9
        If wbk.Worksheets(wsname).Range("A1").Address <> "" Then Exist_sheet = True
     
    Err_notexist:
     
            ' Expected Error raised when acceeding to an not existing sheet
        If Err.Number = 9 Then
            Msgansw = vbOK
            If prompt_ifN_exisit = True Then
                Msgansw = MsgBox("The sheet " & wsname & " doesn't exist in " & wbk.Name & vbCrLf & _
                    "Would you like to create it?", vbExclamation + vbOKCancel, Funcname)
            End If
     
                ' Create it if not existing depending on users inputs or option
            If Msgansw <> vbCancel Or prompt_ifN_exisit = False Then
     
                Set Wsh = Worksheets.Add(After:=wbk.ActiveSheet)
                Wsh.Name = wsname
                Wsh.Tab.Color = vbGreen
     
                    ' Test by access to the sheet, return true if succeeded
                If wbk.Worksheets(wsname).Range("A1").Address <> "" Then Exist_sheet = True
            End If
            Err.Clear
     
                ' Return false if another error
        Else:
            If Err.Number > 0 Then
                MsgBox "Error: " & Err.Number & vbCrLf & Err.Description, vbCritical, Funcname
                Exist_sheet = False
                Err.Clear
            End If
        End If
    End Function

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

    Une fonction retourne une valeur ou un tableau de valeurs et même, elle peut retourner les deux, (voir ci-dessous) donc, l'appeler sans récupérer ce qu'elle retourne n'a aucun sens :
    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
     
    Sub MacroPrincipale()
     
        Dim I As Long
     
        MaFonction 'Methode 1 <-- ne sert à rien car la valeur retournée n'est pas utilisée !
        Call MaFonction 'Methode 2 <-- ne sert à rien non plus car idem !
        I = MaFonction 'Methode 3 <-- c'est la bonne méthode
     
        MsgBox I
     
    End Sub
     
    Function MaFonction() As Long
     
        'la valeur Long de la date du jour
        MaFonction = CLng(Date)
     
    End Function
     
    Sub MacroPrincipalePourTableau()
     
        Dim Tablo() As Long
        Dim I As Integer
        Dim Mot As String
     
        Mot = "Ceci est une chaîne !"
     
        Tablo = MaFonctionTableau(Mot) 'Methode 3 <-- c'est la bonne méthode
     
        For I = 1 To UBound(Tablo)
     
            Debug.Print Tablo(I)
     
        Next I
     
        MsgBox Mot
     
    End Sub
     
     
    Function MaFonctionTableau(Argument As String) As Long()
     
        Dim Tbl() As Long
        Dim I As Integer
     
        For I = 1 To 20
     
            ReDim Preserve Tbl(1 To I)
     
            Tbl(I) = I * 1000
     
        Next I
     
        Argument = "oui mais ici je le modifie !"
     
        'la valeur Long de la date du jour
        MaFonctionTableau = Tbl()
     
    End Function
    En ce qui concerne les procédures Sub, l'appel peut se faire avec ou sans Call c'est au choix, c'est comme l'instruction Rem (pour remarque) qui permet de mettre un commentaire afin d'expliquer le code tout comme le fait l'apostrophe, qui est majoritairement utilisé mais rien n'empêche d'utiliser Rem, le compilateur sait l'interpréter.

  6. #6
    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
    A pasdechances,
    les méthodes que tu as la sont toutes correctes.(homris le i = mafonction quand tu retourne rien le i est vide)
    Là, je dirais que justement, c'est tout le contraire "I = MaFonction" est la seule qui est logique car appeler une fonction sans récupérer ce qu'elle retourne de sert à rien !
    Dire que I est vide c'est faux la preuve :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Sub MacroPrincipale()
     
        Dim I
        I = MaFonction
        MsgBox I 'ici, ce n'est pas rien, puisque la fonction retourne un entier, I aura comme valeur 0
     
    End Sub
     
    Function MaFonction() As Integer
    'mon code
    End Function
    avec un contrôle de la variable :
    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 MacroPrincipale()
     
        Dim I
     
        If IsEmpty(I) Then MsgBox "Vide !"
     
        I = MaFonction
     
        If Not IsEmpty(I) Then MsgBox "Pas vide !"
     
        MsgBox I 'ici, ce n'est pas rien, puisque la fonction retourne un entier, I aura comme valeur 0
     
    End Sub
     
    Function MaFonction() As Integer
    'mon code
    End Function

  7. #7
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 24
    Par défaut
    Merci pour vos réponses.

    Donc pour résumer :
    - "Call" ne sert à rien, c'est juste pour faire joli (et pour la lisibilité du code)
    - Utiliser une fonction qui ne retourne rien n'a aucun sens, il vaut mieux dans ce cas là utiliser une procédure "Sub". C'est une question de logique/cohérence du programmeur, même si VBA est capable de gérer les deux.

  8. #8
    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 173
    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 173
    Billets dans le blog
    53
    Par défaut
    Bonjour,
    "Call" ne sert à rien, c'est juste pour faire joli (et pour la lisibilité du code)
    C'est simplement une autre syntaxe. Je préfère la syntaxe sans le Call
    Utiliser une fonction qui ne retourne rien n'a aucun sens, il vaut mieux dans ce cas là utiliser une procédure "Sub".
    C'est une question de choix. Je privilégie de plus en plus l'emploi de fonction et que j'utilise comme Sub ou comme Function qui renvoie par exemple TRUE (opération réussie) ou FALSE (Echec).
    MSGBOX est par exemple une fonction native du VBA que l'on peut utiliser comme une SUB ou comme une fonction (Function)
    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

  9. #9
    Membre Expert Avatar de antonysansh
    Homme Profil pro
    Chargé d'études RH
    Inscrit en
    Mai 2014
    Messages
    1 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Chargé d'études RH
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2014
    Messages : 1 115
    Par défaut
    Bonjour tout le monde

    Puis qu'on est dans les bonnes pratiques sur la déclaration de Sub ou de Function j'ajoute quelque chose.

    Avec Function MaFonction(argu As Integer) As Integer il faut être très vigilant car tu ne précises pas si c'est ByVal ou ByRef.
    Par défaut c'est du ByRef.

    Avec ByVal c'est une copie de la valeur passée en paramètre qui est utiliser. Avec ByRef c'est la valeur elle-même (on pointe directement sur celle-ci)
    Je t'invite à tester le code suivant :
    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
    Function doubler_val(ByVal n As Long) As Long
        n = n * 2
        doubler_val = n
    End Function
     
    Function doubler_ref(ByRef n As Long) As Long
        n = n * 2
        doubler_ref = n
    End Function
     
    Sub test()
        Dim n_val&, n_ref&, res_val&, res_ref
        n_val = 5:    n_ref = 5
        res_val = doubler_val(n_val):    res_ref = doubler_ref(n_ref)
            Debug.Print "n_val -> " & n_val
            Debug.Print "res_val -> " & res_val
            Debug.Print "n_ref -> " & n_ref
            Debug.Print "res_ref -> " & res_ref
            Debug.Print "------------------"
    End Sub
    Tu peux voir que dans un cas n_val n'est pas modifié alors que n_ref l'est.

    PS : Avant toutes remarques, doubler_ref = n*2 résoudrait ce faux problème mais il s'agit 'un exemple.

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

    Il y a aussi Excel.Run et VBA.CallByName qui permettent d'appeler une procédure. Et éventuellement Excel.Application.OnTime dans certains cas.



    EDIT: Ce que j'avais écris a déjà été écrit au dessus. J'ai supprimé.
    Dernière modification par Invité ; 03/10/2015 à 11h46.

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

Discussions similaires

  1. Appeler une fonction dans une procédure stockée
    Par Guizmo95 dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 29/05/2012, 19h59
  2. Réponses: 2
    Dernier message: 30/08/2011, 17h41
  3. Réponses: 0
    Dernier message: 27/04/2009, 16h13
  4. Appel de fonction dans une procédure stockée
    Par Nuloprog dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 22/12/2008, 16h00
  5. [VBA-E] Appel de fonction/procédure depuis une variable
    Par truman dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 09/05/2006, 16h20

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