Does Excel have a built in method for parsing formulas? (ie: to obtain a list of included RANGE references)

前端 未结 3 1394
余生分开走
余生分开走 2020-12-19 08:34

For a given Excel formula in a cell, I\'d like to be able to parse the formula in order to get a list of Excel Range references contained within the formula.

For exa

相关标签:
3条回答
  • 2020-12-19 08:51

    Tbone, One other option that is not directly what you asked for but could work as alternative solution.

    Rather than using a formula to try and find the corrosponding label, Try adjusting your formulas to work for you. Here are a couple of options depending on what the formula you were trying to parse is. 1. If your formula is a lookup you could just offset to look to the left. 2. Alternatively you could use the "Indirect" function in both formulas to ensure they are referencing the correct location.

    0 讨论(0)
  • 2020-12-19 08:52

    Thanks to @TimWilliams and @brettdj for pointing me in the right direction to previous discussions on this topic, I can confidently say:

    NO, EXCEL DOES NOT HAVE A METHOD FOR PARSING.

    However, for my fairly minimal purposes, I've come up with something that works, works with cross worksheet references, and can be called from a UDF.

    However, it is extremely brittle, and there are multitudes of perfectly legitimate formulas that I'm certain it wouldn't handle properly.

    The code is a mess and could be greatly improved but I just wanted to throw it up on here as I'm moving onto to something else for the time being....

    EDIT

    Also found this, which looks very interesting:
    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
    

    (just google SplitMultiDelims for that function)

    0 讨论(0)
  • 2020-12-19 08:59

    In short, I think you want to do subpart of : Use VBA to generate code to reproduce basic calculations on an Excel worksheet, and using a function to return n'th DirectPrecedents collection element address or name.

    source: http://www.vb-helper.com/howto_vba_excel_formulas.html

    This use case however has been deprecated. As of Excel 2007 tables allow a much better solution.

    0 讨论(0)
提交回复
热议问题