Existe-t-il un moyen d’exprimer une formule Excel complexe en termes de cellules finales (hors formule, valeur uniquement)?

4

J'ai une feuille de calcul Excel très compliquée (formules accédant à des cellules avec d'autres formules sur plusieurs feuilles de calcul) qui calcule finalement une seule cellule (sortie) avec l'entrée de plusieurs autres cellules (paramètres). Existe-t-il un moyen automatisé (une macro Excel ou un outil autonome) qui pourrait commencer à la cellule de sortie et dérouler les calculs de manière récursive jusqu'à ce qu'il exprime directement la formule en termes de cellules de paramètres?

Clarification

Dans les commentaires, il y avait une suggestion de l'outil Evaluer la formule. Bien que je n’aie pas trouvé comment l’activer dans Excel 2008 pour Mac, sa description donne à penser qu’elle permet à l’utilisateur d’effectuer une évaluation pas à pas d’une cellule. Ce n'est pas ce dont j'ai besoin. Ce dont j'ai besoin, c'est d'un moyen de convertir la formule dans une cellule donnée pouvant faire référence à d'autres cellules contenant des formules, en une formule équivalente exprimée en termes de cellules finales (celles qui contiennent des valeurs, mais pas des formules).

Voici un exemple simple. Laisser

  • A1 contenir = B1 + C1
  • B1 contenir = B2 * B2
  • C1 contenir = C2 * C2
  • B2 contenir 1
  • C2 contenir 2

Evaluer la formule me permettrait d’effectuer un calcul détaillé A1pour arriver à la valeur finale de 5. Ce dont j'ai besoin, c'est d'un outil qui permettrait de suivre A1la formule = B2 * B2 + C2 * C2sans l'évaluer réellement.

George Skoptsov
la source
1
Est-ce que “Evaluate Formula” fait ce que vous voulez? Sinon, pouvez - vous s'il vous plaît expliquer un peu plus clairement (peut - être en donnant un exemple) ce que vous ne voulez?
Scott
@ Scott - Merci pour la suggestion, mais cela ne ressemble pas à ce dont j'ai besoin. Pour répondre à votre question, j'ai besoin d'un outil qui «déroulerait les calculs jusqu'à ce qu'il exprime directement la formule en termes de cellules de paramètres». Je pensais que cette phrase était assez claire, mais j’ai ajouté un exemple explicite de ce dont j'avais besoin et de ce dont je n’avais pas besoin, et une explication de la raison pour laquelle Evaluate Formula n’était probablement pas la bonne solution à mon problème.
George Skoptsov
Bon exemple. Ma deuxième hypothèse aurait été que vous vouliez = (1*1) + (2*2)pour cette situation; merci d'avoir éclairci ça. Vous pouvez utiliser l’évaluation de la formule à l’aide de la fonction «Pas à pas», mais vous devrez prendre un million de captures d’écran en cours de route et assembler les résultats manuellement. ( Cette image composite , fortement modifiée à des fins esthétiques, illustre le processus.) Ce n'est clairement pas pratique.
Scott
Je pense que boost pro fait cela, mais je ne l’ai pas essayé et ce n’est pas gratuit (il existe un essai gratuit). Pas sûr que ce soit disponible sur Mac non plus (ça ne lui ressemble pas).
Assylias
@ George, ce site a l'air un peu démodé, mais je pense qu'il existe plusieurs solutions commerciales de ce type. Fondamentalement, vous développez vos formules de feuille de calcul "nativement", puis exécutez un outil pour les convertir en code, que vous pouvez ensuite compiler et appeler de n'importe où, y compris Excel lui-même: calc4web.com
jtolle

Réponses:

3

Le problème

Vous ne pouvez pas faire cela avec Evaluate Formula parce que ce n'est pas le but de la fonction. C'est pourquoi on l'appelle évaluer , c'est pour évaluer les formules. Ce que vous voulez, c'est une sorte de déballage. C'est un besoin un peu spécial, de sorte qu'il n'est pas implémenté comme outil dans Excel, mais il existe des solutions si vous créez des fonctions / macros Visual Basic.

Créez un module de code VBA (macro) comme vous pouvez le voir dans ce tutoriel .

  1. Appuyez sur Alt+F11
  2. Cliquez pour Moduledans Insert.
  3. Coller le code.
Function CellFormula(Target As Range) As String
   CellFormula = Target.Formula
End Function

Puis entrez ce qui suit dans une cellule: =CellFormula(A1)

Cela dira la formule de la cellule. Le seul problème avec ce code est qu'il ne fonctionne que pour un niveau. Si vous souhaitez également décompresser les formules de cellules contenues, vous avez besoin d'un code plus complexe avec récursivité.

La solution

Le voyage a été long, mais j’ai créé pour vous une macro VBA qui implémente cette fonction. Je ne dis pas que ce code fonctionnera pour toutes les formules, mais cela fonctionnera dans la plupart / certaines d'entre elles. De plus, je ne précise pas que ce code générera des formules équivalentes au code entré à l'origine ou donnera le même résultat que l'original.

Code source

Option Explicit

Function isChar(char As String) As Boolean
    Select Case char
        Case "A" To "Z"
            isChar = True
        Case Else
            isChar = False
    End Select
End Function

Function isNumber(char As String, isZero As Boolean) As Boolean
    Select Case char
        Case "0"
            If isZero = True Then
                isNumber = True
            Else
                isNumber = False
            End If
        Case "1" To "9"
            isNumber = True
        Case Else
            isNumber = False
    End Select
End Function

Function CellFormulaExpand(formula As String) As String
    Dim result As String
    Dim previousResult As String
    Dim cell As Range
    Dim stringArray() As String
    Dim arraySize As Integer
    Dim n As Integer
    Dim trimmer As String

    Dim c As Integer 'character number
    Dim chr As String 'current character
    Dim tempcell As String 'suspected cell's temporaly result
    Dim state As Integer 'state machine's state:
    Dim stringSize As Integer

    result = formula
    previousResult = result
    state = 0
    stringSize = 0

    For c = 0 To Len(formula) Step 1
        chr = Mid(formula, c + 1, 1)
        Select Case state
            Case 0
                If isChar(chr) Then
                    state = 1
                    tempcell = tempcell & chr
                ElseIf chr = "$" Then
                    state = 5
                    tempcell = tempcell & chr
                Else
                    state = 0
                    tempcell = ""
                End If
            Case 1
                If isNumber(chr, False) Then
                    state = 4
                    tempcell = tempcell & chr
                ElseIf isChar(chr) Then
                    state = 2
                    tempcell = tempcell & chr
                ElseIf chr = "$" Then
                    state = 6
                    tempcell = tempcell & chr
                Else
                    state = 0
                    tempcell = ""
                End If
            Case 2
                If isNumber(chr, False) Then
                    state = 4
                    tempcell = tempcell + chr
                ElseIf isChar(chr) Then
                    state = 3
                    tempcell = tempcell + chr
                ElseIf chr = "$" Then
                    state = 6
                    tempcell = tempcell + chr
                Else
                    state = 0
                    tempcell = ""
                End If
            Case 3
                If isNumber(chr, False) Then
                    state = 4
                    tempcell = tempcell + chr
                ElseIf chr = "$" Then
                    state = 6
                    tempcell = tempcell + chr
                Else
                    state = 0
                    tempcell = ""
                End If
            Case 4
                If isNumber(chr, True) Then
                    state = 4
                    tempcell = tempcell + chr
                Else
                    state = 0
                    stringSize = stringSize + 1
                    ReDim Preserve stringArray(stringSize - 1)
                    stringArray(stringSize - 1) = tempcell
                    tempcell = ""
                End If
            Case 5
                If isChar(chr) Then
                    state = 1
                    tempcell = tempcell + chr
                Else
                    state = 0
                    tempcell = ""
                End If
            Case 6
                If isNumber(chr, False) Then
                    state = 4
                    tempcell = tempcell + chr
                Else
                    state = 0
                    tempcell = ""
                End If
            Case Else
                state = 0
                tempcell = ""
        End Select
    Next c
    If stringSize = 0 Then
        CellFormulaExpand = result
    Else
        arraySize = UBound(stringArray)
        For n = 0 To arraySize Step 1
            Set cell = Range(stringArray(n))
            If Mid(cell.formula, 1, 1) = "=" Then
                trimmer = Mid(cell.formula, 2, Len(cell.formula) - 1)
                If trimmer <> "" Then
                    result = Replace(result, stringArray(n), trimmer)
                End If
            End If
        Next
        If previousResult <> result Then
            result = CellFormulaExpand(result)
        End If
    End If
    CellFormulaExpand = result
