Programando decisiones en VBA con If

Estructura If en VBA Excel decisiones

¿Lo hago o no lo hago? Eso depende de alguna una circunstancia o condición, ¿verdad? ¿Estudio periodismo o no? Pues si quieres ser periodista evidentemente tienes que estudiar periodismo. Estás tomando una decisión basándote en el resultado que esperas.

Puedes aplicar esta misma lógica en VBA para tomar decisiones de este tipo (y mucho más complejas) con la estructura condicional If-Then.

Hoy te mostraré diferentes formas de usar la estructura condicional más famosa y algunos ejemplos para que le saques todo el partido.

Antes de meterme de lleno en los detalles déjame enseñarte la sintaxis de If-Then:

Puedes usarla de dos formas:

If condición Then código_si_verdadero [Else código_si_falso]

o

If condición Then
    Código_si_verdadero
[Else
    Código_si_falso]
End If

Recuerda que los corchetes [] indican que se trata de una parte opcional.

La diferencia entre las dos sintaxis es que en la primera no se utiliza la instrucción de cierre End If, pues todo el código de la instrucción se encuentra en una sola línea. Esto es útil cuando únicamente debe realizarse una acción. Si se trata de dos o más acciones es mejor la segunda opción, ya que el código queda más ordenado.

Cuando se introducen varias líneas de código en la instrucción If, VBA necesita saber dónde finaliza la estructura (por eso lo del End If). Si por descuido no lo introduces, te encontrarás con este error:

Ejemplos sencillos con If Then

Para hacerte una idea de cómo funciona la instrucción If-Then en VBA déjame comenzar con algunos ejemplos básicos.

Imagina que en la celda A1 tienes la nota del examen de un alumno y quieres comprobar si ha aprobado o no teniendo en cuenta que supera el examen cuando la calificación es 5 o superior. Para comprobarlo puedes usar este procedimiento:

Sub Aprueba()
    If Range("A1").Value >= 5 Then MsgBox "¡Aprobado!"
End Sub

En la línea de código se comprueba el valor de la celda A1. Si es igual o mayor de 5 se muestra el mensaje “¡Aprobado!”. Si es menor que 5, con pasa nada.

En el caso de que quieras mostrar un mensaje en ambos casos, tanto si la nota es igual o mayor que 5 o menor que 5 necesitarías un código como este:

Sub Aprueba()
    If Range("A1").Value >= 35 Then
        MsgBox "¡Aprobado!"
    Else
        MsgBox "¡Suspenso!"
    End If
End Sub

En este procedimiento se utiliza la instrucción If y la cláusula Else para ejecutar dos acciones diferentes. Cuando la calificación es igual o mayor que 5, la condición de If toma el valor True (verdadero) y se ejecuta el código que hay entre esa línea y la cláusula Else.

Pero cuando la condición de If es False, el código salta a la clausula Else y ejecuta el código que hay debajo de ella.

Supongo que habrás observado una ligera diferencia entre los dos procedimientos anteriores. En el primero no es necesario cerrar la condición con End If porque he incluido todo el código en una sola línea. Si divido la estructura If-Then en varias líneas, es necesario indicarle a VBA dónde finalizan las acciones de la condición.

Cómo anidar varios If Then

En los ejemplos anteriores he usado la estructura básica de If-Then. Voy a complicarlos un poco, pues no es habitual encontrarte con situaciones tan sencillas, ¿verdad?

Cuando necesitas evaluar varias condiciones para las mismas acciones se hace necesario anidar varias instrucciones If. Se pueden afrontar de tres formas:

  • Usando varias instrucciones If-Then
  • Usando varias instrucciones If-Then-Else
  • Usando la estructura If-Then ElseIf Else

Varias instrucciones If Then

Sigo con el mismo ejemplo de antes: la calificación del examen del alumno.

Si el alumno obtiene una nota inferior a 5 se mostrará el mensaje “¡Suspenso!” y si es igual o superior aparecerá un cuadro con el mensaje “¡Aprobado!”. Observa el siguiente procedimiento:

Sub Aprueba()
    If Range("A1").Value < 5 Then MsgBox "¡Suspenso!"
    If Range("A1").Value >= 5 Then MsgBox "¡Aprobado!"
End Sub

Es posible escribir tantas instrucciones If Then como quieras. Sin embargo no es un buen ejemplo de codificación. Te mostraré algunas alternativas a continuación.

