Programando decisiones en VBA con If
¿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.