End Function

Function CellFormula(rng As Range) As String
    CellFormula = CellFormulaExpand(rng.formula)
End Function

Pour que cela fonctionne, il suffit de créer une macro (comme je l'ai décrite au début de la réponse) et de copier-coller le code. Après cela, vous pouvez l'utiliser avec =CellFormula(A1)A1peut être n'importe quel type de cellule 1x1.

Cas ça marche

J'ai créé quelques exemples pour que vous puissiez le voir en action. Dans ce cas, je démontre l'utilisation avec des chaînes. Vous pouvez voir que cela fonctionne parfaitement. Le seul petit problème est que, pour l’algorithme, l’algorithme change les points-virgules en virgules. Après les avoir remplacés (comme je l’ai fait dans cet exemple), vous obtenez le bon résultat. Travailler avec des cordes

Ici, vous pouvez voir comment cela fonctionne avec les chiffres. Maintenant, nous sommes confrontés au premier problème que l’algorithme ne se soucie pas de la séquence des opérations mathématiques, c’est pourquoi le nombre rouge est 6 alors qu'il devrait être 10. Si nous plaçons les opérations sensibles (comme l’addition et la soustraction) entre parenthèses, la formule donnée entrée en arrière donnera le même résultat que vous pouvez voir dans le nombre vert en bas qui dit 10. Travailler avec des chiffres

Cas ça ne marche pas

Cet algorithme n'est pas parfait. J’ai seulement essayé d’implémenter les utilisations les plus courantes. Il est donc possible de l’améliorer en ajoutant davantage de fonctionnalités prenant en charge d’autres cas, comme les plages.
Comme vous pouvez le voir dans cet exemple, j'ai utilisé SUM()une plage en tant que paramètre. Étant donné que l’algorithme décrypte le contenu des cellules de haut en bas, il commence par le remplacement des SUM()paramètres au plus tard. Par conséquent, les :objets restent à sa place pendant que tout est remplacé, de sorte que les nouvelles cellules sont remplacées à proximité, ce qui en changera le sens. Ainsi, la sortie sera fausse. Donc, dans ce cas, vous ne pouvez utiliser cette macro que pour étudier la formule d'origine. Travailler avec des gammes

totymedli
la source
Merci d'avoir mis l'effort dans cela. Je comprends les limites, mais je pense que cela se rapproche le plus de ce que j’ai demandé qui puisse être raisonnablement fait.
George Skoptsov
1

Étant donné que vous utilisez le mot "trace" dans votre question, je suppose que vous connaissez les fonctions Trace Precendentset Trace Dependentsdans la section "Audit de formules" d'Excel?

Voici une brève explication de chacun des outils d'audit de formules de dummies.com:

Comprendre les outils d'audit de formules d'Excel 2010

utilisateur1936123
la source
Oui, je connais ces outils - ils dessinent des flèches de dépendance (qui échouent lamentablement lorsque la feuille de calcul est volumineuse ou que la dépendance concerne une cellule d'une feuille différente). J'ai besoin de plus que de connaître les dépendances - j'ai besoin d'un moyen de produire l'expression réelle. En ce qui concerne l'utilisation du mot 'trace' - @killermist a modifié mon titre original - plutôt gratuitement et de manière incompentente.
George Skoptsov
1
Si vous êtes à l'aise avec VBA, vous pouvez dérouler toute la fonction en parcourant tous les précédents avec la fonction décrite ici .
user1936123