Cours VBA : les procédures et fonctions

Public - Private

Pour le moment, toutes les procédures créées sont de type Public, elles sont accessibles depuis tous les modules.

Sub exemple()
'Identique à :
Public Sub exemple()

Pour rendre une procédure inaccessible hors du module, ajoutez Private :

Private Sub exemple()

Lancer une procédure depuis une procédure

Pour exécuter une procédure depuis une autre procédure, entrez simplement son nom.

Un exemple simple :

Private Sub avertissement()
    MsgBox "Attention !!!"
End Sub

Sub macro_test()
    If Range("A1") = "" Then
        avertissement ' <= exécute la procédure "avertissement"
    End If
    'etc ...
End Sub

Ici, lorsque "macro_test" est exécutée et que A1 vaut "", la procédure "avertissement" est exécutée.

Les arguments

Les arguments permettent d'utiliser des valeurs d'une procédure dans une sous-procédure (car rappelez-vous que par défaut les variables ne sont pas accessibles depuis les autres procédures).

Private Sub avertissement(texte As String)
    MsgBox "Attention : " & texte & " !"
End Sub

Sub macro_test()
    If Range("A1") = "" Then
        avertissement "cellule vide"
    ElseIf Not IsNumeric(Range("A1")) Then
        avertissement "valeur non numérique"
    End If
End Sub
test - procedures fonctions

Un argument a été ajouté à la procédure "avertissement", il s'agit de la variable "texte" de type "String" :

Private Sub avertissement(texte As String)

Cette procédure nécessite un argument, il faudra donc placer une valeur après "avertissement" pour l'exécuter :

avertissement "cellule vide"

En cas d'arguments multiples, ceux-ci doivent être séparés par des virgules.

Les arguments optionnels

Par défaut, si une procédure requiert des arguments, ceux-ci sont obligatoires pour exécuter la procédure.

Des arguments optionnels peuvent être ajoutés après les arguments obligatoires avec Optional, par exemple :

Private Sub boite_de_dialogue(nom As String, Optional prenom, Optional age)

Cette procédure peut alors être lancée avec ou sans arguments optionnels, comme ceci :

'Exemple 1 : on affiche le nom :
boite_de_dialogue nom1
   
'Exemple 2 : on affiche le nom et le prénom :
boite_de_dialogue nom1, prenom1
   
'Exemple 3 : on affiche le nom et l'âge :
boite_de_dialogue nom1, , age1
   
'Exemple 4 : on affiche le nom, le prénom et l'âge :
boite_de_dialogue nom1, prenom1, age1

Les arguments doivent être indiqués dans l'ordre.

Pour vérifier si un argument optionnel est présent ou non, nous utiliserons la fonction IsMissing. Cette fonction n'étant compatible qu'avec certains types de variables (dont Variant), le type des arguments optionnels n'a pas été déclaré (type non déclaré = Variant).

Voici un exemple avec les 2 portions de code ci-dessus :

Sub macro_test()

    Dim nom1 As String, prenom1 As String, age1 As Integer
   
    nom1 = Range("A1")
    prenom1 = Range("B1")
    age1 = Range("C1")

    'Exemple 1 : on affiche le nom :
    boite_de_dialogue nom1
   
    'Exemple 2 : on affiche le nom et le prénom :
    boite_de_dialogue nom1, prenom1
   
    'Exemple 3 : on affiche le nom et l'âge :
    boite_de_dialogue nom1, , age1
   
    'Exemple 4 : on affiche le nom, le prénom et l'âge :
    boite_de_dialogue nom1, prenom1, age1

End Sub

Private Sub boite_de_dialogue(nom As String, Optional prenom, Optional age)
   
    If IsMissing(age) Then 'Si la variable age est absente ...
       
        If IsMissing(prenom) Then 'Si la variable prenom est absente, on n'affiche que le nom
           MsgBox nom
        Else 'Sinon, on affiche le nom et le prénom
           MsgBox nom & " " & prenom
        End If
       
    Else 'Si la variable age est présente ...

        If IsMissing(prenom) Then 'Si la variable prenom est absente, on affiche le nom et l'âge
           MsgBox nom & ", " & age & " ans"
        Else 'Sinon on affiche le nom, le prénom et l'âge
           MsgBox nom & " " & prenom & ", " & age & " ans"
        End If
   
    End If
       
End Sub

Aperçu (exemple 1) :

test2 - procedures fonctions

ByRef - ByVal

Par défaut, les arguments sont de type ByRef ce qui signifie que, si une variable est passée en argument, c'est sa référence qui est transmise. Autrement dit, si la variable est modifiée dans la sous-procédure, elle le sera également dans la procédure d'appel.

Par exemple :

Sub macro_test()
    Dim nombre As Integer
    nombre = 30
   
    calcul_carre nombre
   
    MsgBox nombre
End Sub

Private Sub calcul_carre(ByRef valeur As Integer) 'Il n'est pas nécessaire de préciser ByRef (puisque par défaut)
    valeur = valeur * valeur
End Sub

Pour mieux comprendre, voici ce qui se passe lorsque la macro est lancée :

nombre = 30
'La valeur initiale de la variable "nombre" est 30

calcul_carre nombre
'La sous procédure est lancée avec la variable "nombre" en argument

Private Sub calcul_carre(ByRef valeur As Integer)
'La variable "valeur" est en quelque sorte un raccourci vers la variable "nombre", par conséquent, si la variable "valeur" est modifiée, cela modifie la variable "nombre" (il n'est pas nécessaire de les nommer de façon identique)

valeur = valeur * valeur
'La valeur de la variable "valeur" est modifiée (donc la variable "nombre" est modifiée)

End Sub
'Fin de la sous-procédure

MsgBox nombre
'La variable "nombre" a été modifiée, 900 est alors affiché dans la boîte de dialogue

La seconde possibilité consiste à utiliser ByVal.

Contrairement à ByRef qui transmet la référence (raccourci), ByVal transmet la valeur, ce qui signifie que la variable passée en argument ne subit aucune modification.

Voici ce qui se passe avec le code précédent et ByVal :

nombre = 30
'La valeur initiale de la variable "nombre" est 30

calcul_carre nombre
'La sous procédure est lancée avec la variable "nombre" en argument

Private Sub calcul_carre(ByVal valeur As Integer)
'La variable "valeur" copie la valeur de la variable "nombre" (les 2 variables ne sont pas liées)

valeur = valeur * valeur
'La valeur de la variable "valeur" est modifiée

End Sub
'Fin de la sous-procédure (dans cet exemple, la sous-procédure n'aura servi à rien)

MsgBox nombre
'La variable "nombre" n'a pas été modifiée, 30 est donc affiché dans la boîte de dialogue

Ce qu'il faut retenir : utiliser ByVal lorsque la variable ne doit pas être modifiée ...

Les fonctions

La principale différence entre une procédure Sub et Function est la valeur retournée par la fonction.

En voici un exemple simple :

Function carre(nombre)
    carre = nombre ^ 2 'La fonction "carre" renvoie la valeur de "carre"
End Function

Sub macro_test()
    Dim resultat As Double
    resultat = carre(9.876) 'La variable resultat reçoit la valeur retournée par la fonction
    MsgBox resultat 'Affiche le résultat (ici, le carré de 9.876)
End Sub

Les fonctions peuvent également être utilisées sur la feuille comme n'importe quelle fonction Excel.

Par exemple, pour obtenir le carré de la valeur de A1 :

carre - procedures fonctions
Télécharger ce cours au format PDF