Comment définir un ou des arguments optionnels lors de l'appel d'une fonction ?
Les fonctions et procédures sont la base de la programmation structurée. L'utilisation de celles-ci va bien sur de pair avec l'utilisation de paramètres, définis lors de la déclaration de la fonction et renseignés lors de l'appel. Ainsi, une fonction classique prenant un paramètre par valeur sera définie et utilisée comme suit : Function Toto(ByVal n As Integer) As Integer Toto = n * 2 End Function
Dim res As Integer res = Toto(4) Telle que définie ci-dessus, il est obligatoire de passer un paramètre à la fonction "Toto" lors de son appel, sans quoi VB générera une erreur de compilation (Argument not optional). Visual Basic offre une fonctionnalité très puissante lors de la définition et de l'appel de fonctions : la possibilité de définir certains paramètres comme optionnels, ce qui permet de les omettre lors de l'appel de la fonction. L'utilisation du mot clé : OptionalIl est parfois utile et pratique de pouvoir définir des paramètres optionnels. Ceci permet par exemple d'alléger le code des appels à la fonction, en laissant la possibilité si le besoin s'en fait sentir de spécifier les paramètres optionnels supplémentaires. En VB, cela se fait tout simplement en faisant précéder la déclaration de l'argument par le mot-clé "Optional". Ainsi, une fonction Toto prenant en paramètres 2 entiers, le second pouvant être omis se déclarera ainsi : Function Toto(ByVal A As Integer, Optional ByVal B As Integer) As Integer End Function
La fonction pourra être appelée en spécifiant ou non le second paramètre. Ainsi, les 2 appels suivants sont corrects : ret = Toto(2, 3) ret = Toto(4) Remarque importante : on peut spécifier plusieurs paramètres optionnels, mais aucun paramètre obligatoire ne peut apparaître derrière un paramètre optionnel. Autrement dit, après un paramètre optionnel, tous les paramètres suivants doivent être aussi optionnels. Si on y réfléchit, c'est logique car sans cela, le compilateur ne pourrait pas savoir quels paramètres sont fournis ou omis. Exemple : Soit à écrire une fonction "IsMultiLine", qui reçoit en entrée une chaîne de caractères et qui retourne TRUE si la chaîne reçue contient un "saut de ligne". Sous Windows, les sauts de lignes sont représentés par la séquence de caractères "CarriageReturn/LineFeed", correspondant à la constante VB : vbCrLf. Il suffit donc à priori de vérifier si la chaîne de caractère contient un vbCrLf. Mais sous d'autre systèmes d'exploitation, Unix par exemple, le saut de ligne est représenté par une autre séquence (un simple LineFeed, vbLf en VB). Il sera donc pratique d'écrire notre fonction de telle sorte que : - Par défaut, elle puisse utiliser vbCrLf comme marqueur de saut de ligne
- Qu'on puisse explicitement lui indiquer, optionnellement, que la chaîne de caractère en entrée est au format Unix et qu'il faut donc utiliser vbLf comme marqueur de saut de ligne.
Public Function IsMultiLine(ByVal Buffer As String, _ Optional ByVal UnixConvention As Boolean) As Boolean Dim LineSeparator As String
LineSeparator = vbCrLf If UnixConvention Then LineSeparator = vbLf End If
IsMultiLine = (InStr(Buffer, LineSeparator) > 0)
End Function
Les appels à cette fonction peuvent alors ressembler à : ret = IsMultiLine(Buffer) ret = IsMultiLine(Buffer, False) ret = IsMultiLine(Buffer, True)
Valeurs par défautQue se passe t-il alors si on omet un paramètre? Si l'on omet un paramètre, celui ci va alors prendre la valeur par défaut correspondant à son type. Si c'est un entier, il vaudra 0, si c'est une chaîne il vaudra "", etc. A noter que pour le type variant, les choses sont un peu différentes : VB dispose de 2 fonctions dédiées (IsMissing et IsEmpty) pour connaître exactement le statut de ces paramètres; ceci est expliqué en détail dans la suite de cet article. VB permet également au programmeur de fournir une valeur par défaut de son choix, qui sera affectée au paramètre si il est omis lors de l'appel. On utilise la syntaxe suivante : Function Toto(ByVal A As Integer, _ Optional ByVal B As Integer = 42) As Integer End Function
Function Toto(ByVal A As Integer, _ Optional ByVal B As String = "HELLO") As Integer End Function
Cette possibilité est non seulement très utile mais son usage est en plus recommandé. En effet, indiquer explicitement une valeur par défaut dans tous les cas est une bonne habitude car cela rend le code plus clair à lire et à maintenir. Le prototype de notre fonction "IsMultiLine" devrait être écrit comme suit : Public Function IsMultiLine(ByVal Buffer As String, _ Optional ByVal UnixConvention As Boolean = False) As Boolean
Comment savoir si un paramètre optionnel a été fourni ou non ?On a vu dans le paragraphe précédent qu'il est recommandé de fournir de toute façon une valeur par défaut, ce qui permet en pratique de ne pas devoir se soucier de cela. Pour être complet, mentionnons l'existence de la fonction IsMissing(), qui permet de savoir si un paramètre optionnel de type variant a été fourni ou non. NOTE : cette fonction ne renvoie un résultat correct QUE pour les paramètres optionnels de type VARIANT, dont l'usage est déconseillé. La fonction IsEmpty() quand à elle permet de savoir si une variable de type variant a été ou non initialisée (si on lui a ou non affecté une valeur). Voici un exemple d'utilisation de ces 2 fonction : Public Function Titi(ByVal A As Integer, _ Optional ByVal B As Variant) As Boolean If IsMissing(B) Then MsgBox "le paramètre B n Else If IsEmpty(B) Then MsgBox "le paramètre B a été passé en paramètre, SANS avoir été initialisé." Else MsgBox "le paramètre B a été passé en paramètre et vaut : " & B End If End If End Function
Passage d'un nombre quelconque d'arguments optionnels : ParamArrayVB permet également de définir une fonction qui accepte (optionnellement) un nombre quelconque de paramètres. Ces paramètres seront lus dans un tableau de variant de taille variable. Un ParamArray est toujours le dernier paramètre d'une fonction. Exemple : une fonction "FuzzySum" qui prend un nombre quelconque d'arguments et en retourne la somme Private Function FuzzySum(ParamArray t()) As Long
Dim i As Long Dim sum As Long
If Not IsMissing(t) Then For i = LBound(t()) To UBound(t()) sum = sum + t(i) Next i End If FuzzySum = sum End Function
Dim ret As Long
ret = FuzzySum() Debug.Print ret ret = FuzzySum(1, 2, 3) Debug.Print ret ret = FuzzySum(1, 2, 3, 4, 5, 6) Debug.Print ret Pour ou contre les arguments optionnels ?Cette question fait débat... C'est une fonctionnalité qui s'avère pratique dans bien des cas, en permettant notamment d'écrire des fonctions très paramétrables sans pour autant forcer le passage systématique de tous les paramètres, ce qui parfois peut rendre la lecture du code "indigeste". La contre-partie est que cette possibilité peut également être source d'erreurs ou d'incompréhension : La lecture du code de l'appel de la fonction ne permet pas de connaître de façon certaine la définition exacte de la fonction (et donc ses fonctionnalités) puisque certains paramètres peuvent avoir été omis lors de l'appel. Sans prendre partie, on peut néanmoins faire remarquer que ce serait une bonne pratique que de mentionner par un commentaire placé près de l'appel de la fonction que la dite fonction possède des paramètres optionnels non fournis, en invitant le lecteur à se référer à la définition de la fonction pour plus de détails. On pourrait écrire : ret = IsMultiLine(Buffer) ... Pour aller plus loin
Voir aussi : |