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 impedir 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()

'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órmula

        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()

'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í.

Acceso al VIDEO Nº 55 desde aquí.











No hay comentarios.:

Publicar un comentario