Aun así, en caso de que decidas usarlo recuerda que cada una de las líneas If deben ser independientes o excluyentes. Lo importante es saber que todas ellas se evaluarán y se ejecutará el código en aquellas en las que la condición sea verdadera.

En el ejemplo anterior, incluso la primera línea se evalúa como verdadera, también se evaluaría la segunda.

Ejemplos con If Then Else anidados

Ahora imagina que en lugar de mostrar los mensajes “¡Suspenso!” o “¡Aprobado!”, existe una condición más.

Si el alumno tiene una calificación menor que 5 se mostrará el mensaje de suspenso, si es igual o mayor que 5 se muestra el mensaje de aprobado y si la calificación superior a 9 debe aparecer el mensaje “¡Sobresaliente!”.

Observa el código:

Sub Aprueba()
    If Range("A1").Value < 5 Then
        MsgBox "¡Suspenso!"
    Else
        If Range("A1").Value < 9 Then
            MsgBox "¡Aprobado!"
        Else
            MsgBox "¡Sobresaliente!"
        End If
    End If
End Sub

En el procedimiento he utilizado varias instrucciones If-Then anidadas ayudándome de la cláusula Else.

El valor de la celda se evalúa una primera vez. Si es menor que 5 aparece el mensaje correspondiente, pero si es mayor se ejecuta otra instrucción If preguntando si el valor es menor que 9. En caso de que sea menor aparece el mensaje de aprobado y si no es menor, se muestra “¡Sobresaliente!”.

De la misma forma que podemos anidar unos bucles dentro de otros, lo podemos hacer con las instrucciones condicionales.

Ejemplos con If Then ElseIf Else

Pero es posible optimizar más el código anterior usando la cláusula ElseIf.

Sub Aprueba()
    If Range("A1").Value < 5 Then
        MsgBox "¡Suspenso!"
    ElseIf Range("A1").Value < 9 Then
        MsgBox "¡Aprobado!"
    Else
        MsgBox "¡Sobresaliente!"
    End If
End Sub

ElseIf permite agrupar varias condiciones en un solo If.

If Then con condiciones complejas

En todos los ejemplos anteriores solo se ha evaluado una condición en cada If. Sin embargo cuando se dan varias condiciones dependientes es posible utilizar las cláusulas And y Or con la instrucción If.

Te lo explico con un ejemplo:

If condición1 And condición2 Then
        instrucciones_si_verdadero
    Else
        instrucciones_si_falso
End If

En el ‘código’ anterior (no es un procedimiento como tal sino un pseudocódigo), sólo cuando se cumplen la condición1 Y la condición2, se ejecutan las instrucciones_si_verdadero. Si una de las condiciones (o las dos) es falsa, la instrucción If devuelve también falso y se ejecutarán las instrucciones_si_falso.

Con Or ocurre algo similar. Si una sola de las condiciones es verdadera (o las dos), se ejecutan las instrucciones_si_verdadero. Cuando todas las condiciones son falsas se ejecutan las instrucciones_si_falso.

¿Cómo puedes aplicar esto al ejemplo de las calificaciones?

Imagina que quieres evaluar dos calificaciones en lugar de una. Una de ellas se encuentra en la celda A1 y la otra en B1. Las condiciones a evaluar son las siguientes:

  • ¡Suspenso!” cuando la nota es inferior a 5 en cualquiera de las asignaturas.
  • ¡Aprobado!” cuando la nota es mayor o igual a 5 pero inferior a 9 en las dos asignaturas.
  • ¡Sobresaliente!” cuando la nota es mayor que 5 en ambas asignaturas y es mayor o igual a 9 en una o las dos asignaturas.

Este código hace posible las condiciones anteriores:

Sub Aprueba()
    If Range("A1").Value < 5 Or Range("B1").Value < 5 Then
        MsgBox "¡Suspenso!"
    ElseIf Range("A1").Value < 9 And Range("B1").Value < 9 Then
        MsgBox "¡Aprobado!"
    Else
        MsgBox "¡Sobresaliente!"
    End If
End Sub

Observa cómo he usado And y Or.

Para obtener el mismo resultado también podría haber usado Or en vez de And en el ElseIf:

