domingo, 10 de abril de 2022

55 - Propiedad 'HasFormula' en VBA

 En Excel tenemos la función ESFORMULA para determinar si una celda contiene valores o fórmula, devolviendo VERDADERO en caso de que la tenga.

            =ESFORMULA(E3) 

En VBA, también podemos necesitar esta información para tomar alguna decisión. Y para ello utilizaremos la propiedad 'HasFormula' de la celda. 

En esta entrada veremos 2 casos concretos de cómo evaluar esta situación.

CASO 1: si por alguna razón la hoja no puede ser protegida, pero necesitamos impedir que se modifiquen sus fórmulas. 

Lo que haremos es evaluar la situación al momento de seleccionar una celda y en caso de que contenga fórmula, pasar a la celda siguiente. Esto lo controlamos desde el evento SelectionChange de la hoja.

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

If Target.HasFormula Then Target.Offset(0, 1).Select

       'If Target.Row < 3 Then Target.Offset(1, 0).Select

End Sub


Nota: La segunda instrucción no tiene que ver con las fórmulas pero nos sirve para impidir que se modifiquen títulos o encabezados de tablas en una hoja sin protección.

CASO 2: cuando necesitamos agregar algún argumento o alguna otra función a un rango de celdas.

Es un caso frecuente cuando olvidamos agregar la función SI.ERROR en cualquier función que presenta nuestra hoja. Y con las siguientes macros que colocaremos en un módulo, lograremos modificar la celda activa (opción 1) o un rango dentro de la hoja (opción 2).


Opción 1: Solo para la celda activa. Recomiendo utilizar un atajo de teclado para ejecutarla.

Sub cambiaFormula_celda()

'Opción 1: solo la celda activa. Para este caso podrías utilizar un atajo de teclado

'atajo de teclado: CTRL f

 

 With ActiveCell

    If .HasFormula Then

        cadena = Mid(.FormulaR1C1, 2, Len(.FormulaR1C1) - 1)

        'se evalúa si todavía no tiene la función SI.ERROR, en ese caso lo agrega

        If Left(cadena, 7) <> "IFERROR" Then

            .FormulaR1C1 = "=IFERROR(" & cadena & ","""")"

        End If

    End If

End With

End Sub


Opción 2: Para un rango seleccionado previamente. También en este caso es posible utilizar un atajo de teclado para ejecutarla. 

Sub cambiaFormula_seleccion()

'x Elsamatilde

'atajo de teclado: CTRL h

 

'Opción 2: recorriendo el rango previamente seleccionado

'tratándose de un rango extenso es conveniente pasar el modo de cálculo

'a manual para que no recalcule en cada celda y evitar así demoras en el proceso

Application.Calculation = xlCalculationManual

'se recorre cada celda de la selección, evaluando si tiene fórmula o no

For Each cd In Selection

    If cd.HasFormula Then

    'se obtiene la fórmula a partir de la posición 2

        cadena = Mid(cd.FormulaR1C1, 2, Len(cd.FormulaR1C1) - 1)

        'si los 7 1ros caracteres no mencionan iferror se arma la nueva fórmila

        If Left(cadena, 7) <> "IFERROR" Then

            'el última argumento es vacío. Puede ser 0 o algún otro valor.

            cd.FormulaR1C1 = "=IFERROR(" & cadena & ","""")"

        End If

    End If

Next cd

'volver el modo de cálculo a automático

Application.Calculation = xlCalculationAutomatic

'opcional: enviar un mensaje de fin

MsgBox "Fin del proceso.", , "Información"

End Sub

Nota: si el rango es muy extenso como para seleccionarlo previamente, agregar la siguiente instrucción marcada de color (ajustando al rango deseado):

Sub cambiaFormula_seleccion()

'x Elsamatilde

'atajo de teclado: CTRL h

'Opción 2: recorriendo el rango previamente seleccionado

'tratándose de un rango extenso es conveniente pasar el modo de cálculo

'a manual para que no recalcule en cada celda y evitar así demoras en el proceso

Application.Calculation = xlCalculationManual


Range("A2:K200").Select


'se recorre cada celda de la selección, evaluando si tiene fórmula o no

For Each cd In Selection

     '................ continúa la macro.

End Sub

           

El libro con los ejemplos puede ser descargado desde aquí.

Ver video 55 desde aquí.











No hay comentarios.:

Publicar un comentario