Problème récurcivité EVALUATE

Bonjour a tous.213868

j'ai trouvé un soucis, qu'on a fini par clairement identifier / carractériser, mais sans explication ni solution.

a part recoder complètement Evaluate, je ne vois pas quoi faire.

voila ma fonction :

Sub Bouton_Cliquer()    temp = InputBox("Formule, EN ANGLAIS (, au lieu de ;)", "ReadValue(A1,3)")
    temp2 = Evaluate(CStr(temp))
    MsgBox (temp3)
End Sub

Public Function ReadValue(valeur As Variant, Reference As Long) As Variant
'lis une des valeur d'une matrice textuelle

    Dim Tableau() As String
    Dim temp As Variant

    If valeur = "" Then
        ReadValue = ""
        Exit Function
    End If

    'découpe la chaine en fonction des espaces " "
    'le résultat de la fonction Split est stocké dans un tableau
    'il faudra commencer par trier les données pour s'assurer qu'il n'y a pas de "coupe" entre guillemet (plus tard)

    Tableau = Split(valeur, "|")

    'boucle sur le tableau pour visualiser le résultat

    Select Case Reference

        Case Is <= 0
            ReadValue = UBound(Tableau) + 1
            'dans le cas négatif ou =0, retourne le NOMBRE de référence dispo

        Case Else
            If Reference > UBound(Tableau) + 1 Then Exit Function
            temp = CStr(Tableau(Reference - 1))
            'temp = ChangeLangueFormule(CStr(temp))
            ReadValue = Evaluate(CStr(temp)) '<<<<======= c'est cette fonction qui plante.
            'ReadValue = temp '<<<==== si on remplace par celle ci, ca marche/
            'dans le cas positif, retourne le résultat de l'index

    End Select

End Function

mettez ce code dans un module

le but est le suivant, si vous avez la cellule A1 où est écrit, par exemple :

12|24|Sum(D)|38

écrivez dans une cellule :

=ReadValue(A1, 1)

résultat : 12

=ReadValue(A1, 2)

résultat : 24

=ReadValue(A1, 4)

résultat : 38

le truc spécial, c'est

=ReadValue(A1, 3)

résultat : la somme de la colonne D

ok, si vous l'écrivez ainsi, en formule, tout marche, rien a redire.

toutefois, le soucis, c'est que dans mon code complet, je laisse l'utilisateur écrire lui même un texte "ReadValue"

pour reproduire le bug, donc, maintenant que vous avez vu que ma fonction ... fonctionne.

creez un bouton ou autre, et cette fois ci, utilisez la procédure bouton, pour entrer dans l'input box :

readvalue(A1,3)

en théorie, ca devrait marcher, et retourner la somme de D

=> ERREUR 2015 !

pourtant, c'est écrit en anglais, RAS.

essayez sur des valeurs sans formule, par exemple

readvalue(A1,1)

en théorie, ca devrait retourner 12

=> ERREUR 2015 Oo !!!

dans le doute, passez en commentaire la ligne du "evaluate" de ma fonction, pour mettre à la place celle au dessous.

code :

Sub Bouton_Cliquer()    temp = InputBox("Formule, EN ANGLAIS (, au lieu de ;)", "ReadValue(A1,3)")
    temp2 = Evaluate(CStr(temp))
    MsgBox (temp3)
End Sub

Public Function ReadValue(valeur As Variant, Reference As Long) As Variant
'lis une des valeur d'une matrice textuelle

    Dim Tableau() As String
    Dim temp As Variant

    If valeur = "" Then
        ReadValue = ""
        Exit Function
    End If

    'découpe la chaine en fonction des espaces " "
    'le résultat de la fonction Split est stocké dans un tableau
    'il faudra commencer par trier les données pour s'assurer qu'il n'y a pas de "coupe" entre guillemet (plus tard)

    Tableau = Split(valeur, "|")

    'boucle sur le tableau pour visualiser le résultat

    Select Case Reference

        Case Is <= 0
            ReadValue = UBound(Tableau) + 1
            'dans le cas négatif ou =0, retourne le NOMBRE de référence dispo

        Case Else
            If Reference > UBound(Tableau) + 1 Then Exit Function
            temp = CStr(Tableau(Reference - 1))
            'temp = ChangeLangueFormule(CStr(temp))
           'ReadValue = Evaluate(CStr(temp)) '<<<<======= c'est cette fonction qui plante.
           ReadValue = temp '<<<==== si on remplace par celle ci, ca marche/
            'dans le cas positif, retourne le résultat de l'index

    End Select

