4

У меня очень сложная электронная таблица Excel (формулы для доступа к ячейкам с другими формулами на нескольких листах), которая в итоге вычисляет одну ячейку (вывод) с вводом из нескольких других ячеек (параметров). Существует ли автоматический способ (макрос Excel или автономный инструмент), который может начинаться с выходной ячейки и рекурсивно развертывать вычисления, пока он не выразит формулу непосредственно в ячейках параметров?

осветление

В комментариях было предложено использовать инструмент «Формула оценки». Хотя я не мог найти, как активировать его в Excel 2008 для Mac, из его описания это звучит так, как будто он позволяет пользователю пройти этап оценки ячейки. Это не то, что мне нужно. Мне нужен способ преобразования формулы в данной ячейке, которая может ссылаться на другие ячейки, содержащие формулы, в эквивалентную формулу, выраженную в терминах конечных ячеек (те, которые содержат значения, но не формулы).

Вот простой пример. Позволять

  • A1 содержит = B1 + C1
  • B1 содержит = B2 * B2
  • C1 содержит = C2 * C2
  • B2 содержат 1
  • C2 содержат 2

Формула оценки позволила бы мне пройти через вычисление A1 чтобы получить окончательное значение 5 . Мне нужен инструмент, который развернул бы A1 до формулы = B2 * B2 + C2 * C2 без фактической оценки.

2 ответа2

3

Эта проблема

Вы не можете сделать это с помощью формулы оценки, потому что это не является целью этой функции. Вот почему это называется оценить, это для оценки формул. То, что вы хотите, это какая-то распаковка. Это немного особая необходимость, поэтому она не реализована как инструмент в Excel, но есть решения, если вы создаете некоторые функции / макросы Visual Basic.

Создайте модуль кода VBA (макрос), как вы можете видеть в этом руководстве.

  1. Нажмите Alt+F11
  2. Нажмите на Module во Insert .
  3. Вставьте код.
Function CellFormula(Target As Range) As String
   CellFormula = Target.Formula
End Function

Затем введите в ячейку следующее: =CellFormula(A1)

Это скажет формула ячейки. Единственная проблема с этим кодом, что он работает только для одного уровня. Если вы тоже хотите распаковать содержащиеся в ячейках формулы, вам нужен более сложный код с рекурсией.

Решение

Это был длинный путь, но я создал для вас макрос VBA, который реализует эту функцию. Я не утверждаю, что этот код будет работать для каждой формулы, но он будет работать в большинстве / некоторых из них. Также я не утверждаю, что этот код будет генерировать формулы, которые эквивалентны оригинально введенному коду или будут давать тот же результат, что и оригинал.

Исходный код

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

Чтобы заставить его работать, просто создайте макрос (как я описал в начале ответа) и скопируйте код. После этого вы можете использовать его с =CellFormula(A1) где A1 может быть любой вид ячейки 1x1.

Случаи это работает

Я создал несколько примеров, чтобы вы могли увидеть это в действии. В этом случае я демонстрирую использование со строками. Вы можете видеть, что это работает отлично. Единственная небольшая ошибка в том, что алгоритм изменяет точки с запятой на запятые. После их замены (как я сделал в этом примере) вы получите правильный вывод. Работа со строками

Здесь вы можете увидеть, как это работает с числами. Теперь мы сталкиваемся с первой проблемой: алгоритм не заботится о последовательности математических операций, поэтому красное число равно 6, когда оно должно быть 10. Если мы поместим чувствительные операции (такие как сложение и вычитание) в круглые скобки, то заданная формула, введенная назад, даст тот же результат, что вы можете видеть в зеленом числе внизу, которое говорит 10. Работа с числами

Случаи это не работает

Этот алгоритм не идеален. Я только попытался реализовать наиболее распространенные варианты использования, поэтому его можно улучшить, добавив больше функций, которые обрабатывают другие случаи, например диапазоны.
Как вы можете видеть в этом примере, я использовал SUM() с диапазоном в качестве параметра. Поскольку алгоритм расшифровывает содержимое ячеек сверху вниз, он начинается с замены параметров SUM() не чем-либо другим. Поэтому : остается на своем месте, в то время как вокруг него все заменяется, поэтому рядом с ним заменяются новые ячейки, которые изменят его значение. Таким образом, вывод будет неправильным. Так что в этом случае вы можете использовать этот макрос только для изучения исходной формулы. Работа с диапазонами

1

Учитывая, что вы использовали слово "трассировка" в своем вопросе, я предполагаю, что вы знакомы с Trace Precendents трассировки» и « Trace Dependents в разделе "Аудит формул " в Excel?

Вот краткое объяснение каждого из инструментов аудита формул от dummies.com:

Понимание инструментов аудита формул в Excel 2010

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .