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 SubIci, 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
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, age1Les 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 type 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 SubAperçu (exemple 1) :
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 SubPour 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 SubLes 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 :