End Function

alors cette fois ci, les résultat :

readvalue(A1,1)

Retourne bien 12; cette fois ci, ca marche.

readvalue(A1,3)

Retourne "SUM(D)" mais sans l'appliquer. ca marche, mais c'est pas ce que je souhaite !

Conclusion :

impossible d'appliquer un EVALUATE depuis une fonction deja lancé par un EVALUATE.

comment contourner ce soucis ? comment appliquer mon évaluate au clic bouton pour obtenir le meme effet que si je l'avais entré dans une cellule en tant que formule ?

évidement, mon projet complet est bien plus complexe que ca, et donc, je dois avoir une fonction "universelle" de "readvalue" qui fonctionne et s'adapte à tout les cas.

ca fait 2 jours que je m'arrache les cheveux dessus, et je commence a sérieusement envisager de faire un traitement de chaine de carra pour décompiler en petit bout les formule pour les "callbyname" ... autrement dit ... recoder à la main evaluate. rien que ca.

si quelqu'un a la moindre solution, parce que là, je pete un cable.

en vous remerciant par avance.

cordialement.

Bonjour,

deux petit question :

  • la valeur n°3 est toujours un "SUM"
  • la valeur retourné est affecter a une case ou juste un variable tmp ?

bonjour

ca peut etre SUM, ou n'importe quoi. d'ou l'interet d'un "evaluate" qui peu permettre de calculer tout les cas possible.

le retour peut etre soit une variable (si appelé par un evaluate depuis ma macro), soit un résultat affiché dans une cellule si c'est l'utilisateur lui meme qui l'exploite.

j'ai compilé le tout dans un fichier pour que ca soit plus explicite

7classeur2.xlsm (20.87 Ko)

j'ai la version BRUTE et j'espere que quelqu'un vous donnera mieux ^^

je prend le SUM(D) comme exemple

voila ma proposition :

si c'est a mettre directement dans une cellule : récupere "sum(d)" comme vous l'avez deja fait et le concatener avec un = sa donne :

  "=" & readvalue(A1,3)

si c'est pour un variable : couper "sum(D)" en deux partie => "SUM" et "D" ensuite appliquer une simple addition si c'est SUM ou autre

ex :

 
dim f as String
dim v as String 
f = "SUM"
v = "D"  'évidament pour vous sa sera un fonction qui recupere la chaine entre parenthèse
if f = "SUM" then   'utiliser select case sera mieux ici 
Application.Sum(Range(v & 1  ).EntireColumn)  
end if 

bonjour

la solution de passer par une cellule plutot que evaluate

donc ajouter en fin de readvalue

range("A1").value = "=sum(D:D)"

readvalue = range("A1").value

fonctionne. seulement, c'est le cas comme ca, ici, mais ca rends ma fonction non universelle, peu transposable. et de fait, dans l'usine a gaz dans laquelle elle est utilisé, c'est juste "mort". ca marche pas.

quand a la seconde, comme je ne sais pas si je vais avoir du sum, ou autre chose, ou meme des fonctions perso, il faudra s'adapter a chaque cas. comme les formule peuvent en plus etre imbriqué, c'est encore pire.

bref, ca revient a ce que j'envisage en esperant fortement ne pas avoir a le faire : recoder integralement "evaluate" moi meme a grand coup de traitement de chaine et de callbyname.

je cherche une solution plus elegante, ou une explication a mon soucis, voir un contournement efficace.

cordialement

Rechercher des sujets similaires à "probleme recurcivite evaluate"