Geo*_*sov 5 worksheet-function microsoft-excel
我有一个非常复杂的 Excel 电子表格(通过多个工作表中的其他公式访问单元格的公式),它最终会使用来自其他几个单元格(参数)的输入来计算单个单元格(输出)。是否有一种自动方式(Excel 宏或独立工具)可以从输出单元格开始并递归展开计算,直到它直接根据参数单元格表达公式?
澄清
在评论中有一个评估公式工具的建议。虽然我找不到如何在 Excel 2008 for Mac 中激活它,但从它的描述来看,它似乎允许用户逐步评估单元格。那不是我需要的。我需要的是一种将给定单元格中可能引用其他包含公式的单元格的公式转换为以最终单元格(包含值但不包含公式的单元格)表示的等效公式的方法。
这是一个简单的例子。让
A1
包含 = B1 + C1
B1
包含 = B2 * B2
C1
包含 = C2 * C2
B2
包含 1
C2
包含 2
评估公式将允许我逐步完成 的计算A1
以获得 的最终值 5
。我需要的是一种无需实际评估即可展开A1
到公式的工具= B2 * B2 + C2 * C2
。
您不能使用评估公式来执行此操作,因为这不是该函数的目的。这就是为什么它被称为评估,它用于评估公式。你想要的是某种拆包。这是一个有点特殊的需求,因此它没有作为 Excel 中的工具实现,但如果您创建一些 Visual Basic 函数/宏,则有一些解决方案。
Module
进入Insert
.Function CellFormula(Target As Range) As String
CellFormula = Target.Formula
End Function
Run Code Online (Sandbox Code Playgroud)
然后在单元格中输入以下内容:=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
Run Code Online (Sandbox Code Playgroud)
要使其工作,只需创建一个宏(正如我在答案开头所描述的那样)并复制粘贴代码。之后,您可以将其与任何类型的 1x1 单元一=CellFormula(A1)
起使用。A1
我创建了一些示例,以便您可以看到它的实际效果。在本例中,我演示了字符串的使用。你可以看到它运行完美。唯一的小错误是,不知何故,算法将分号更改为逗号。替换它们后(正如我在本示例中所做的那样),您将获得正确的输出。
在这里,您可以看到它如何处理数字。现在,我们面临的第一个问题是算法不关心数学运算顺序,这就是为什么红色数字应该是 10 时却是 6。如果我们将敏感运算(如加法和减法)放在括号中,那么输入的给定公式将给出与底部绿色数字 10 相同的输出。
这个算法并不完美。我只尝试实现最常见的用途,因此可以通过添加更多处理其他情况(例如范围)的功能来改进它。
正如您在本示例中看到的,我使用SUM()
范围作为参数。由于该算法从上到下解密单元格内容,因此它从替换参数开始,SUM()
然后再替换任何其他内容。因此,它:
留在原来的位置,而它周围的一切都被替换了,所以它附近有新的细胞被替换,谁会改变它的含义。因此输出将是错误的。所以这种情况就只能用这个宏来研究原公式了。
归档时间: |
|
查看次数: |
3197 次 |
最近记录: |