Bucles VBA de Excel – For Each, For Next, Do While, Bucles Anidados y Más

Written by

Editorial Team

Reviewed by

Steve Rynearson

Translated by

Dennis Madrid

Last updated on junio 30, 2022

Para trabajar efectivamente en VBA, debe entender los bucles. Los bucles le permiten repetir un bloque de código un número determinado de veces o repetir un bloque de código en cada objeto de un conjunto de objetos.

Primero le mostraremos algunos ejemplos para enseñarle de qué son capaces los bucles. Luego le enseñaremos todo sobre los bucles.

Ejemplos Rápidos de Bucles VBA

Bucles For Each

Los bucles For Each recorren cada objeto de una colección, como cada hoja de trabajo del libro o cada celda de un rango.

Recorrer todas las hojas de trabajo del libro de trabajo

Este código hará un bucle a través de todas las hojas de trabajo en el libro de trabajo, desocultando cada hoja:

Sub BucleAtravesdeHojas()
    Dim hoja As Worksheet
    For Each hoja In Worksheets
        hoja.Visible = True
    Next
End Sub

Recorrer todas las celdas del rango

Este código recorrerá un rango de celdas, probando si el valor de la celda es negativo, positivo o cero:

Sub BucleIf()
Dim Celda As Range
  For Each Celda In Range("A2:A6")
    If Celda.Value > 0 Then
      Celda.Offset(0, 1).Value = "Positivo"
    ElseIf Celda.Value < 0 Then
      Celda.Offset(0, 1).Value = "Negativo"
    Else
      Celda.Offset(0, 1).Value = "Cero"
     End If
  Next Celda
End Sub

Bucle For Condicional If

 

Bucles For Next

Otro tipo de bucle «For» es el bucle For Next. El bucle For Next le permite hacer un bucle a través de enteros. Este código hará un bucle a través de los enteros del 1 al 10, mostrando cada uno con un cuadro de mensaje:

Sub BucleForNext()
    Dim i As Integer
    For i = 1 To 10
        MsgBox i
    Next i
End Sub

Bucles Do While

Los bucles Do While hacen un bucle mientras se cumple una condición. Este código también hará un bucle a través de los enteros del 1 al 10, mostrando cada uno con un cuadro de mensaje.

Sub BucleDoWhile()
    Dim n As Integer
    n = 1
    Do While n < 11
        MsgBox n
        n = n + 1
    Loop
End Sub

Bucles Do Until

A la inversa, los bucles Do Until harán un bucle hasta que se cumpla una condición. Este código hace lo mismo que los dos ejemplos anteriores.

Sub BucleDoUntilLoop()
    Dim n As Integer
    n = 1
    Do Until n >= 10
        MsgBox n
        n = n + 1
    Loop
End Sub

Discutiremos esto más adelante, pero debe tener mucho cuidado cuando cree bucles Do While o Do Until para no crear un bucle interminable.

Constructor de Bucles VBA

vba loop builder Esta es una captura de pantalla del «Constructor de Bucles» de nuestro Complemento VBA Premium : AutoMacro. El Constructor de Bucles le permite construir rápida y fácilmente bucles para recorrer diferentes objetos o números. Puede realizar acciones en cada objeto y/o seleccionar sólo los objetos que cumplan ciertos criterios. El complemento también contiene muchos otros constructores de código, una extensa biblioteca de código VBA y una variedad de herramientas de codificación. Es una herramienta imprescindible para cualquier desarrollador de VBA. Ahora cubriremos los diferentes tipos de bucles en profundidad.

Bucle For Next de VBA

Sintaxis del Bucle For

El bucle For Next le permite repetir un bloque de código un número específico de veces. La sintaxis es:

[Dim contador As Long]
 
For contador = Inicio to Fin [Valor de Paso]
    [Hacer Algo]
Next [contador]

Donde los elementos entre paréntesis son opcionales.

  • [Dim Contador As Long] – Declara la variable contador. Se requiere si la opción explícita se declara en la parte superior de su módulo.
  • Contador – Una variable entero largo utilizada para contar
  • Inicio – El valor inicial (Ej. 1)
  • Fin – El valor final (Ej. 10)
  • [Valor de paso ] – Le permite contar cada n enteros en lugar de cada 1 entero. También puede ir a la inversa con un valor negativo (Ej. Paso -1)
  • [Hacer algo ] – El código que se repetirá
  • Next [contador] – Declaración de cierre del bucle For Next. Puede incluir el contador o no. Sin embargo, recomiendo incluir el contador ya que hace que su código sea más fácil de leer.

