Para trabajar de manera efectiva en VBA, debe comprender 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 mostrarle de qué son capaces los bucles. Luego te enseñaremos todo sobre los bucles.
Ejemplos rápidos de bucle de VBA
Para cada bucle
For Each Loops recorre cada objeto en una colección, como cada hoja de trabajo en el libro de trabajo o cada celda en un rango.
Recorrer todas las hojas de trabajo en el libro de trabajo
Este código recorrerá todas las hojas de trabajo en el libro de trabajo, mostrando cada hoja:
12345678 | Sub LoopThroughSheets ()Dim ws como hoja de trabajoPara cada ws en hojas de trabajows.Visible = VerdaderopróximoEnd 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:
1234567891011121314 | Sub If_Loop ()Atenuar celda como rangoPara cada celda del rango ("A2: A6")Si Cell.Value> 0 entoncesCell.Offset (0, 1) .Value = "Positivo"Else Si Cell.Value <0 EntoncesCell.Offset (0, 1) .Value = "Negative"DemásCell.Offset (0, 1) .Value = "Cero"Terminara siSiguiente celdaEnd Sub |
Para los siguientes bucles
Otro tipo de bucle “For” es el bucle For Next. For Next Loop le permite recorrer los números enteros.
Este código recorrerá los números enteros del 1 al 10, mostrando cada uno con un cuadro de mensaje:
123456 | Sub ForLoop ()Dim i como enteroPara i = 1 a 10MsgBox iSiguiente yoEnd Sub |
Hacer bucles while
Do While Loops se repetirá mientras se cumpla una condición. Este código también recorrerá los números enteros del 1 al 10, mostrando cada uno con un cuadro de mensaje.
12345678 | Sub DoWhileLoop ()Dim n como enteron = 1Hacer mientras n <11MsgBox nn = n + 1CírculoEnd Sub |
Hacer hasta bucles
Por el contrario, Do until Loops se repetirá hasta que se cumpla una condición. Este código hace lo mismo que los dos ejemplos anteriores.
12345678 | Sub DoUntilLoop ()Dim n como enteron = 1Hacer hasta n> = 10MsgBox nn = n + 1CírculoEnd Sub |
Discutiremos esto a continuación, pero debe tener mucho cuidado al crear bucles Do While o Do until para no crear un bucle interminable.
Generador de bucles VBA
Esta es una captura de pantalla del "Loop Builder" de nuestro complemento VBA Premium: AutoMacro. El generador de bucles le permite crear bucles rápida y fácilmente para recorrer diferentes objetos o números. Puede realizar acciones en cada objeto y / o seleccionar solo objetos que cumplan con ciertos criterios.
El complemento también contiene muchos otros constructores de código, una extensa biblioteca de códigos VBA y una variedad de herramientas de codificación. Es imprescindible para cualquier desarrollador de VBA.
Ahora cubriremos los diferentes tipos de bucles en profundidad.
VBA para el siguiente bucle
Para sintaxis de bucle
For Next Loop le permite repetir un bloque de código un número específico de veces. La sintaxis es:
12345 | [Atenuar contador como entero]Para contador = de principio a fin [valor de paso][Hacer algo]Siguiente [Contador] |
Donde los elementos entre paréntesis son opcionales.
- [Atenuar el contador tanto tiempo] - Declara la variable de contador. Obligatorio si Option Explicit se declara en la parte superior de su módulo.
- Encimera - Una variable entera que se usa para contar
- Comienzo - El valor inicial (Ej. 1)
- Fin - El valor final (Ej. 10)
- [Valor de paso] - Le permite contar cada n números enteros en lugar de cada 1 entero. También puede ir en reversa con un valor negativo (ej. Paso -1)
- [Hacer algo] - El código que se repetirá
- Siguiente [Contador] - Declaración de cierre del For Next Loop. Puedes incluir el Contador o no. Sin embargo, recomiendo encarecidamente incluir el contador, ya que hace que su código sea más fácil de leer.
Si eso le resulta confuso, no se preocupe. Repasaremos algunos ejemplos:
Cuenta hasta 10
Este código contará hasta 10 usando un bucle For-Next:
12345678 | Sub ForEach_CountTo10 ()Dim n como enteroPara n = 1 a 10MsgBox nSiguiente nEnd Sub |
Para paso de bucle
Cuente hasta 10: solo números pares
Este código contará hasta 10 solo contando números pares:
12345678 | Sub ForEach_CountTo10_Even ()Dim n como enteroPara n = 2 a 10 Paso 2MsgBox nSiguiente nEnd Sub |
Observe que agregamos el "Paso 2". Esto le dice al For Loop que “pase” a través del contador en 2. También podemos usar un valor de paso negativo para dar un paso en reversa:
Para paso de bucle: inverso
Cuenta regresiva desde 10
Este código contará hacia atrás desde el 10:
123456789 | Sub ForEach_Countdown_Inverse ()Dim n como enteroPara n = 10 a 1 paso -1MsgBox nSiguiente nMsgBox "Despegue"End Sub |
Eliminar filas si la celda está en blanco
Con mayor frecuencia he usado un paso For-Loop negativo para recorrer los rangos de celdas, eliminando filas que cumplen con ciertos criterios. Si recorre desde las filas superiores hasta las filas inferiores, a medida que elimina filas, arruinará su contador.
Este ejemplo eliminará filas con celdas en blanco (comenzando desde la fila inferior):
12345678910 | Sub ForEach_DeleteRows_BlankCells ()Dim n como enteroPara n = 10 a 1 paso -1Si Rango ("a" & n) .Value = "" EntoncesRango ("a" & n) .EntireRow.DeleteTerminara siSiguiente nEnd Sub |
Anidado para bucle
Puede "anidar" un For Loop dentro de otro For Loop. Usaremos Nested For Loops para crear una tabla de multiplicar:
1234567891011 | Sub Nested_ForEach_MultiplicationTable ()Dim fila como entero, col como enteroPara fila = 1 a 9Para col = 1 a 9Celdas (fila + 1, col + 1) .Valor = fila * colSiguiente columnaFila siguienteEnd Sub |
Salir para
La instrucción Exit For le permite salir de un bucle For Next inmediatamente.
Por lo general, usaría Exit For junto con una instrucción If, saliendo del For Next Loop si se cumple una determinada condición.
Por ejemplo, puede usar un bucle For para buscar una celda. Una vez que se encuentra esa celda, puede salir del bucle para acelerar su código.
Este código recorrerá las filas 1 a 1000, buscando "error" en la columna A. Si se encuentra, el código seleccionará la celda, lo alertará sobre el error encontrado y saldrá del ciclo:
12345678910111213 | Sub ExitFor_Loop ()Dim i como enteroPara i = 1 a 1000Si Range ("A" & i) .Value = "error" EntoncesRango ("A" e i) .SeleccionarMsgBox "Error encontrado"Salir paraTerminara siSiguiente yoEnd Sub |
Importante: En el caso de bucles For anidados, Exit For solo sale del bucle For actual, no de todos los bucles activos.
Continuar para
VBA no tiene el comando "Continuar" que se encuentra en Visual Basic. En su lugar, deberá utilizar "Salir".
VBA para cada bucle
El VBA para cada bucle recorrerá todos los objetos de una colección:
- Todas las celdas de un rango
- Todas las hojas de trabajo en un libro
- Todas las formas en una hoja de trabajo
- Todos los libros 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 en todas las hojas de trabajo
- Todas las hojas de todos los libros abiertos
- etcétera…
La sintaxis es:
123 | Para cada objeto de la colección[Hacer algo]Siguiente [Objeto] |
Dónde:
- Objeto - Variable que representa un rango, hoja de trabajo, libro de trabajo, forma, etc. (por ejemplo, rng)
- Colección - Colección de objetos (ej. Range ("a1: a10")
- [Hacer algo] - Bloque de código para ejecutar en cada objeto
- Siguiente [Objeto] - Frase de cierre. [Objeto] es opcional, sin embargo se recomienda encarecidamente.
Para cada celda en el rango
Este código recorrerá cada celda en un rango:
123456789 | Sub ForEachCell_inRange ()Atenuar celda como rangoPara cada celda del rango ("a1: a10")cell.Value = cell.Offset (0,1) .ValueSiguiente celdaEnd Sub |
Para cada hoja de trabajo en el libro de trabajo
Este código recorrerá todas las hojas de trabajo en un libro, desprotegiendo cada hoja:
123456789 | Sub ForEachSheet_inWorkbook ()Dim ws como hoja de trabajoPara cada ws en hojas de trabajows. Desproteger "contraseña"Siguiente wsEnd Sub |
Para cada libro de trabajo abierto
Este código guardará y cerrará todos los libros abiertos:
123456789 | Sub ForEachWB_inWorkbooks ()Dim wb como libro de trabajoPara cada wb en libros de trabajowb.Close SaveChanges: = TrueSiguiente wbEnd Sub |
Para cada forma en la hoja de trabajo
Este código eliminará todas las formas en la hoja activa.
123456789 | Sub ForEachShape ()Dim shp como formaPara cada artículo en ActiveSheet.Shapesshp.DeleteSiguiente shpEnd Sub |
Para cada forma en cada hoja de trabajo en el libro de trabajo
También puede anidar For Each Loops. Aquí recorreremos todas las formas en todas las hojas de trabajo del libro activo:
1234567891011 | Sub ForEachShape_inAllWorksheets ()Atenuar shp como forma, ws como hoja de trabajoPara cada ws en hojas de trabajoPara cada shp en ws.shp.DeleteSiguiente shpSiguiente wsEnd Sub |
Para cada uno: bucle IF
Como mencionamos antes, puede usar una instrucción If dentro de un bucle, realizando acciones solo si se cumplen ciertos criterios.
Este código ocultará todas las filas en blanco en un rango:
12345678910 | Sub ForEachCell_inRange ()Atenuar celda como rangoPara cada celda del rango ("a1: a10")Si cell.Value = "" Entonces _cell.EntireRow.Hidden = TrueSiguiente celdaEnd Sub |
VBA Do While Loop
Las opciones de VBA Do While y Do until (consulte la siguiente sección) son muy similares. Repetirán un ciclo mientras (o hasta que) se cumpla una condición.
El bucle Do While repetirá un bucle mientras se cumpla una condición.
Aquí está la sintaxis Do While:
123 | Hacer mientras condición[Hacer algo]Círculo |
Dónde:
- Condición - La condición para probar
- [Hacer algo] - El bloque de código para repetir
También puede configurar un bucle Do While con la condición al final del bucle:
123 | Hacer[Hacer algo]Condición de bucle mientras |
Haremos una demostración de cada uno y mostraremos en qué se diferencian:
Hacer mientras
Aquí está el ejemplo de bucle Do While que demostramos anteriormente:
12345678 | Sub DoWhileLoop ()Dim n como enteron = 1Hacer mientras n <11MsgBox nn = n + 1CírculoEnd Sub |
Bucle mientras
Ahora ejecutemos el mismo procedimiento, excepto que moveremos la condición al final del ciclo:
12345678 | Sub DoLoopWhile ()Dim n como enteron = 1HacerMsgBox nn = n + 1Bucle mientras n <11End Sub |
VBA Do hasta bucle
Do until Loops repetirá un bucle hasta que se cumpla una determinada condición. La sintaxis es esencialmente la misma que la de los bucles Do While:
123 | Hacer hasta la condición[Hacer algo]Círculo |
y de manera similar, la condición puede ir al principio o al final del ciclo:
123 | Hacer[Hacer algo]Bucle hasta condición |
Hacer hasta
Este bucle do until contará hasta 10, como en nuestros ejemplos anteriores
12345678 | Sub DoUntilLoop ()Dim n como enteron = 1Hacer hasta n> 10MsgBox nn = n + 1CírculoEnd Sub |
Bucle hasta
Este bucle de bucle hasta contará hasta 10:
12345678 | Sub DoLoopUntil ()Dim n como enteron = 1HacerMsgBox nn = n + 1Bucle hasta n> 10End Sub |
Salir Do Loop
Similar a usar Exit For para salir de un bucle For, usa el comando Exit Do para salir de un bucle Do inmediatamente
1 | Salir Hacer |
Aquí hay un ejemplo de Exit Do:
123456789101112131415 | Sub ExitDo_Loop ()Dim i como enteroi = 1Hacer hasta i> 1000Si Range ("A" & i) .Value = "error" EntoncesRango ("A" e i) .SeleccionarMsgBox "Error encontrado"Salir HacerTerminara siyo = yo + 1CírculoEnd Sub |
Finalizar o romper bucle
Como mencionamos anteriormente, puede usar Exit For o Exit Do para salir de los bucles:
1 | Salir para |
1 | Salir Hacer |
Sin embargo, estos comandos deben agregarse a su código antes de ejecutar su ciclo.
Si está intentando "romper" un bucle que se está ejecutando actualmente, puede intentar presionar ESC o CONTROL + Pausa descanso en el teclado. Sin embargo, es posible que esto no funcione. Si no funciona, deberá esperar a que termine su ciclo o, en el caso de un ciclo sin fin, utilizar CONTROL + ALT + Borrar para forzar el cierre de Excel.
Es por eso que trato de evitar los bucles Do, es más fácil crear accidentalmente un bucle sin fin que te obligue a reiniciar Excel, lo que podría perder tu trabajo.
Más ejemplos de bucles
Bucle a través de filas
Esto recorrerá todas las filas de una columna:
123456789 | Public Sub LoopThroughRows ()Atenuar celda como rangoPara cada celda del rango ("A: A")Ff cell.value "", luego MsgBox cell.address & ":" & cell.valueSiguiente celdaEnd Sub |
Bucle a través de columnas
Esto recorrerá todas las columnas en una fila:
123456789 | Public Sub LoopThroughColumns ()Atenuar celda como rangoPara cada celda del rango ("1: 1")If cell.Value "" Entonces MsgBox cell.Address & ":" & cell.ValueSiguiente celdaEnd Sub |
Recorrer archivos en una carpeta
Este código recorrerá todos los archivos de una carpeta, creando una lista:
12345678910111213141516171819 | Sub LoopThroughFiles ()Dim oFSO como objetoDim oFolder como objetoDim oFile como objetoDim i como enteroEstablecer oFSO = CreateObject ("Scripting.FileSystemObject")Establecer oFolder = oFSO.GetFolder ("C: \ Demo)i = 2Para cada oFile en oFolder.FilesRango ("A" & i) .value = oFile.Nameyo = yo + 1Siguiente oFileEnd Sub |
Bucle a través de la matriz
Este código recorrerá la matriz "arrList":
123 | Para i = LBound (arrList) a UBound (arrList)MsgBox arrList (i)Siguiente yo |
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 funcionarán en Access VBA. Sin embargo, en Access, recorremos el objeto Recordset en lugar del objeto Range.
123456789101112131415161718 | Sub LoopThroughRecords ()En caso de error, reanudar siguienteDim dbs como base de datosDim rst As RecordsetEstablecer dbs = CurrentDbEstablecer rst = dbs.OpenRecordset ("tblClients", dbOpenDynaset)Con la primera.MoveLast.MoveFirstHacer hasta .EOF = VerdaderoMsgBox (rst.Fields ("ClientName")).MoveNextCírculoTerminar conprimer cierreEstablecer rst = NadaEstablecer dbs = NadaEnd Sub |