🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA Optional Parameter dans Excel — valeurs par défaut, IsMissing, arguments nommés et ParamArray

|

VBA Optional Parameter dans Excel — valeurs par défaut, IsMissing, arguments nommés et ParamArray

TL;DR — Optional permet à l'appelant d'omettre un argument : Sub Export(ByVal path As String, Optional ByVal addDate As Boolean = True) peut s'appeler Export "C:\Out" ou Export "C:\Out", False. Donnez une valeur par défaut à chaque Optional typé, et c'est réglé. La seule règle à connaître : un Optional typé ne peut pas distinguer « non passé » de « passé avec la valeur par défaut », et IsMissing ne fonctionne que sur un Variant sans valeur par défaut. Utilisez une valeur par défaut quand omettre l'argument revient à passer cette valeur ; n'utilisez un Variant et IsMissing que lorsque l'omettre signifie quelque chose qu'aucune valeur ne peut exprimer. Et quand une procédure a besoin d'une nouvelle entrée, ajoutez-la en Optional à la fin, avec l'ancien comportement comme valeur par défaut : tous les appelants existants continuent de fonctionner.

Sub ExportReport(ByVal folder As String, Optional ByVal addDate As Boolean = True)
    Dim fileName As String
    fileName = "Report"
    If addDate Then fileName = fileName & " " & Format(Date, "yyyy-mm-dd")
    Debug.Print folder & "\" & fileName & ".pdf"
End Sub

' ExportReport "C:\Out"             -> C:\Out\Report 2026-10-01.pdf
' ExportReport "C:\Out", False      -> C:\Out\Report.pdf

Voici le dernier volet d'une série de trois sur l'endroit où vit une valeur. Une variable globale est partagée par tout le projet jusqu'à sa réinitialisation ; une variable Static est la mémoire privée d'une procédure. Un paramètre Optional est le plus étroit de tous : l'appelant fournit la valeur pour un seul appel, ou laisse la valeur par défaut s'appliquer. C'est aussi le plus facile à croire, car on voit d'où vient la valeur en lisant l'appel.

Ce que vous allez apprendre

  • Le modèle mental : un Optional est un champ de formulaire avec une valeur par défaut déjà imprimée
  • Les règles de déclaration, et pourquoi la valeur par défaut doit être une constante
  • La seule règle : un Optional typé ne distingue pas l'omission de la valeur par défaut
  • IsMissing avec un Variant, et quand c'est le bon choix
  • Sauter des arguments, et pourquoi les arguments nommés rendent les noms de paramètres définitifs
  • ParamArray pour un nombre quelconque de valeurs, et le piège de la retransmission
  • Optional, le moyen sûr de modifier une procédure que tout le monde appelle déjà

Le modèle mental : un champ de formulaire avec une valeur par défaut imprimée

Un paramètre obligatoire est un champ vide que l'appelant doit remplir. Un paramètre Optional est un champ où une valeur est déjà imprimée : l'appelant peut écrire par-dessus ou la laisser telle quelle. Dans les deux cas, la procédure reçoit toujours une valeur. Cette image explique toutes les règles qui suivent : la valeur imprimée doit être connue avant que quiconque remplisse le formulaire, elle doit venir après les champs obligatoires, et une fois imprimée, la procédure ne peut plus savoir si l'appelant l'a laissée telle quelle ou a réécrit la même chose par-dessus.

Déclarer des paramètres Optional : les règles

Function Discount(ByVal amount As Double, _
                  Optional ByVal rate As Double = 0.1, _
                  Optional ByVal roundTo As Long = 2) As Double
    Discount = Round(amount * (1 - rate), roundTo)
End Function
  • Optional se place avant ByVal ou ByRef, et la valeur par défaut après le type : = 0.1.
  • Tous les Optional viennent après tous les paramètres obligatoires. Dès qu'un paramètre est Optional, tous les paramètres qui le suivent doivent l'être aussi.
  • La valeur par défaut doit être une expression constante : un nombre, une chaîne, True, une constante que vous avez déclarée. Optional asOf As Date = Date provoque une erreur de compilation (« Constant expression required »), car Date est une fonction qui s'exécute plus tard. Omettez la valeur par défaut et remplissez-la plutôt en tête de la procédure :
Sub Snapshot(Optional ByVal asOf As Date)
    If asOf = 0 Then asOf = Date     ' 0 signifie non fourni - on prend alors la date du jour
    Debug.Print Format(asOf, "yyyy-mm-dd")
