Excel是否有内置的parsing公式的方法? (即:获取包含的RANGE引用的列表)

对于单元格中给定的Excel公式,我希望能够parsing公式以获取公式中包含的Excel范围参考列表。

例如,如果我有一个这个公式的单元格:

= A + 25 + B 

….我想能够得到公式中包含的Excel范围数组,所以在这种情况下,它将包含[A]和[B]

“你为什么要这样做?”,我可以听到你问:
为什么我要这样做的一个例子是查找公式的范围“标签”…..所以,而不是只是做一个CTRL +〜查看我的表中的公式,我想要的选项以编程方式访问公式中的范围引用,以便查找目标范围旁边的标签。

所以,在我上面的例子中,我可以写公式如下:

 =Offset(CellFormulaRanges('TheAddressMyFormulaIsIn',1),0,-1) =Offset(CellFormulaRanges('TheAddressMyFormulaIsIn',2),0,-1) 

…这会给我的公式内的第一和第二范围的左侧的标签。

要做到这一点,必须调用Excel本身的一些function,因为编写公式分析器是一项复杂的任务:
http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html

感谢@TimWilliams和@brettdj指出我在前面关于这个话题的讨论的正确方向,我可以自信地说:

不,EXCEL没有办法进行PARSING。

然而,为了达到最低限度的目的,我想出了一些可行的方法,使用交叉工作表引用,并且可以从UDF调用。

然而,这是非常脆弱的,有很多完全合法的公式,我敢肯定,它不会妥善处理。

代码是一团糟,可以大大改善,但我只是想把它放在这里,因为我正在转移到别的东西,目前….

编辑

还发现这个,看起来很有趣:
http://www.dailydoseofexcel.com/archives/2009/12/05/formula-tokenizer/

 Public Function CellPrecedents(cell As Range) As Variant() Dim resultRanges As New Collection If cell.Cells.count <> 1 Then GoTo exit_CellPrecedents If cell.HasFormula = False Then GoTo exit_CellPrecedents Dim formula As String formula = Mid(cell.formula, 2, Len(cell.formula) - 1) If IsRange(formula) Then resultRanges.Add Range(formula), 1 Else Dim elements() As String 'Debug.Print formula & " --> " formula = Replace(formula, "(", "") formula = Replace(formula, ")", "") 'Debug.Print formula & " --> " elements() = SplitMultiDelims(formula, "+-*/\^") Dim n As Long, count As Integer For n = LBound(elements) To UBound(elements) If IsRange(elements(n)) Then 'ACTUALLY JUST DO A REDIM PRESERVE HERE!!!! count = count + 1 'resultRanges.Add Range(Trim(elements(n))) '<--- Do **NOT** store as a range, as that gets automatically Eval()'d resultRanges.Add Trim(elements(n)) End If Next End If Dim resultRangeArray() As Variant ReDim resultRangeArray(resultRanges.count) Dim i As Integer For i = 1 To resultRanges.count resultRangeArray(i) = CStr(resultRanges(i)) '// have to store as a string so Eval() doesn't get invoked (I think??) Next CellPrecedents = resultRangeArray exit_CellPrecedents: Exit Function End Function Public Function IsRange(var As Variant) As Boolean On Error Resume Next Dim rng As Range: Set rng = Range(var) If err.Number = 0 Then IsRange = True End Function 

(只是谷歌SplitMultiDelims该function)

Tbone,另外一种select不是直接要求的,而是可以作为替代解决scheme。

尝试调整您的公式来为您工作,而不是使用公式来尝试find相应的标签。 这里有几个选项取决于你想要parsing的公式是什么。 如果你的公式是一个查询,你可以抵消一下,看看左边。 2.或者,您可以在两个公式中使用“间接”function,以确保它们引用的是正确的位置。

简而言之,我认为你想做下面的子部分: Use VBA to generate code to reproduce basic calculations on an Excel worksheet ,并使用函数返回第n个DirectPrecedents集合元素地址或名称。

来源: http : //www.vb-helper.com/howto_vba_excel_formulas.html

但是这个用例已经被弃用了。 从Excel 2007起,表格允许更好的解决scheme。