TOP
VBA-Leçon 9. Procédures et fonctions
Dans tout langage de programmation, il existe des concepts tels que des procédures et des fonctions. Ils ont également été inclus dans le langage de programmation intégré VBA pour Excel.
Une fonction est une routine qui renvoie un résultat. Un appel de fonction est une expression et peut être utilisé dans d'autres expressions ou sur le côté droit d'une instruction d'affectation (notée dans VBA par "Function") ;
Une procédure est toute routine qui n’est pas une fonction. Marqué dans VBA comme "Sub" (du mot "sous-programme").
Procédures (Public - Private)
À ce stade, toutes les procédures que nous avons créées sont de type Public, ce qui signifie qu'elles sont accessibles depuis n'importe quel module.
- Sub example()
-
-
- Public Sub example()
Sub example()
'Identique à:
Public Sub example()
Pour rendre la procédure disponible uniquement dans un certain module, le mot-clé Private est utilisé :
Private Sub example()
Exécuter une procédure au milieu d'une autre procédure
Pour exécuter une procédure depuis une autre procédure, il suffit de saisir son nom.
En voici un exemple très simple :
- Private Sub warning()
- MsgBox "Caution !!!"
- End Sub
-
- Sub macro_test()
- If Range("A1") = "" Then
- warning
- End If
-
- End Sub
Private Sub warning()
MsgBox "Caution !!!" '"AVERTISSEMENT!"
End Sub
Sub macro_test()
If Range("A1") = "" Then
warning '=> exécuter la procédure "warning"
End If
'etc...
End Sub
Arguments
Les arguments permettent d'utiliser les valeurs d'une procédure dans une sous-procédure (rappelons que par défaut, les variables ne sont disponibles que depuis la procédure dans laquelle elles ont été déclarées).
- Private Sub warning(var_text As String)
- MsgBox "Caution : " & var_text & " !"
- End Sub
-
- Sub macro_test()
- If Range("A1") = "" Then
- warning "empty cell"
- ElseIf Not IsNumeric(Range("A1")) Then
- warning "non-numerical value"
- End If
- End Sub
Private Sub warning(var_text As String)
MsgBox "Caution : " & var_text & " !"
End Sub
Sub macro_test()
If Range("A1") = "" Then
warning "empty cell" '"cellule vide"
ElseIf Not IsNumeric(Range("A1")) Then
warning "non-numerical value" '"valeur non numérique"
End If
End Sub
Un argument a été ajouté à la procédure "warning", dans ce cas il s'agit d'une variable "var_text" de type "String" (ruban) :
- Private Sub warning(var_text As String)
Private Sub warning(var_text As String)
Cette routine prend un argument, nous devons donc mettre une valeur après "warning" pour l'exécuter :
warning "empty cell"
Lorsque nous voulons écrire plusieurs arguments, ils doivent alors être séparés par des virgules.
Arguments facultatifs
Par défaut, si la procédure a des arguments, alors ils doivent être fournis, et s'ils ne le sont pas, alors la procédure ne sera pas exécutée.
Un argument facultatif peut être ajouté après un argument obligatoire, à l'aide du mot-clé Optionnel. Exemple:
- Private Sub dialog_boxes(last_name As String, Optional first_name, Optional age)
Private Sub dialog_boxes(last_name As String, Optional first_name, Optional age)
Cette procédure peut désormais être exécutée avec ou sans argument optionnel, comme ici :
-
- dialog_boxes last_name1
-
-
- dialog_boxes last_name1, first_name1
-
-
- dialog_boxes last_name1, , age1
-
-
- dialog_boxes last_name1, first_name1, age1
'Exemple 1 : afficher le nom :
dialog_boxes last_name1
'Exemple 2 : on affiche le nom et le prénom :
dialog_boxes last_name1, first_name1
'Exemple 3 : afficher le nom et l'âge :
dialog_boxes last_name1, , age1
'Exemple 4 : afficher le nom, le prénom et l'âge :
dialog_boxes last_name1, first_name1, age1
Les arguments doivent être saisis dans le bon ordre.
Pour tester si un argument facultatif est présent dans une procédure, nous utilisons la fonction IsMissing. Cette fonction n'est compatible qu'avec certains types de fonctions (de type Variant) et cela est critique car le type des arguments optionnels n'a pas été déclaré (type non déclaré = Variant).
Voici un exemple qui utilise les deux extraits de code évoqués ci-dessus :
- Sub macro_test()
-
- Dim last_name1 As String, first_name1 As String, age1 As Integer
-
- last_name1 = Range("A1")
- first_name1 = Range("B1")
- age1 = Range("C1")
-
-
- dialog_boxes last_name1
-
-
- dialog_boxes last_name1, first_name1
-
-
- dialog_boxes last_name1, , age1
-
-
- dialog_boxes last_name1, first_name1, age1
-
- End Sub
-
- Private Sub dialog_boxes(last_name As String, Optional first_name, Optional age)
-
- If IsMissing(age) Then
-
- If IsMissing(first_name) Then
-
- MsgBox last_name
- Else
- MsgBox last_name & " " & first_name
- End If
-
- Else
-
- If IsMissing(first_name) Then
-
- MsgBox last_name & ", " & age & " years old"
- Else
- MsgBox last_name & " " & first_name & ", " & age & " years old"
- End If
-
- End If
-
- End Sub
Sub macro_test()
Dim last_name1 As String, first_name1 As String, age1 As Integer
last_name1 = Range("A1")
first_name1 = Range("B1")
age1 = Range("C1")
'Exemple 1 : afficher le nom :
dialog_boxes last_name1
'Exemple 2 : on affiche le nom et le prénom :
dialog_boxes last_name1, first_name1
'Exemple 3 : afficher le nom et l'âge :
dialog_boxes last_name1, , age1
'Exemple 4 : afficher le nom, le prénom et l'âge :
dialog_boxes last_name1, first_name1, age1
End Sub
Private Sub dialog_boxes(last_name As String, Optional first_name, Optional age)
If IsMissing(age) Then 'Si la variable âge est manquante...
If IsMissing(first_name) Then 'Si la variable prénom_nom est manquante, alors
'seul le nom de famille sera affiché
MsgBox last_name
Else 'Sinon, le nom et le prénom seront affichés
MsgBox last_name & " " & first_name
End If
Else 'Si la variable âge est présente...
If IsMissing(first_name) Then 'Si la variable prénom_nom est manquante, alors
'le nom de famille et l'âge seront affichés
MsgBox last_name & ", " & age & " years old"
Else 'Dans le cas contraire, le nom, le prénom et l'âge seront affichés
MsgBox last_name & " " & first_name & ", " & age & " years old"
End If
End If
End Sub
Voir image ci-dessous (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, une référence à celle-ci sera également transmise. En d’autres termes, si une variable a été modifiée par une autre sous-procédure, elle sera également modifiée dans la procédure externe qui appelle cette sous-procédure.
Exemple:
- Sub macro_test()
- Dim var_number As Integer
-
- var_number = 30
- calcul_square var_number
-
- MsgBox var_number
- End Sub
-
- Private Sub calcul_square(ByRef var_value As Integer)
-
- var_value = var_value * var_value
- End Sub
Sub macro_test()
Dim var_number As Integer
var_number = 30
calcul_square var_number
MsgBox var_number
End Sub
Private Sub calcul_square(ByRef var_value As Integer) 'ByRef est facultatif
'(c'est la valeur par défaut)
var_value = var_value * var_value
End Sub
Pour que ce soit clair, voici un exemple de ce qui se passera si l’exécution de la macro démarre :
- var_number = 30
-
-
- calcul_square var_number
-
-
- Private Sub calcul_square(ByRef var_value As Integer)
-
-
-
- var_value = var_value * var_value
-
-
- End Sub
-
-
- MsgBox var_number
-
var_number = 30
'La valeur initiale de la variable "var_number" est 30
calcul_square var_number
'La sous-procédure est exécutée avec "var_number" comme argument
Private Sub calcul_square(ByRef var_value As Integer)
'La variable "var_value" sert dans une certaine mesure à un accès rapide à la variable "var_number",
'ce qui signifie que si la variable "var_value" est modifiée, la variable "var_number" sera également modifiée
'(et ils ne doivent pas nécessairement avoir le même nom)
var_value = var_value * var_value
'La valeur de la variable "var_value" est modifiée (et donc "var_number" est également modifiée en même temps)
End Sub
'Fin de la sous-procédure
MsgBox var_number
'La variable "var_number" a été modifiée donc 900 sera désormais affiché dans la boîte de dialogue
La deuxième méthode consiste à utiliser ByVal.
Contrairement à ByRef, qui passe une référence (libellé), ByVal passe une valeur, ce qui signifie que la valeur passée en argument n'a pas été modifiée.
Ci-dessous, vous pouvez voir comment fonctionnent le code précédent et ByVal :
- var_number = 30
-
-
- calcul_square var_number
-
-
- Private Sub calcul_square(ByVal var_value As Integer)
-
-
- var_value = var_value * var_value
-
-
- End Sub
-
-
- MsgBox var_number
-
var_number = 30
'La valeur initiale de la variable "var_number" est 30
calcul_square var_number
'La sous-procédure est exécutée avec "var_number" comme argument
Private Sub calcul_square(ByVal var_value As Integer)
'La variable "var_value" copie la valeur de la variable "var_number" (les 2 variables ne sont pas liées)
var_value = var_value * var_value
'La valeur de la variable "var_value" a changé
End Sub
'Fin de la sous-procédure (dans cet exemple la sous-procédure n'a aucun effet)
MsgBox var_number
'La variable "var_number" n'a pas été modifiée et donc 30 sera affiché dans la boîte de dialogue
Ce que vous devez retenir : utilisez ByVal lorsque la variable ne doit pas être modifiée.
Les fonctions
La principale différence entre une procédure et une fonction est qu'une fonction renvoie une valeur.
Voici un exemple simple :
- Function square(var_number)
- square = var_number ^ 2
- End Function
-
- Sub macro_test()
- Dim result As Double
- result = square(9.876)
- MsgBox result
- End Sub
Function square(var_number)
square = var_number ^ 2 'La fonction "carré" renvoie la valeur "racine carrée"
End Function
Sub macro_test()
Dim result As Double
result = square(9.876) 'La variable de résultat reçoit la valeur calculée par la fonction
MsgBox result 'Le résultat s'affiche (dans ce cas le carré de 9,876)
End Sub
La fonction peut être utilisée sur une feuille de calcul comme n'importe quelle autre fonction dans Excel.
Par exemple, pour obtenir le carré de la valeur saisie dans la cellule A1 :