Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2021 VBA: Extraction des paramètres d'une formule (texte)

p'tit vieux

XLDnaute Occasionnel
Bonjour à tous
Après moulte recherche et écriture de divers fonctions donnant des résultats mitigés, je n'arrive pas à trouver LA bonne solution à mon problème.
Alors ayant très "bobo tête" je men remet à vos esprits d'expert.
PS: J'ai essayé avec Split, Instr, InStrRev etc Parfois en utilisant Like. Mais … Boff ce n'est pas vraiment cela.

Voici le problème.
Exemple de formule à traiter:
"=FOO(((A),(B),"C"),"D,E,F",((G),H))"
Pour simplifié j'ai mis des lettres à la place des valeurs
A, B , C, E, F G etc = sont des "valeurs paramètres".
Exemple de ce peut contenir A, B etc.
A = A1:B2, B5, B7, C8
B = D5:E12
C = 9850
D = Banque, Caisse, Référence -> par exemple.

Ce qui donnerait en développant:
"(((A1:B2, B5, B7, C8),(D5:E12),"9850"),"Banque, Caisse, Référence",((G),H))"

OBJECTIF
: Extraire chaque paramètre en gardant sa cohérence.
Dans la formule ci-dessus les paramètres complets a extraire serait :
n°1 : ((A),(B),"C")
N°2 : "D,E,F"
N°3 : ((G),H))
MAIS:
Il peut y avoir imbrication de fonction "Foo()". Comme ceci:
"=FOO1(((A),(B),"C"),"D,E,F",(FOO2((a),(b),"c"),H))"
… Sinon ce ne serait pas drôle. Ici, FOO2 = le paramètre G qui sera analysé à part.

Pour vous aider à m'aider , si j'utilise Split sur la virgule "," ou sur la "(" ou la ")" sans compter le paramètre délimité par " " " -Chr(34)- , j'obtiens un tableau qui ne correspond à rien sans des traitement supplémentaires.

Si quelqu'un a une idée (ou plusieurs) j'en serai très heureux.
Désolé pour les mots de tête. J'aime bien partager

Par avance merci à vous.

PS:
Bien sûr ici dans l'exemple on peut commencer par simplifier la 1ere et la dernière parenthèse. Mais, même si rare, ce n'est pas toujours le cas.
 
Dernière édition:

sylvanu

XLDnaute Barbatruc
Supporter XLD
Bonjour P'tit vieux,
Un essai en PJ avec cette fonction perso.
Elle marche avec votre exemple mais à vérifier sur toutes vos configurations :
VB:
Function SplitChamp(C$, N%)
    C = Replace(C, "((", "£")
    C = Replace(C, "))", "£")
    C = Replace(C, "),", "£")
    C = Replace(C, "(", "")
    T = Split(C, "£")
    Nit = 0
    For x = 0 To UBound(T)
        If T(x) <> "" Then
            If Nit = N - 1 Then SplitChamp = Replace(T(x), """", "")
            Nit = Nit + 1
        End If
    Next x
End Function
On peut optimiser l'écriture si ça marche correctement, mais cela sera moins lisible.
 

Pièces jointes

  • Classeur1.xlsm
    13.9 KB · Affichages: 2

p'tit vieux

XLDnaute Occasionnel
Pour l'instant, je n'ai pas vraiment compris comment fonctionne ta fonction mais bon en ce moment je suis un peu … "mou du bulbe" . (Comprend mais faut expliquer longtemps)

J'ai testé et "unitairement" ca marche. Bravo!
Un détail toutefois j'obtiens "valeur" par "valeur" mais pas paramètre par paramètre
Exemple:
Le paramètre n°1 complet devrait être: ((A),(B),"C") ou (((A1:B2, B5, B7, C8),(D5:E12),"9850")
qui contient bien les valeurs que votre fonction retourne A, B, C ou (A1:B2, B5, B7, C8),(D5:E12),"9850"
Le paramètre n°2 complet devrait être: "D,E,F" ou "Banque, Caisse, Référence"

"PIRE" … (G) = (FOO2((a),(b),"c") à la place du paramètre G
Unitairement c'est bon mais ce n'est pas le paramètre complet

Je vais creuser votre algo car il est rapide et simple. Simple OK mais d'abord pour comprendre les substitutions que vous faites et voir si je (on) peut avancer.

Merci
 

p'tit vieux

XLDnaute Occasionnel
Re,
Par contre j'ai zappé la fonction Foo. Sorry.
D'autre part il s'agit de chaine de caractères ou est ce une fonction comme "=Foo1(.... " ?
Pas de problème
Foo2 est une fonction. Pour faire simple on dira que c'est la même fonction que Foo1.
Par contre elle est à considérer comme un paramètre de Foo1 à elle toute seule. Donc on ne la traite pas!
Pour la traiter, si besoin, je pense simplement appeler à nouveau la fonction d'extraction de paramètres qui me les renverra.
 

sylvanu

XLDnaute Barbatruc
Supporter XLD
Désolé je n'avais pas compris la problématique.
En PJ un nouvel essai avec :
VB:
Function SplitChamp(C$, N%)
    C = Replace(C, """),""", "£")
    C = Replace(C, """,(", "£")
    T = Split(C, "£")
    If N = 1 Then SplitChamp = T(0) & """" Else SplitChamp = T(1)
End Function
Ca donne avec l'exemple :
Param1 : (((A1:B2, B5, B7, C8),(D5:E12),"9850"
Param2 : Banque, Caisse, Référence
( j'ai gardé l'ancienne version dont la syntaxe est SplitChamp2. )
 

Pièces jointes

  • Classeur1 V2.xlsm
    14.7 KB · Affichages: 1

p'tit vieux

XLDnaute Occasionnel
J'ai fais un petit nettoyage d'entête et de queue

VB:
   ' A ajouter au tout début avant traitement
    If UCase(C) Like "=[A-Z]*(*)" Then                    ' Test si "=Foo(*)""
      C = Mid(C, InStr(1, C, "(", vbTextCompare) + 1)     'nettoie le nom de =Foo1
      C = Left(C, Len(C) - 1)
    End If
 

p'tit vieux

XLDnaute Occasionnel
J'ai fait ce test avec l'ancienne et la nouvelle version
SplitChamp2("=Foo1((N2:N4),Foo2(""Banque, Caisse, Référence"",B2:B366,(A2;C2)),""A2,C2"")",1)
Le résultat du paramètre Foo2 est:
Foo2Banque, Caisse, Référence,B2:B366,A2;C2
On perd toutes les parenthèses, guillemets etc.
 

p'tit vieux

XLDnaute Occasionnel
Pour aider voici une fonction que j'utilise souvent qui permet de connaitre le nombre d'occurrence d'une chaine.
VB:
' Return the number of occurrence of the string SubStr
' TheText    = Ta chaine principale
' SubStr     = Ta sous chaine (ou caractère)
' RC         = Pour Respecter ou non la Casse dans la fonction Replace prédéfinie en visual basic
' si RC      = 1 alors majuscule = minuscule
' si RC      = 0 alors majuscule <> minuscule
Private Function CountOccurrence(ByVal TheText As String, ByVal SubStr As String, Optional RC As Variant = 1) As Long
' (Longueur de la chaine - longueur de chaine SANS la sous-chaine)/longuer de la sous-chaine
    CountOccurrence = (Len(TheText) - Len(Replace(TheText, SubStr, vbNullString, , , RC))) / Len(SubStr)

End Function
 

p'tit vieux

XLDnaute Occasionnel
Re
il y a un bug. il n'extrait pas le paramètre "((G);H)". Le dernier.
Je vous envoie le fichier.

PS:
Dans le Code je parle de formule simple c'est à dire sans parenthèse exemple:
"=Foo(D3:d4,'E:\FONCTIONS VBA PERSO\TESTS\[Datas externes.xlsx]2020'!$A$1:$B$3,'E:\FONCTIONS VBA PERSO\TESTS\[Datas externes.xlsx]2020'!$B$1)"
Dans ce cas un Split sur les "," suffit
Par contre ce n'est plus vrai lorsque j'ai ceci:
"=Foo("Banque, Caisse, Référence", 'E:\FONCTIONS VBA PERSO\TESTS\[Datas externes.xlsx]2020'!$A$1:$B$3,'E:\FONCTIONS VBA PERSO\TESTS\[Datas externes.xlsx]2020'!$B$1)"
 

Pièces jointes

  • Sylvanu v2.xlsm
    19.7 KB · Affichages: 1
Dernière édition:

Discussions similaires

Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…