Comment ajouter une valeur dans un Variant en VBA

En VBA, le type Variant est un type de données spécial et très souple : il peut contenir n’importe quel type de données (à l’exception des chaînes de longueur fixe), y compris des références d’objet, des tableaux, des dates, des nombres, et des valeurs spéciales comme Empty, Error, Nothing et Null. Comprendre comment ajouter une valeur dans un Variant, et comment gérer les Variant qui référencent des objets (Variant/Object/Range) est essentiel pour écrire des fonctions robustes, utilisables aussi bien depuis VBA que depuis une feuille Excel.

Déclarer une variable Variant et autres types d’objet

Vous devez déclarer une variable avant de pouvoir l’utiliser. Utilisez l’instruction Dim (ou Public, Private, Static) pour déclarer une variable :

  • Dim MyObject As Variant ' Déclaré en tant que Variant
  • Dim MyObject As Object ' Déclaré en tant qu’Object générique
  • Dim MyObject As Font ' Déclaré comme type d’objet spécifique

Une variable qui fait référence à un objet doit être un Variant, un Object ou un type spécifique d’objet. Vous pouvez déclarer une variable objet avec le type de données Object lorsque le type d’objet spécifique n’est pas connu avant l’exécution de la procédure. Si vous connaissez le type d’objet spécifique, vous devez déclarer la variable objet en tant que ce type.

Affecter une valeur ou un objet à une variable Variant

Pour affecter une valeur simple à un Variant, utilisez l’opérateur = :

  • Dim v As Variant
  • v = 123
  • v = "Texte"

Pour affecter un objet à une variable objet, utilisez l’instruction Set :

Lire aussi: guide pour ajouter une valeur dans une colonne via un trigger

  • Set MyObject = YourObject ' Assigner la référence d’objet
  • Set MyObject = Nothing ' Rompre l’association

Vous pouvez combiner la déclaration d’une variable objet avec l’affectation d’un objet à celle-ci à l’aide du mot clé New avec l’instruction Set. L’affectation de la valeur Nothing à une variable objet interrompt l’association de la variable objet à un objet spécifique. Une variable objet est toujours définie sur Nothing après la fermeture de l’objet associé afin que vous puissiez tester si la variable objet pointe vers un objet valide.

Variant contenant un Range : pourquoi Variant/Object/Range ?

Si l’input d’une fonction est un Range Excel, le Variant correspondant peut s’afficher dans un espion comme Variant/Object/Range et contenir l’ensemble des caractéristiques du Range (formatage, police, couleur, taille de colonnes, etc.). C’est différent d’un Variant/Variant qui contient uniquement les valeurs. Cela se produit parce que lorsque vous passez directement une référence Range à une fonction (par exemple MyFunc(Sheet1.Range("A1:K12"))), Excel transmet la référence de l’objet Range, et non seulement les valeurs.

Conséquences :

  • Travailler sur le Range (la référence) permet d’accéder à des propriétés et méthodes du Range (Format, Font, Interior, etc.).
  • Si vous avez besoin uniquement des valeurs, vous pouvez extraire la propriété .Value ou .Value2 pour obtenir un tableau de valeurs (Variant/Variant).
  • Si vous voulez normaliser l’input pour supporter à la fois une plage passée directement et une matrice créée en VBA, vous pouvez forcer la conversion en Variant contenant les valeurs via CVar(matrice) ou en utilisant matrice = matrice.Value2.

Exemples pratiques

Recevoir une plage en paramètre de fonction :

  • Function Recup_data(matrice As Variant)
  • ' Si matrice est un Range, matrice sera un Variant/Object/Range
  • ' Pour obtenir seulement les valeurs : If TypeName(matrice) = "Range" Then matrice = matrice.Value2
  • End Function

Conversion explicite pour uniformiser le type :

Lire aussi: Choisir le bon condensateur pour une alimentation LED sans transformateur

  • matrice = CVar(matrice) ' Convertit en Variant contenant les valeurs

Utiliser Set et Nothing pour les objets :

  • Dim obj As Object
  • Set obj = ThisWorkbook.Sheets("Feuil1").Range("A1")
  • ' ... utilisation ...
  • Set obj = Nothing ' libère la référence

Tester et détecter le contenu d’un Variant

Différentes fonctions aident à déterminer ce qu’un Variant contient :

  • IsEmpty(var) - teste si la variable est Empty (non initialisée).
  • IsNull(var) - teste si la variable contient Null.
  • IsError(var) - teste si la variable contient une erreur.
  • TypeName(var) - renvoie le type sous forme de chaîne (ex : "Range", "Variant()", "String").

Exemple :

  • If TypeName(matrice) = "Range" Then matrice = matrice.Value2
  • If IsArray(matrice) Then ' traiter comme tableau End If

Travailler avec des tableaux Variant

Un Variant peut contenir un tableau. Vous pouvez déclarer et redimensionner des tableaux Variant :

  • Dim Tablo() As Variant
  • ReDim Preserve Tablo(0 To 6, 0 To Ind) ' Exemple de redimensionnement multi-dimensionnel

Deux façons courantes de créer des tableaux de valeurs Variant :

Lire aussi: Comment obtenir plus de schémas de craft

  1. Attribuer .Value ou .Value2 d’un Range à un Variant : matrice = Range("A1:C3").Value2 - cela renvoie un tableau 2D Variant contenant uniquement les valeurs.
  2. Créer la matrice manuellement en VBA : Dim m(1 To N, 1 To M) As Variant et remplir les éléments.

Bonnes pratiques

  • Si possible, déclarez le type d’objet spécifique (ex : Dim MyFont As Font) pour bénéficier du typage fort et de l’IntelliSense.
  • Quand une fonction est destinée à être appelée depuis une feuille Excel (UDF), acceptez Variant et gérez les cas Range vs tableau vs valeur scalaire à l’intérieur de la fonction.
  • Utilisez .Value2 pour récupérer les données d’un Range sans conversions automatiques de Date (Value2 n’applique pas la conversion de date basée sur l’objet Date de VBA).
  • Si vous voulez forcer qu’un Variant contienne uniquement des données (pas un objet), utilisez matrice = matrice.Value2 ou matrice = CVar(matrice) selon le contexte.
  • Libérez les références d’objets avec Set ... = Nothing pour éviter les fuites de références.

Cas pratiques issus d’expériences réelles

Problème rencontré : en plaçant un espion sur "matrice" on obtient Variant/Object/Range avec toutes les caractéristiques du Range initial (format, police, tailles). Ce comportement est normal lorsque l’on passe un Range directement comme input à la fonction (ex : MaFonction(A1:B2)).

Solutions testées :

  • Créer d’abord une variable intermédiaire : Set tmp = Sheet1.Range("A1:K12") puis appeler MaFonction tmp - parfois change le comportement selon la manière dont Excel transmet la référence.
  • Utiliser matrice = matrice.Value2 à l’entrée de la fonction : cela transforme le Variant/Object/Range en un Variant/Variant (tableau de valeurs).
  • Utiliser CVar(matrice) pour forcer la conversion en Variant contenant les valeurs sans conserver la référence Range.

Remarque pratique : Si l’input est déjà une matrice créée en VBA, alors matrice et matrice_N2 (après conversion) seront identiques. Si l’input est un Range, alors matrice sera Variant/Object/Range et matrice_N2 (après Value2 ou CVar) sera Variant/Variant.

Exemple de fonction UDF robuste

Voici un modèle de fonction qui accepte un Range ou un tableau, et opère sur les valeurs :

' Function Recup_data(matrice As Variant) ...

Idée clé : détecter si l’input est un Range puis récupérer .Value2. Ensuite, traiter le Variant comme tableau si IsArray renvoie True.

[🟢 LIVE] เกิดอะไรขึ้น ทำไมคนส่วนใหญ่ทำผิดพลาดในช่วงเวลานี้ ?

Résumé des outils utiles

Outil Utilité
Dim ... As Variant Déclare une variable pouvant contenir n’importe quel type
TypeName(variable) Connaître le type concret (ex : "Range", "Variant()", "String")
IsArray(variable) Tester si Variant contient un tableau
Variable = Range.Value2 Obtenir uniquement les valeurs du Range (tableau Variant)
Set obj = Nothing Rompre la référence d’objet
CVar(variable) Forcer la conversion en Variant

En appliquant ces principes, vous pourrez écrire des fonctions flexibles utilisables directement depuis Excel (en sélectionnant une plage comme input) ou depuis VBA, tout en évitant les confusions entre Variant contenant un objet Range et Variant contenant un tableau de valeurs.

balises:

Articles populaires: