¿Excel tiene un método integrado para analizar fórmulas? (es decir: para obtener una lista de referencias RANGE incluidas)

Para una fórmula de Excel dada en una celda, me gustaría poder analizar la fórmula para obtener una lista de referencias de rango de Excel contenidas en la fórmula.

Por ejemplo, si tengo una celda con esta fórmula:

= A + 25 + B  

.... Me gustaría poder obtener una matriz de rangos de Excel contenidos dentro de la fórmula, por lo que en este caso, contendría [A] y [B]

"¿Por qué quieres hacer esto?" Puedo oírte preguntar:
Solo un ejemplo de por qué quiero hacer esto es buscar "etiquetas" para rangos en fórmulas... entonces, en lugar de simplemente hacer CTRL+~ para ver las fórmulas en mi hoja, me gustaría la opción de acceder programáticamente a las referencias de rango dentro de la fórmula para realizar una búsqueda de la etiqueta al lado del rango de destino.

Entonces, en mi ejemplo anterior, podría escribir fórmulas como:

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

...lo que me daría la etiqueta a la izquierda del primer y segundo rango dentro de la fórmula.

Hacer esto tendría que recurrir a alguna funcionalidad que ya está dentro de Excel, ya que escribir a mano un analizador de fórmulas es una tarea complicada:
http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html

preguntado el 04 de julio de 12 a las 00:07

VBA tiene acceso a una fórmula Precedents, pero solo aquellos en la misma hoja que la fórmula. Hay esto: ozgrid.com/forum/showthread.php?t=17028, pero no podrá usar eso en un UDF, que parece ser lo que quiere. Ver también: stackoverflow.com/questions/5541342/… -

Además del comentario de Tim, puedes usar el NavigateArrows método para identificar referencias fuera de la hoja. Usé este enfoque aquí, el crédito por el código inicial pertenece a Bill Manville. -

3 Respuestas

Gracias a @TimWilliams y @brettdj por orientarme en la dirección correcta de discusiones previas sobre este tema, puedo decir con confianza:

NO, EXCEL NO TIENE UN MÉTODO PARA EL ANÁLISIS.

Sin embargo, para mis propósitos bastante mínimos, se me ocurrió algo que funciona, funciona con referencias cruzadas de hojas de trabajo y se puede llamar desde una UDF.

Sin embargo, es extremadamente frágil y hay multitud de fórmulas perfectamente legítimas que estoy seguro de que no se manejarían correctamente.

El código es un desastre y podría mejorarse mucho, pero solo quería mostrarlo aquí, ya que por el momento me estoy moviendo hacia otra cosa...

EDITAR

También encontré esto, que se ve muy interesante:
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

(solo google SplitMultiDelims para esa función)

contestado el 21 de mayo de 13 a las 22:05

github.com/spreadsheetlab/XLParser es un ejemplo de un esfuerzo más dedicado. - ivan_pozdeev

Muchas gracias por esto. Aquí hay una versión actualizada, compatibilidad si la fórmula tiene verificación de errores y tiene citas dobles: fórmula = Reemplazar (fórmula, """", ""); fórmula = Reemplazar(fórmula, "SI.ERROR", ""); ;; Corrija si la fórmula tiene solo un rango, es decir: =B98: Si esRango(fórmula) Entonces resultRanges.Add Trim(fórmula); Reparar el rango de resultados siempre tiene el primer índice vacío: ReDim resultRangeArray(1 To resultRanges.count); - PalFS

Tbone, Otra opción que no es directamente lo que pediste pero podría funcionar como solución alternativa.

En lugar de usar una fórmula para tratar de encontrar la etiqueta correspondiente, intente ajustar sus fórmulas para que funcionen para usted. Aquí hay un par de opciones dependiendo de cuál sea la fórmula que estaba tratando de analizar. 1. Si su fórmula es una búsqueda, puede simplemente compensar para mirar a la izquierda. 2. Alternativamente, puede usar la función "Indirecta" en ambas fórmulas para asegurarse de que hagan referencia a la ubicación correcta.

Respondido 06 ago 15, 19:08

En resumen, creo que quieres hacer una subparte de: Use VBA to generate code to reproduce basic calculations on an Excel worksheet, y usar una función para devolver la dirección o el nombre del elemento de la colección DirectPrecedents número n.

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

Sin embargo, este caso de uso ha quedado obsoleto. A partir de Excel 2007, las tablas permiten una solución mucho mejor.

Respondido 04 Jul 12, 22:07

¿Malas noticias?: La propiedad DirectPrecedents solo funciona en la hoja activa y no puede rastrear referencias remotas. (msdn.microsoft.com/en-us/library/aa175240(v=office.11).aspx) - tbone

Estoy bastante seguro de que otra limitación de esto (de Excel) será que no se puede llamar desde una fórmula dentro de una celda. - tbone

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.