Je n'avais pas encore fait d'article sur la fonction LET et si vous êtes un lecteur de mes articles vous avez du constaté que je l'utilise souvent. J'en profite pour vous proposer une fonction personnalisée et une procédure aidant à analyser les résultats générés dans les fonctions LET.
Présentation de la fonction
Objet de la fonction
Au lieu d'utiliser plusieurs cellules/colonnes/lignes d'Excel pour réaliser des calculs intermédiaires, on va pouvoir les générer directement dans la fonction et réutiliser ces résultats "intermédiaires" pour faire un calcul final.
Tout comme en programmation, on va déclarer des variables et leurs valeurs remplaçant ces cellules/colonnes/lignes intermédiaires puis les utiliser pour un calcul final.
Syntaxe
Officielle
= LET(Nom1 ; Nom_valeur1 ; Calcul_ou_nom2 ; [Nom_valeur2 ; Calcul_ou_nom3...])
Personnelle
= LET(NomVariable1 ; ValeurVariable1 [ ; NomVariable2 ; ValeurVariable2]...[ ; NomVariable126 ; ValeurVariable126] ; Calcul_Final)Arguments :
- NomVariable1 à 126 ; ValeurVariable126 : 126 paires de valeurs, seule la 1ère paire est obligatoire.
- NomVariable : Nom de la variable.
- Il doit être unique parmi les Noms définis.
- Ne doit pas commencer par un chiffre.
- Les caractères suivants sont interdits : espace & " ' ( - ) = ~ # { [ | ` ^ @ ] } % * , ; : ! . / +
- Ne doit pas correspondre à une référence de cellules : "Cas" >OK, "Cas1" > KO (2073eme colonne, ligne 1).
- ValeurVariable : Valeur, expression, formule.
- Ne peut utiliser une variable que si celle-ci est définie précédemment (attention à l’ordre de déclaration).
- NomVariable : Nom de la variable.
- Calcul_Final : Formule dont la valeur sera renvoyée par la fonction LET.
Remarque :
- En cas de conflit (même nom) entre le nom d'une variable déclaré dans la fonction LET et un nom déclaré (via le gestionnaire de noms par exemple), c'est celui déclaré dans la fonction LET qui sera utilisé par la fonction LET (il en est de même avec un nom de fonction en conflit).
Exemples d'utilisation
Exemple 1
Objectif : Récupérer dans une liste unique les personnes entre 50 et 90 ans présent dans 2 listes distinctes.
Version classique
= ASSEMB.V({"Nom"."Age"};
FILTRE(Liste1;(Liste1[Age]>50)*(Liste1[Age]<90));
FILTRE(Liste2;(Liste2[Age]>50)*(Liste2[Age]<90)))
Version LET
= LET(AgeMini;50;AgeMaxi;90;
Liste1;FILTRE(Liste1;(Liste1[Age]>AgeMini)*(Liste1[Age]<AgeMaxi));
Liste2;FILTRE(Liste2;(Liste2[Age]>AgeMini)*(Liste2[Age]<AgeMaxi));
Resultat;ASSEMB.V({"Nom"."Age"};Liste1;Liste2);
Resultat)La version LET offre plusieurs avantages :
- Plus lisible.
- Centralisation des valeurs de seuil (50 et 90) permettant une mise à jour facile et rapide de la formule en cas de changement (2 changements au lieu de 4)
- Pour faciliter cette mise à jour, j'ai pris l'habitude de centraliser sur la 1ère ligne les valeurs "utilisateurs" (valeur, références cellules/plages).
- Pour faciliter le contrôle des valeurs intermédiaires calculées via les variables, je place souvent le résultat final dans une variable (ici "Resultat"). Il suffira de remplacer la dernière ligne par "Liste1" ou "Liste2" pour visualiser ces valeurs intermédiaires.
Exemple 2
Objectif : Calculer le montant d'une prime en fonction des ventes (moins de 1 000 € alors pas de prime, entre 1 000 et 2 000 € 5% du montant, plus de 2 000 € 7%).
Version classique
= SI(SOMME(TabVentes[MtVentes])<1000;
"Pas de prime";
SI(SOMME(TabVentes[MtVentes])<2000;
"Prime de " & TEXTE(SOMME(TabVentes[MtVentes])*5%;"# ##0,00 €");
"Prime de " & TEXTE(SOMME(TabVentes[MtVentes])*7%;"# ##0,00 €")))
Version optimisée
= SI(SOMME(TabVentes[MtVentes])<1000;
"Pas de prime";
"Prime de " & TEXTE(SI(SOMME(TabVentes[MtVentes])<2000;
SOMME(TabVentes[MtVentes])*5%;
SOMME(TabVentes[MtVentes])*7%);
"# ##0,00 €"))
Version LET
= LET(Total;SOMME(TabVentes[MtVentes]);
SI(Total<1000;
"Pas de prime";
"Prime de " & TEXTE(SI(Total<2000;Total*5%;Total*7%);"# ##0,00 €")))La fonction TEXTE est là pour obtenir un formatage en Euros (le formatage classique est inutilisable ici vu que le résultat final est du texte et non une valeur numérique).
La version LET dans ce cas permet d'éviter de calculer plusieurs fois la même formule SOMME(TabVentes[MtVentes]) et ainsi d'obtenir une formule plus courte, plus rapide à calculer et un fichier plus petit.
Autres exemples
- Contrôler la validité d'un RIB français, IBAN français, n° Sécurité Sociale (NIR).
- Traduire un nombre en lettres sans VBA
- Additions et soustractions au delà du mur des Billions
- Manipuler des dates avant 1900, c'est possible !
Exemple à éviter : Rendre illisible une formule 😁
Basé sur de l'exemple 1.
=LET(x;50;u;90;c;FILTRE;z;Liste1[Age];e;Liste2;o;Liste1;b;Liste2[Age];k;ASSEMB.V;r;c(o;(z>x)*(z<u));g;c(e;(b>x)*(b<u));n;k({"Nom"."Age"};r;g);n)- Utilisation de nom pour les "Nom de variable" non expressif.
- Ordre de déclaration des variables illogique.
- Utilisation de la fonction cachée des variables permettant même de remplacer les noms des fonctions.
- ici c remplace le nom de fonction FILTRE : c(o;(z>x)*(z<u)) correspond donc à FILTRE(o;(z>x)*(z<u)).
- Pourrait quand même être utile dans certain cas notamment avec la fonction LIREDONNEESTABCROISDYNAMIQUE (nom un peu long😁).
Formule certes plus courte mais difficilement maintenable (modifiable par la suite).
Outils de débogage
Je vous propose :
- Une Fonction à appeler dans une cellule et générant une matrice en résultat.
➕ Facile à utiliser, mise à jour automatique.
➖ Ne fonctionnant qu'à partir d'une cellule contenant une formule. - Une Procédure à exécuter manuellement et générant une nouvelle feuille en résultat.
➕ Fonctionne aussi à partir d'une cellule contenant le texte d'une formule.
➖ Mise à jour manuelle en réexécutant la procédure.
Pour utiliser ces outils plus facilement vous pourriez :
- Placer la fonction dans un classeur Complément (.xlam) chargé au démarrage d'Excel.
- Placer la procédure dans le classeur de macros personnelles.
La fonction
Nécessite la présence des fonctions utilitaires présentées plus bas.
Utilisation
Fonction de test en B4 :
=LET(
cstNum;5,2;
cstTxt;"1forme ; "".fr";
cstTxt2;"1fo[r[m'e.#@fr";
cstMat1;{"ee";"m[;@{'}'[mm"};
cstMat2;{5;6};
cstMat3;{1.3,5.7;2.4.-6};
cellule1;A1;
cellule2;'Fe;u''il2'!B2;
cellule3;'Fe''''u,il4'!B2;
cellule4;'Feu"il5'!B2;
nom;UnNom;
refStruct1;Tableau1[A;''{g"e];
refStruct2;Tableau1[Vi''l'[le];
refStruct3;Tableau1[[A;''{g"e]:[Vi''l'[le]];
plage;A1:B3;
form1;4/0;
form2;5+cstNum+NBCAR(cstTxt);
form3;LET(v_1;SOMME(NBCAR(cstMat1));v_2;INDEX(cstMat3;1;2);v_1+v_2);
form4;cellule1+SOMME(plage);
formMat;INDEX(plage;2;0);
form2+form3)Formule dans la cellule de destination :
=EvalLET(B4)Résultat :

(La mise en forme a été ajoutée manuellement)
Code
Public Function EvalLET(cellRef As Range, Optional Separator) As Variant
' Objectif : Générer une matrice des paramètres (Nom, définition et valeur) de la fonction LET sélectionnée
' Utilisation : Comme une fonction classique d'Excel. Commencer à saisir "=EvalLET(" dans la cellule de destination.
' > cellRef : La cellule contenant la fonction LET
' > Separator : Facultatif, le séparateur utilisé (par défaut, celui configuré dans Excel)
' Retour : Matrice de 3 colonnes (Nom, définition et valeur).
' Auteur : Arnaud (www.1forme.fr).
' Licence : CC-BY-NC-SA (Vous pouvez diffuser/partager/modifier cette macro dans les
' même conditions, seulement à titre personnel et citant l'auteur/site d'origine.
Dim strF As String, strFL As String ' Texte de la formule version US (nécessaire pour eval)/FR (Locale)
Dim intPosPar As Integer ' Position de la parenthèse ouvrante de =LET(
Dim strInsideF As String, strInsideFL As String ' Texte entre les parenthèses de la formule version US/FR (Locale)
Dim strPartsF() As String, strPartsFL() As String ' Texte des arguments version US/FR (Locale)
Dim dicVars As Object ' Dico des variables pour les substituer dans les définitions
Dim out() As Variant ' Tableau résultats
Dim i As Long, lgNbVar As Long
Dim strVarName As String ' Nom de la variable
Dim strDefF As String, strDefFL As String ' Définition de la variable version US/FR (Locale)
Dim strDefF2 As String ' Définition de la variable version US avec remplacement des variables
Dim varValV As Variant ' Valeur de la variable
Dim strDerDef As String
If IsMissing(Separator) Then Separator = Application.International(xlListSeparator)
strF = cellRef.Formula2
strFL = cellRef.Formula2Local
intPosPar = InStr(1, strF, "(") + 1
If Replace(Left$(strF, intPosPar - 1), " ", "") <> "=LET(" Then EvalLET = "#NOT_LET_FUNCTION!": Exit Function
' Contenu interne du LET() anglais et français
strInsideF = Mid$(strF, intPosPar, Len(strF) - intPosPar)
strInsideFL = Mid$(strFL, intPosPar, Len(strFL) - intPosPar)
' Découpage intelligent top-level
strPartsF = SplitTopLevel(strInsideF, ",")
strPartsFL = SplitTopLevel(strInsideFL, Separator)
lgNbVar = (UBound(strPartsF) + 1) \ 2 + 1 ' Nombre total éléments LET
ReDim out(0 To lgNbVar, 0 To 2)
' Entêtes
out(0, 0) = "Paramètre"
out(0, 1) = "Définition"
out(0, 2) = "Valeur"
Set dicVars = CreateObject("Scripting.Dictionary")
' Évaluer chaque variable
For i = 0 To lgNbVar - 2
strVarName = strPartsF(2 * i)
strDefF = strPartsF(2 * i + 1)
strDefFL = "=" & strPartsFL(2 * i + 1)
strDefF2 = ReplaceLETVariables(strDefF, dicVars) ' On remplace les variables déjà définies
varValV = Evaluate2(strDefF2)
If TypeName(varValV) <> "Error" Then
If TypeName(varValV) = "String" And Left(varValV, 1) <> "{" Then ' Chaîne mais pas matrice, doublement des "
varValV = """" & Replace(varValV, """", """""") & """"
End If
End If
dicVars.Add strVarName, varValV ' Ajout au dico
' Tableau final
out(i + 1, 0) = strVarName
out(i + 1, 1) = strDefFL
out(i + 1, 2) = varValV
Next i
' Résultat final LET
strDerDef = strPartsF(UBound(strPartsF))
strDerDef = ReplaceLETVariables(strDerDef, dicVars) ' On remplace les variables déjà définies
out(lgNbVar, 0) = "Formule finale"
out(lgNbVar, 1) = "=" & strPartsFL(UBound(strPartsFL))
out(lgNbVar, 2) = Evaluate2(strDerDef)
EvalLET = out
End FunctionLa procédure
Nécessite la présence des fonctions utilitaires présentées plus bas.
Utilisation
On sélectionne la fonction de test en B4 dans la feuille "dev" puis on exécute la macro/procédure "AnalyseLET".
Résultat :

Ici on pourrait sélectionner la cellule B19 (contient du texte et non une formule) pour relancer la macro mais elle échouera du fait de la non-définition des variables "cstMat1" et "cstMat3" (extérieures à cette fonction LET). Dans ce cas, la feuille de réponse ayant déjà été créée Excel vous demandera si vous voulez la supprimer.
Code
Public Sub AnalyseLET()
' Objectif : Génère la liste des paramètres (Nom, définition et valeur) de la fonction LET sélectionnée dans une nouvelle feuille
' Utilisation : Sélectionner la cellule contenant la formule ou le texte représentant la fonction LET à analyser puis lancer la macro.
' Retour : Tableau de 3 colonnes (Nom, définition et valeur) dans une nouvelle feuille ayant comme suffixe l'adresse de la cellule.
' Auteur : Arnaud (www.1forme.fr).
' Licence : CC-BY-NC-SA (Vous pouvez diffuser/partager/modifier cette macro dans les
' même conditions, seulement à titre personnel et citant l'auteur/site d'origine.
Dim strF As String, strFL As String ' Texte de la formule version US (nécessaire pour eval)/FR (Locale)
Dim intPosPar As Integer ' Position de la parenthèse ouvrante de =LET(
Dim strInsideF As String, strInsideFL As String ' Texte entre les parenthèses de la formule version US/FR (Locale)
Dim strPartsF() As String, strPartsFL() As String ' Texte des arguments version US/FR (Locale)
Dim dicVars As Object ' Dico des variables pour les substituer dans les définitions
Dim i As Long, lgNbVar As Long
Dim strVarName As String ' Nom de la variable
Dim strDefF As String, strDefFL As String ' Définition de la variable version US/FR (Locale)
Dim strDefF2 As String ' Définition de la variable version US avec remplacement des variables
Dim varValV As Variant ' Valeur de la variable
Dim strDerDef As String
Dim objWs As Worksheet
Dim objActivWs As Worksheet
Dim strWsName As String
Dim strSeparator As String
If ActiveCell.HasFormula Then
strF = ActiveCell.Formula2
strFL = ActiveCell.Formula2Local
Else
strF = ActiveCell.Value2 ' Dans ce cas c'est en réalité la version local (FL) !
End If
intPosPar = InStr(1, strF, "(") + 1
If Replace(Left$(strF, intPosPar - 1), " ", "") <> "=LET(" Then MsgBox "Pas LET": Exit Sub
strSeparator = Application.International(xlListSeparator)
Set objActivWs = ActiveSheet
strWsName = "Let_" & objActivWs.Name & "_" & ActiveCell.Address(False, False)
On Error Resume Next
Set objWs = ActiveWorkbook.Sheets(strWsName)
On Error GoTo erreur
If objWs Is Nothing Then ' La feuille n'existe pas, on la crée
Set objWs = ActiveWorkbook.Sheets.Add
objWs.Name = strWsName
Else
objWs.Cells.Clear ' La feuille existe, on efface son contenu
End If
objActivWs.Activate
If strFL = "" Then ' Génération d'un nom pour récupérer la version US
objWs.Range("A2").Formula2Local = strF
strFL = strF
strF = objWs.Range("A2").Formula
objWs.Range("A2").ClearContents
End If
' Contenu interne du LET() anglais et français
strInsideF = Mid$(strF, intPosPar, Len(strF) - intPosPar)
strInsideFL = Mid$(strFL, intPosPar, Len(strFL) - intPosPar)
' Découpage intelligent top-level
strPartsF = SplitTopLevel(strInsideF, ",")
strPartsFL = SplitTopLevel(strInsideFL, strSeparator)
lgNbVar = (UBound(strPartsF) + 1) \ 2 + 1 ' Nombre total éléments LET
' Entêtes
objWs.Range("A1").Value = "Paramètre"
objWs.Range("B1").Value = "Définition"
objWs.Range("C1").Value = "Valeur"
Set dicVars = CreateObject("Scripting.Dictionary")
' Évaluer chaque variable
For i = 0 To lgNbVar - 2
strVarName = strPartsF(2 * i)
strDefF = strPartsF(2 * i + 1)
strDefFL = "'=" & strPartsFL(2 * i + 1)
strDefF2 = ReplaceLETVariables(strDefF, dicVars) ' On remplace les variables déjà définies
varValV = Evaluate2(strDefF2)
If TypeName(varValV) <> "Error" Then
If TypeName(varValV) = "String" And Left(varValV, 1) <> "{" Then ' Chaîne mais pas matrice, doublement des "
varValV = """" & Replace(varValV, """", """""") & """"
End If
End If
dicVars.Add strVarName, varValV ' Ajout au dico
' Tableau final
objWs.Range("A" & i + 2).Value = strVarName
objWs.Range("B" & i + 2).Value = strDefFL
objWs.Range("C" & i + 2).Value = varValV
Next i
' Résultat final LET
strDerDef = strPartsF(UBound(strPartsF))
strDerDef = ReplaceLETVariables(strDerDef, dicVars) ' On remplace les variables déjà définies
objWs.Range("A" & lgNbVar + 1).Value = "Formule finale"
objWs.Range("B" & lgNbVar + 1).Value = "'=" & strPartsFL(UBound(strPartsFL))
objWs.Range("C" & lgNbVar + 1).Value = Evaluate2(strDerDef)
objWs.Columns("A:B").EntireColumn.AutoFit ' 3eme colonne non ajusté volontairement
fin:
Set objWs = Nothing
Set objActivWs = Nothing
Exit Sub
erreur:
If Not objWs Is Nothing Then objWs.Delete
GoTo fin
End SubFonctions utilitaires
Ces fonctions sont nécessaires pour les 2 solutions Procédure et Fonction.
Private Function ReplaceLETVariables(ByVal strDef As String, ByVal dicVars As Object) As String
' Remplace les variables dans les définitions
' Appellée par : EvalLET / AnalyseLET
Dim i As Long, n As Long
Dim strChar As String, strIdent As String
Dim boInString As Boolean
Dim strResult As String
i = 1
n = Len(strDef)
While i <= n
strChar = Mid$(strDef, i, 1)
' Gestion des chaînes
If strChar = """" Then
boInString = Not boInString
strResult = strResult & strChar
i = i + 1
GoTo NextChar
End If
If boInString Then
strResult = strResult & strChar
i = i + 1
GoTo NextChar
End If
' Détection identifiant
If strChar Like "[A-Za-z_ÀÂÄÉÈËÊÎÏÔÖÙÛÜàâäéèëêîïôöùûü]" Then '
strIdent = strChar
i = i + 1
While i <= n And (Mid$(strDef, i, 1) Like "[A-Za-z0-9_.ÀÂÄÉÈËÊÎÏÔÖÙÛÜàâäéèëêîïôöùûü]")
strIdent = strIdent & Mid$(strDef, i, 1)
i = i + 1
Wend
If dicVars.Exists(strIdent) Then
If IsNumeric(dicVars(strIdent)) Then
strResult = strResult & Replace(dicVars(strIdent), ",", ".")
Else
strResult = strResult & dicVars(strIdent)
End If
Else
strResult = strResult & strIdent
End If
GoTo NextChar
End If
' Sinon caractère normal
strResult = strResult & strChar
i = i + 1
NextChar:
Wend
ReplaceLETVariables = strResult
End Function
Private Function SplitTopLevel(strInside As String, strSep) As Variant
' Tokenise en découpant les arguments de la fonction LET en se basant sur les ";" mais
' en ignorant les ";" qui sont dans des parenthèses (arguments
' de sous fonctions) ou dans des guillemets (ponctuation)
' Caractères problématiques :
' []{}";' ne sont pas acceptés dans les noms définis
' [] ne sont pas acceptés dans les noms des feuilles
' Pas de limite pour le nom des colonnes des tableaux structurés
' Carac d'échappement ' pour []'#@
' []{}";' ne sont pas acceptés dans les noms des tableaux structurés
' Appellée par : EvalLET / AnalyseLET
Dim strParts() As String ' Tableau résultat
Dim strBuf As String, strCh As String ' Buffer, caractère
Dim lgLevel As Long
Dim boInString As Boolean, boInSheetName As Boolean, boInStructRef As Boolean
' Pour les cas ou un ; est dans une chaîne, dans le nom d'une feuille,
' dans une référence structurée (; dans nom des colonnes, non accepté par Excel pour le nom du tableau)
Dim intNbAppSh As Integer
Dim intNbCrocO As Integer
Dim boCarEchap As Boolean ' C'est un caratère d'echapement
Dim boCarSuiteEchp As Boolean ' C'est le caratère d'echapé
Dim intNbCarIns As Integer
Dim i As Long
ReDim strParts(0 To 0)
strBuf = ""
intNbCarIns = Len(strInside)
For i = 1 To intNbCarIns
strCh = Mid$(strInside, i, 1)
If i < intNbCarIns Then _
boCarEchap = (strCh = "'") And (InStr("[]'#@", Mid$(strInside, i + 1, 1)) > 0)
Select Case strCh
Case """" ' Chaîne : Bascule In/Out
If Not boInSheetName And (intNbCrocO = 0) Then boInString = Not boInString
strBuf = strBuf & strCh
Case "'" ' feuille : Bascule In/Out
If Not boCarEchap And Not boInString And Not boCarSuiteEchp Then boInSheetName = Not boInSheetName
strBuf = strBuf & strCh
Case "[" ' Bascule In/Out ("[", "]" non autorisés dans le nom des feuilles)
If Not boInString And Not boCarSuiteEchp Then intNbCrocO = intNbCrocO + 1
strBuf = strBuf & strCh
Case "]" ' Bascule In/Out ("[", "]" non autorisés dans le nom des feuilles)
If Not boInString And Not boCarSuiteEchp Then intNbCrocO = intNbCrocO - 1
strBuf = strBuf & strCh
Case "(", "{"
If Not boInString And Not boInSheetName And (intNbCrocO = 0) Then lgLevel = lgLevel + 1
strBuf = strBuf & strCh
Case ")", "}"
If Not boInString And Not boInSheetName And (intNbCrocO = 0) Then lgLevel = lgLevel - 1
strBuf = strBuf & strCh
Case strSep
'Debug.Assert strBuf <> "refStruct2"
If lgLevel = 0 And Not boInString And Not boInSheetName And (intNbCrocO = 0) Then ' Chgt d'arguments de 1er niveau
strParts(UBound(strParts)) = Trim$(strBuf)
ReDim Preserve strParts(0 To UBound(strParts) + 1)
strBuf = ""
Else
strBuf = strBuf & strCh
End If
Case Else
' Traitement des retours à la lignes (Alt+Entrer) servant à la présentation
If Asc(strCh) <> 10 Then strBuf = strBuf & strCh
End Select
boCarSuiteEchp = boCarEchap
Next i
strParts(UBound(strParts)) = Trim$(strBuf)
SplitTopLevel = strParts
End Function
Private Function Evaluate2(strDef As String)
' Version de "Evaluate" qui transforme les résultats tableau 2D (ex: range) en une chaîne du type "{1,2;3,4}"
' Appellée par : EvalLET
Dim vaValDef As Variant
Dim r As Long, c As Long
Dim strValMat As String
Dim strRes As String
Dim lgRmin As Long, lgRmax As Long
Dim lgCmin As Long, lgCmax As Long
vaValDef = Evaluate(strDef)
If Not IsArray(vaValDef) Then Evaluate2 = vaValDef: Exit Function
If Not IsArrayDim2(vaValDef) Then
lgRmin = 1: lgRmax = 1
lgCmin = LBound(vaValDef): lgCmax = UBound(vaValDef)
Else
lgRmin = LBound(vaValDef, 1): lgRmax = UBound(vaValDef, 1)
lgCmin = LBound(vaValDef, 2): lgCmax = UBound(vaValDef, 2)
End If
For r = lgRmin To lgRmax
For c = lgCmin To lgCmax
If IsArrayDim2(vaValDef) Then
strValMat = FormatCellValue(vaValDef(r, c))
Else
strValMat = FormatCellValue(vaValDef(c))
End If
strRes = strRes & strValMat
If c < lgCmax Then strRes = strRes & ","
Next c
If r < lgRmax Then strRes = strRes & ";"
Next r
Evaluate2 = "{" & strRes & "}"
End Function
Private Function IsArrayDim2(varTab As Variant) As Boolean
' Teste si varTab à 2 dimensions
' Appelée par : Evaluate2
Dim lgTmp As Long
On Error Resume Next
lgTmp = LBound(varTab, 2)
IsArrayDim2 = (Err.Number = 0)
Err.Clear
End Function
Private Function FormatCellValue(vaVal As Variant) As String
' Formatage des données du tableau
' Appelée par : Evaluate2
Dim strValMat As String
If IsNumeric(vaVal) Then
strValMat = vaVal
Else
strValMat = """" & vaVal & """"
End If
If strValMat = "" Then strValMat = "0"
strValMat = Replace(strValMat, ",", ".") ' format US
FormatCellValue = strValMat
End FunctionMerci pour votre attention bienveillante.