End Sub

Un paramètre objet sans valeur par défaut arrive sous la forme Nothing, ce qui rend facile le « utilise la feuille active sauf indication contraire » : Optional ws As Worksheet, puis If ws Is Nothing Then Set ws = ActiveSheet.

Dans une fonction de feuille, les paramètres Optional se comportent de la même façon : =Discount(A2) utilise les deux valeurs par défaut, et =Discount(A2, 0.2) en remplace une. Le guide Function couvre le reste de la conception des fonctions personnalisées (UDF).

La seule règle : un Optional typé ne distingue pas l'omission de la valeur par défaut

Reprenez Snapshot. Si l'appelant ne passe rien, asOf vaut 0. Si l'appelant passe 0 exprès, asOf vaut aussi 0. La procédure ne peut pas les distinguer, et c'est vrai de tout Optional typé : un Long omis vaut 0, un String omis vaut "", un Boolean omis vaut False — ou la valeur par défaut que vous avez déclarée.

La plupart du temps, c'est exactement ce que vous voulez. « L'omettre » et « passer la valeur par défaut » devraient signifier la même chose, et une valeur par défaut rend le comportement de la procédure évident dès sa première ligne. Le problème survient quand le fait que l'appelant l'omette doit signifier quelque chose qu'aucune valeur du type ne peut exprimer. Un cas typique : un filtre dont la valeur par défaut est « aucun filtre », alors que 0 et "" sont des valeurs réelles sur lesquelles quelqu'un pourrait vouloir filtrer.

IsMissing : quand l'omission doit avoir un sens

Dans ce cas, déclarez le paramètre comme un Variant sans valeur par défaut, et interrogez IsMissing :

Function CountWhere(rng As Range, Optional ByVal match As Variant) As Long
    Dim c As Range, n As Long
    For Each c In rng
        If IsMissing(match) Then
            If Not IsEmpty(c.Value) Then n = n + 1   ' pas de filtre : compter les cellules remplies
        ElseIf c.Value = match Then
            n = n + 1                                ' filtre, meme sur 0 ou ""
        End If
    Next c
    CountWhere = n
End Function

IsMissing pose deux conditions, et enfreindre l'une ou l'autre lui fait discrètement renvoyer False pour toujours :

  • Le paramètre doit être un Variant. Sur un Long ou un String, IsMissing vaut toujours False.
  • Le paramètre ne doit avoir aucune valeur par défaut. Optional match As Variant = "" n'est jamais manquant, car la valeur par défaut le remplit.

Mon jugement : ne sortez IsMissing que lorsque l'absence est un vrai troisième état. Si vous ne l'utilisez que pour remplir une valeur par défaut en tête de la procédure, déclarez plutôt la valeur par défaut typée : la signature documente alors le comportement, et le compilateur vérifie le type.

Sauter des arguments, et les arguments nommés

Pour sauter un Optional au milieu, laissez son emplacement vide, ou nommez l'argument que vous passez :

Debug.Print Discount(200, , 0)            ' taux par defaut, arrondi a 0 decimale
Debug.Print Discount(200, roundTo:=0)     ' la meme chose, et lisible
Debug.Print Discount(amount:=200, rate:=0.25)

Les arguments nommés utilisent := et le nom du paramètre, dans n'importe quel ordre. C'est le choix lisible dès qu'une procédure a plus d'un Optional, car , , 0 ne dit rien de quelle valeur correspond à quoi. Ils ont une conséquence que l'on rate souvent : dès qu'un appelant utilise roundTo:=, le nom du paramètre fait partie de l'interface. Renommer roundTo en decimals compile sans problème dans la procédure et casse tous les appelants qui l'ont nommé, avec « Named argument not found » (argument nommé introuvable). Choisissez les noms des Optional avec autant de soin que les noms de procédures.

ParamArray : un nombre quelconque de valeurs

Quand l'appelant doit pouvoir passer autant de valeurs qu'il le souhaite, utilisez ParamArray. Il doit être le dernier paramètre, il doit être un tableau de Variant, et il ne peut pas être combiné avec Optional dans la même procédure :

Function SumAll(ParamArray values() As Variant) As Double
    Dim i As Long, total As Double
    For i = LBound(values) To UBound(values)
        total = total + values(i)
    Next i
    SumAll = total
End Function

' SumAll(1, 2, 3)  -> 6
' SumAll()         -> 0   (UBound vaut -1, la boucle ne s'execute donc jamais)

Le piège, c'est la retransmission. Si SumAll veut transmettre ses valeurs à une seconde procédure ParamArray, Other values ne les déplie pas : Other reçoit un seul argument, qui est le tableau entier. Écrivez plutôt l'auxiliaire pour qu'il prenne un Variant ordinaire contenant un tableau, et bouclez dessus là-bas. Le guide UBound couvre les bornes qui rendent les tableaux vides sûrs.

Le jugement : Optional, c'est ainsi qu'une procédure grandit sans rien casser

Ce qu'Optional apporte de plus utile, ce n'est pas le confort. C'est la compatibilité. Supposons que ExportReport folder soit appelée depuis douze boutons et trois autres macros, et qu'un rapport doive maintenant se passer de la date. Changer la signature pour ajouter un nouveau paramètre obligatoire casse quinze appelants. Ajouter Optional ByVal addDate As Boolean = True n'en casse aucun, car la valeur par défaut correspond exactement à ce qu'ils obtenaient avant, et le seul nouvel appelant passe False.

Mes règles :

  • Les nouvelles entrées vont à la fin, en Optional, avec l'ancien comportement comme valeur par défaut.
  • Préférez une valeur par défaut typée à IsMissing, sauf si « non fourni » est un vrai troisième état.
  • Au-delà de deux ou trois Optional, les appelants devraient utiliser des arguments nommés, et il vaut la peine de se demander si la procédure ne fait pas deux travaux qui devraient être deux procédures, dans l'esprit du guide Sub.
  • N'utilisez jamais une variable globale pour transmettre un réglage à une procédure qui pourrait le recevoir en Optional. L'argument est visible dans l'appel ; la globale n'est visible nulle part.

Comment ExcelMaster vous aide

Les bogues de paramètres Optional se cachent dans les appels : un filtre qui ne s'applique jamais parce qu'IsMissing a été interrogé sur un String, un renommage qui casse tous les appelants utilisant des arguments nommés, une procédure à laquelle on a ajouté un paramètre obligatoire et qui a cassé les boutons qui l'appellent.

ExcelMaster vous laisse décrire la modification, par exemple « permets à cet export de se passer de la date pour le rapport mensuel ». Il ajoute l'entrée en Optional avec l'ancien comportement comme valeur par défaut, pour que les appelants existants continuent de fonctionner, et vérifie chaque appel dans le projet.

Questions fréquentes

Comment rendre un paramètre facultatif en VBA ?

Placez Optional devant lui dans la déclaration et donnez-lui une valeur par défaut : Optional ByVal rate As Double = 0.1. Il doit venir après tous les paramètres obligatoires, et tout paramètre qui le suit doit être Optional lui aussi. Les appelants peuvent alors l'omettre, et la procédure reçoit la valeur par défaut.

Pourquoi IsMissing renvoie-t-il toujours False ?

IsMissing ne fonctionne que lorsque le paramètre Optional est un Variant sans valeur par défaut. Pour un paramètre typé comme Long ou String, ou un Variant avec une valeur par défaut, VBA remplit une valeur quand l'argument est omis : il n'est donc jamais manquant.

Un paramètre Optional peut-il prendre la date du jour par défaut ?

Pas directement, car une valeur par défaut doit être une constante et Date est une fonction. Déclarez Optional asOf As Date sans valeur par défaut, puis écrivez If asOf = 0 Then asOf = Date en tête de la procédure.

Comment sauter un argument facultatif au milieu ?

Laissez sa position vide avec une virgule, comme dans Discount(200, , 0), ou utilisez des arguments nommés, comme dans Discount(200, roundTo:=0). Les arguments nommés sont plus clairs et peuvent être donnés dans n'importe quel ordre.

Qu'est-ce que ParamArray en VBA ?

ParamArray permet à une procédure d'accepter un nombre quelconque d'arguments sous la forme d'un seul tableau de Variant, comme Function SumAll(ParamArray values() As Variant). Il doit être le dernier paramètre et ne peut pas être utilisé avec des paramètres Optional. Parcourez-le avec LBound et UBound ; quand aucun argument n'est passé, UBound vaut -1.

Testé dans

Testé dans : Excel 365 (Windows 11), VBA 7.1 — dernière vérification le 01/10/2026.

Guides associés : VBA Global Variable · VBA Static Variable · VBA Function · VBA Sub · VBA ByRef contre ByVal · VBA UBound · VBA Format · VBA Save as PDF