Sub Aprueba()
    If Range("A1").Value < 5 Or Range("B1").Value < 5 Then
        MsgBox "¡Suspenso!"
    ElseIf Range("A1").Value > 9 Or Range("B1").Value > 9 Then
        MsgBox "¡Sobresaliente!"
    Else
        MsgBox "¡Aprobado!"
    End If
End Sub

Los dos códigos anteriores dan el mismo resultado pero personalmente prefiero el primero, porque tiene un flujo más lógico de comprobación (o eso pienso yo).

Cómo usar el operador Distinto a

En todos los ejemplos anteriores he usado los operadores =, >= y <.

También es posible usar una condición en la cual el valor distinto a otro valor. Esto se hace mediante el operador <>. Tienes un ejemplo un poco más abajo

Cómo usar la estructura If Then Else dentro de bucles

Hasta ahora te he mostrado algunos ejemplos para que entiendas el funcionamiento de If-Then en VBA sin embargo en el mundo real no te servirán de mucho. Estoy seguro de que las condiciones que se te presenten en tus tareas diarias serán más complejas que una simple comparación de calificaciones…

A continuación te muestro más ejemplos prácticos que pueden ayudarte a automatizar algunas tareas para ser más eficiente.

Cómo guardar y cerrar todos los libros excepto el activo

Cuando tengas muchos libros de Excel abiertos y quieras mantener abierto únicamente el libro activo, puedes usar el siguiente procedimiento:

Sub CerrarLibrosExceptoActivo()
    Dim wb As Workbook
    For Each wb In Workbooks
        On Error Resume Next
        If wb.Name <> ActiveWorkbook.Name Then
            wb.Save
            wb.Close
        End If
    Next wb
End Sub

Esta macro guarda (Save) y cierra (Close) todos los libros excepto el libro activo.

Utiliza el bucle For Each-Next para recorrer la colección de libros abiertos y comprueba si el nombre coincide con el libro activo.

Si el nombre no es el mismo que el del libro activo, lo cierra y lo guarda.

En caso de que existan macros en alguno de los libros y no lo hayas guardado previamente como .xlsm, aparecerá una advertencia (pues el código VBA se pierde al guardarlo como .xlsx).

Ocultar todas las hojas excepto la activa

Un procedimiento similar al anterior. En este caso se ocultan todas las hojas del libro excepto la activa.

Sub OcultarHojasExceptoActiva()
    Dim ws As Worksheet
    For Each ws In ThisWorkbook.Worksheets
        If ws.Name <> ActiveSheet.Name Then ws.Visible = xlSheetHidden
    Next ws
End Sub

El código anterior recorre la colección de hojas comprobando si el nombre de cada una de ellas coincide con el de la hoja activa. Si no es así, la hoja se oculta.

Resaltar celdas con números negativos

Imagina que tienes una columna con números y quieres resaltar los valores negativos en color rojo (sin usar el formato condicional, claro ????).

Sub ResaltaNegativos()
    Dim celda As Range
    For Each celda In Selection
        If celda.Value < 0 Then
            celda.Interior.Color = vbRed
            celda.Font.Color = vbWhite
        End If
    Next celda
End Sub

El bucle del procedimiento anterior recorre todas las celdas del rango que tengas seleccionado. Si la celda tiene un número negativo, se resalta en rojo con la fuente en blanco.

Extraer la parte numérica de valores alfanuméricos

Una petición muy habitual en el foro de Ayuda Excel es la de separar los números de las letras de un valor alfanumérico. Con la siguiente función puedes extraer los números de cualquier celda:

Function ExtraeNumeros(celda As String)
    Dim largovalor As Integer
    largovalor = Len(celda)
    For i = 1 To largovalor
        If IsNumeric(Mid(celda, i, 1)) Then Resultado = Resultado & Mid(celda, i, 1)
    Next i
    ExtraeNumeros = Resultado
End Function

Como se trata de una función puedes usarla como tal (desde la hoja). Escribe el signo igual en una celda y a continuación “ExtraeNumeros”. Abre un paréntesis, selecciona la celda que contenga el valor a extraer y cierra el paréntesis. Así de sencillo.

Resumen

La instrucción If es la más utilizada en VBA para tomar decisiones en el código. En función de una o varias condiciones el flujo de código ejecuta diferentes bloques de acciones.

Las condiciones a evaluar pueden ser tan sencillas como una simple igualdad o tan complejas como sea necesario, pues If puede usar algunas cláusulas como And y Or para combinar cualquier criterio que se ponga por delante.