Si eso es confuso, no te preocupes. Revisaremos algunos ejemplos:

Contar hasta 10

Este código contará hasta 10 usando un bucle For-Next:

Sub BucleForEach_ContarHasta10()
 
Dim n As Integer
For n = 1 To 10
    MsgBox n
Next n
 
End Sub

Paso del bucle For

Contar hasta 10 – Sólo números pares

Este código contará hasta 10 sólo contando los números pares:

Sub BucleForEach_ContarHasta10_Pares()

Dim n As Integer
For n = 2 To 10 Step 2
    MsgBox n
Next n
 
End Sub

Observe que hemos añadido «Step 2». Esto le dice al bucle For que «pase» por el contador de 2 en 2. También podemos usar un valor de paso negativo para pasar al revés:

Paso del Bucle For – Inverso

Cuenta atrás desde 10

Este código hará la cuenta atrás desde 10:

Sub ForEach_Countdown_Inverse()
 
  Dim n As Integer
  For n = 10 To 1 Step -1
    MsgBox n
  Next n
  MsgBox "Despegue"

End Sub

Borrar Filas si la Celda está en Blanco

La mayoría de las veces he utilizado un bucle For-Loop de paso negativo para hacer un bucle a través de rangos de celdas, eliminando las filas que cumplen ciertos criterios. Si haces un bucle desde las filas superiores a las inferiores, a medida que eliminas filas desordenarás tu contador. Este ejemplo borrará las filas con celdas en blanco (empezando por la fila inferior):

Sub BucleForEach_BorrarFilasEnBlanco()
 
Dim n As Integer
For n = 10 To 1 Step -1
    If Range("A" & n).Value = "" Then
        Range("A" & n).EntireRow.Delete
    End If
Next n
 
End Sub

Bucle For anidado

Puede «anidar» un bucle For dentro de otro bucle For. Utilizaremos los bucles For anidados para crear una tabla de multiplicación:

Sub Nested_ForEach_MultiplicationTable()

Dim row As Integer, col As Integer

Para row = 1 a 9
    Para col = 1 a 9
        Cells(row + 1, col + 1).Value = row * col
    Siguiente col
Siguiente fila

End Sub

Bucle For Anidadados

Exit For

La sentencia Exit For permite salir inmediatamente de un bucle For Next. Normalmente se utiliza Exit For junto con una sentencia If, saliendo del bucle For Next si se cumple una determinada condición. Por ejemplo, puede utilizar un bucle For para encontrar una celda. Una vez que la celda es encontrada, puede salir del bucle para acelerar su código. Este código hará un bucle a través de las filas 1 a 1000, buscando el «error» en la columna A. Si lo encuentra, el código seleccionará la celda, le avisará del error encontrado y saldrá del bucle:

Sub SalidaDeFor_Loop()
 
    Dim i As Integer
    For i = 1 To 1000
        If Range("A" & i).Value = "error" Then
            Range("A" & i).Select
            MsgBox "Error Encontrado"
            Exit For
        End If
    Next i
 
End Sub

Importante: En el caso de los bucles For anidados, Exit For sólo sale del bucle For actual, no de todos los bucles activos.

Continue For

VBA no tiene el comando «Continue» que se encuentra en Visual Basic. En su lugar, necesitará usar «Exit».

Bucle For Each de VBA

El Bucle For Each de VBA recorrerá todos los objetos de una colección:

  • Todas las celdas de un rango
  • Todas las hojas de trabajo de un libro
  • Todas las formas en una hoja de trabajo
  • Todos los libros de trabajo abiertos

También puede utilizar bucles For Each anidados para:

  • Todas las celdas de un rango en todas las hojas de trabajo
  • Todas las formas de todas las hojas de trabajo
  • Todas las hojas de todos los libros de trabajo abiertos
  • y así sucesivamente…

La sintaxis es:

For Each Objeto in Collection
[Hacer algo]
Next [Objeto]

Donde:

  • Objeto – Variable que representa un rango, hoja de trabajo, libro de trabajo, forma, etc. (ej. rng)
  • Colección – Colección de objetos (ej. Rango(«a1:a10»)
  • [Hacer algo ] – Bloque de código a ejecutar en cada objeto
  • Next [ Objeto] – Declaración de cierre. [Objeto] es opcional, pero se recomienda encarecidamente.

Bucle For Each para recorrer cada celda del rango

Este código recorrerá cada celda de un rango:

Sub ForEachCelda_enRange()
 
  Dim celda As Range
 
  For Each celda In Range("a1:a10")
    celda.Value = cell.Offset(0,1).Value
  Next celda
 
End Sub

Bucle For Each para recorrer cada hoja en el libro de trabajo

Este código hará un bucle a través de todas las hojas de trabajo en un libro de trabajo, desprotegiendo cada hoja:

Sub ForEachHoja_enLibro()
    Dim hoja As Worksheet
     
    For Each hoja In Worksheets
        hoja.Unprotect "password"
    Next hoja
End Sub

Bucle For Each para recorrer cada libro de trabajo abierto

Este código guardará y cerrará todos los libros de trabajo abiertos:

Sub ForEachLibro_enLibros()
    Dim libro As Workbook
     
    For Each libro In Workbooks
        libro.Close SaveChanges:=True
    Next libro
End Sub

Bucle For Each para recorrer cada forma en la hoja de trabajo

Este código borrará todas las formas en la hoja activa.

Sub ForEachForma()
    Dim forma As Shape
     
    For Each forma In ActiveSheet.Shapes
        forma.Delete
    Next forma
End Sub

Bucle For Each para recorrer cada forma en cada hoja de trabajo en el libro de trabajo

También puede anidar los bucles For Each. Aquí haremos un bucle a través de todas las formas en todas las hojas de trabajo en el libro de trabajo activo:

Sub ForEachForma_enTodasLasHojas()
    Dim forma As Shape, hoja As Worksheet
     
    For Each hoja In Worksheets
        For Each forma In hoja.Shapes
            forma.Delete
        Next forma
    Next hoja
End Sub

For Each – Bucle IF

Como hemos mencionado antes, puede utilizar una sentencia If dentro de un bucle, realizando acciones sólo si se cumplen ciertos criterios. Este código ocultará todas las filas en blanco de un rango:

Sub ForEachCeldaEnRango()
    Dim celda As Range
     
    For Each celda In Range("a1:a10")
        If celda.Value = "" Then _
           celda.EntireRow.Hidden = True
    Next celda
End Sub

Bucle Do While de VBA

Los bucles VBA Do While y Do Until (ver la siguiente sección) son muy similares. Repetirán un bucle mientras (o hasta que) se cumpla una condición. El bucle Do While repetirá un bucle mientras se cumpla una condición. Esta es la sintaxis del Do While:

Do While Condición
  [Hacer algo]
Loop

Donde:

  • Condición – La condición a probar
  • [Hacer algo] – El bloque de código a repetir

También puede establecer un bucle Do While con la Condición al final del bucle:

Do 
  [Hacer algo]
Loop While Condición

Haremos una demostración de cada uno de ellos y mostraremos en qué se diferencian:

Do While

Aquí está el ejemplo del bucle Do While que demostramos anteriormente:

Sub BucleDoWhile()
    Dim n As Integer
    n = 1
    Do While n < 11
        MsgBox n
        n = n + 1
    Loop
End Sub

Bucle While

Ahora vamos a ejecutar el mismo procedimiento, excepto que moveremos la condición al final del bucle:

Sub BucleDoLoopWhile()
    Dim n As Integer
    n = 1
    Do
        MsgBox n
        n = n + 1
    Loop While n < 11
End Sub

Bucle Do Until de VBA

Los bucles Do Until repetirán un bucle hasta que se cumpla una determinada condición. La sintaxis es esencialmente la misma que la de los bucles Do While:

Do Until Condición
  [Hacer algo]
Loop

y de forma similar la condición puede ir al principio o al final del bucle:

Do
  [Hacer Algo]
Loop Until Condición

Do Until

Este bucle Do Until contará hasta 10, como nuestros ejemplos anteriores

Sub BucleDoUntil()
    Dim n As Integer
    n = 1
    Do Until n > 10
        MsgBox n
        n = n + 1
    Loop
End Sub

Bucle Loop Until

Este bucle Loop Until contará hasta 10:

Sub BucleDoLoopUntil()
    Dim n As Integer
    n = 1
    Do
        MsgBox n
        n = n + 1
    Loop Until n > 10
End Sub

Salir del Bucle Do

De forma similar al uso de Exit For para salir de un bucle For, se utiliza el comando Exit Do para salir de un bucle Do inmediatamente

Exit Do

Aquí hay un ejemplo de Exit Do:

Sub EjemploExitDo_Loop()
    Dim i As Integer
    i = 1
     
    Do Until i > 1000
        If Range("A" & i).Value = "error" Then
            Range("A" & i).Select
            MsgBox "Error Encontrado"
            Exit Do
        End If
        i = i + 1
    Loop
End Sub

Finalizar o romper el bucle

Como mencionamos anteriormente, puedes usar el Exit For o Exit Do para salir de los bucles:

Exit For
Exit Do

Sin embargo, estos comandos deben ser añadidos a su código antes de ejecutar su bucle. Si está tratando de «romper» un bucle que se está ejecutando actualmente, puede intentar presionar ESC o CTRL + Pause Break en el teclado. Sin embargo, esto puede no funcionar. Si no funciona, tendrás que esperar a que tu bucle termine o, en el caso de un bucle infinito, utilizar CTRL + ALT + Supr para forzar el cierre de Excel. Esta es la razón por la que trato de evitar los bucles Do, es más fácil crear accidentalmente un bucle sin fin que te obligue a reiniciar Excel, perdiendo potencialmente tu trabajo.

Más Ejemplos de Bucles

Bucle a través de las filas

Esto hará un bucle a través de todas las filas de una columna:

Sub BucleATravesdeFilas()
    Dim celda As Range
    For Each celda In Range("A:A")
        If celda.Value <> "" Then MsgBox celda.Address & ": " & celda.Value
    Next celda
End Sub

Bucle a través de las columnas

Esto hará un bucle a través de todas las columnas de una fila:

Sub BucleATravesdeColumnas()
    Dim celda As Range
    For Each celda In Range("1:1")
        If celda.Value <> "" Then MsgBox celda.Address & ": " & celda.Value
    Next celda
End Sub

Recorrer los archivos de una carpeta

Este código recorrerá todos los archivos de una carpeta, creando una lista:

Sub BucleATravesdeArchivos()
    Dim oFSO As Object
    Dim oFolder As Object
    Dim oFile As Object
    Dim i As Integer
     
    Set oFSO = CreateObject("Scripting.FileSystemObject")
     
    Set oFolder = oFSO.GetFolder("C:\Demo)
     
    i = 2
     
    For Each oFile In oFolder.Files
        Range("A" & i).Value = oFile.Name
        i = i + 1
    Next oFile
End Sub

Bucle a través de la matriz

Este código recorrerá el array ‘arrList’:

Sub bucleATravesdeMatriz()
    For i = LBound(matriz) To UBound(matriz)
        MsgBox matriz(i)
    Next i
End Sub

La función LBound obtiene el «límite inferior» de la matriz y UBound obtiene el «límite superior».

Bucles en Access VBA

La mayoría de los ejemplos anteriores también funcionan en Access VBA. Sin embargo, en Access, hacemos un bucle a través del objeto Recordset en lugar del objeto Range.

Sub BucleATravesdeRegistros()
   On Error Resume Next
   Dim dbs As Database
   Dim rst As Recordset
   Set dbs = CurrentDb
   Set rst = dbs.OpenRecordset("tblClients", dbOpenDynaset)
   With rst
      .MoveLast
      .MoveFirst
      Do Until .EOF = True
         MsgBox (rst.Fields("NombreDelCliente"))
        .MoveNext
     Loop
   End With
   rst.Close
   Set rst = Nothing
   Set dbs = Nothing
End Sub
vba-free-addin

Complemento de Ejemplos de Código de VBA

Acceda fácilmente a todos los ejemplos de código que se encuentran en nuestro sitio.

Simplemente navegue al menú, haga clic y el código se insertará directamente en su módulo. Complemento .xlam.

(¡No se requiere instalación!)

Descarga gratuita

Return to VBA Code Examples