Bucles
Desliza para mostrar el menú
Hasta ahora, cada técnica ha trabajado con un solo valor a la vez. Los bucles permiten aplicar la misma lógica a muchos valores en una fila — cinco productos, quinientos pedidos, o la cantidad de filas que contenga una tabla — sin necesidad de copiar y pegar el mismo bloque de código una y otra vez.
For...Next
Repite un bloque de código un número fijo y conocido de veces:
Dim i As Long
For i = 1 To 5
Debug.Print "Row " & i
Next i
' Step lets you skip or count backward
For i = 10 To 1 Step -1
Debug.Print i
Next i
En el primer bucle, i comienza en 1, el código dentro se ejecuta una vez con ese valor, luego i aumenta automáticamente en 1 y todo el bloque se ejecuta de nuevo — repitiendo hasta que i supera 5, momento en el que el bucle simplemente se detiene y la ejecución continúa después de Next. Step cambia el incremento: Step -1 cuenta hacia abajo en lugar del valor predeterminado de uno en uno hacia arriba, y Step 2 contaría de dos en dos. La variable de bucle i no es una sintaxis especial — es simplemente una variable Long ordinaria que VBA actualiza por ti en cada iteración.
For Each
Itera directamente sobre cada elemento de una colección, sin necesidad de saber cuántos elementos hay ni de gestionar un contador manualmente:
Dim cell As Range
For Each cell In ThisWorkbook.Worksheets("Products").Range("B2:B6")
Debug.Print cell.Value
Next cell
Aquí, cell toma cada celda individual en el rango B2:B6 en orden, y puedes leer lo que contiene usando .Value. Compáralo con For...Next: con For...Next cuentas a través de números y usas ese número para buscar algo; con For Each recorres directamente los elementos, lo que resulta más natural cuando trabajas con rangos de hojas de cálculo.
Do While
Repite mientras una condición siga siendo True — el bucle no sabe de antemano cuántas veces se ejecutará, lo que lo diferencia de For...Next:
Dim stock As Integer
stock = 134
Do While stock > 0
stock = stock - 30 ' simulate selling in batches of 30
Loop
Debug.Print stock ' whatever's left after the loop stops
VBA comprueba stock > 0 antes de cada pasada por el bucle, incluida la primera. Haz el seguimiento manualmente: 134 → 104 → 74 → 44 → 14, y luego la condición se verifica de nuevo — 14 sigue siendo mayor que 0, así que el bucle se ejecuta una vez más, llegando a -16. Solo entonces stock > 0 finalmente resulta Falso, y el bucle se detiene con stock en -16, no exactamente en 0 o 14. Esto merece ser analizado con cuidado la primera vez, porque es una fuente común de errores de un paso: un bucle Do While sigue ejecutándose mientras la condición sea verdadera en el momento en que se verifica, incluso si la acción dentro del bucle sobrepasa el límite que tenías en mente.
Do Until
También existe Do Until, que es la imagen inversa de Do While — repite mientras una condición sea False y se detiene en el momento en que esa condición se vuelve True, en lugar de al revés. Cuál resulta más natural depende de cómo expresarías la regla de negocio en voz alta: "seguir mientras quede stock" sugiere Do While; "seguir hasta que se acabe el stock" sugiere Do Until — pueden producir el mismo comportamiento, solo que expresados desde direcciones opuestas.
Sentencias Exit
Permiten salir de un bucle antes de que se alcance su condición final natural:
For i = 1 To 100
If i = 10 Then Exit For ' stop the loop immediately
Debug.Print i
Next i
Este bucle está configurado para contar hasta 100, pero en el momento en que i llega a 10, Exit For lo detiene de inmediato — nada después de Exit For se ejecuta, y la ejecución salta directamente a la línea después de Next i. Este es el patrón que usarías para buscar en una lista y detenerte tan pronto como encuentres lo que buscas, en lugar de seguir comprobando innecesariamente cada elemento restante.
Integrando todo
Cada técnica de este capítulo — variables, operadores, funciones, lógica condicional y ahora bucles — se combina en el procedimiento hacia el que ha ido construyendo este capítulo:
Option Explicit
Sub CheckStockLevels()
' Sample data standing in for the Products table
Dim products(1 To 5) As String
Dim stockLevels(1 To 5) As Integer
Dim reorderLevels(1 To 5) As Integer
Dim i As Long
Dim alertMessage As String
products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20
products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30
products(3) = "USB-C Hub": stockLevels(3) = 44: reorderLevels(3) = 15
products(4) = "Monitor Arm": stockLevels(4) = 18: reorderLevels(4) = 10
products(5) = "Keyboard": stockLevels(5) = 61: reorderLevels(5) = 20
alertMessage = ""
For i = 1 To 5
Select Case stockLevels(i)
Case Is <= reorderLevels(i)
alertMessage = alertMessage & products(i) & _
" — REORDER NOW" & vbNewLine
Case Is <= reorderLevels(i) + 10
alertMessage = alertMessage & products(i) & _
" — watch closely" & vbNewLine
End Select
Next i
If alertMessage = "" Then
MsgBox "All products are adequately stocked."
Else
MsgBox "Stock Alerts:" & vbNewLine & alertMessage
End If
End Sub
- Dim products(1 To 5) As String y las dos líneas similares debajo declaran arreglos — cada uno es una fila numerada de cinco casillas en lugar de una sola, así que products(1) es el nombre del primer producto, products(2) el segundo, y así sucesivamente;
- Las cinco líneas que usan dos puntos (
:) entre sentencias agrupan varias asignaciones en una sola línea solo por legibilidad aquí —products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20es exactamente equivalente a escribirlas como tres líneas separadas; For i = 1 To 5 ... Next irecorre los cinco productos uno a uno, usando i tanto como contador del bucle como índice de cada arreglo;Select Case stockLevels(i)vuelve a ejecutar la misma decisión basada en rangos de la sección 2.4, pero ahora con datos reales de arreglos en lugar de un solo número fijo;- Case Is <= reorderLevels(i) detecta cualquier producto cuyo stock haya caído en o por debajo de su propio nivel de reposición — observa que reorderLevels(i) es en sí mismo una variable, no un número fijo, así que cada producto se evalúa contra su propio umbral en lugar de un umbral para todos;
alertMessage = alertMessage & ... & vbNewLineconstruye una cadena creciente línea por línea —vbNewLinees una constante incorporada que inserta un salto de línea, así que cada producto marcado aparece en su propia línea en el mensaje final;- La comprobación final
If alertMessage = "" Thenes la que decide cuál de las dos variantes deMsgBoxve realmente el usuario — una cadena vacía significa que el bucle nunca encontró nada que señalar.
Ejecuta esto y deberías ver que el Monitor Arm está marcado como "observar de cerca" (18 unidades frente a un nivel de reposición de 10); sigue el bucle manualmente para i = 4 si quieres confirmar exactamente por qué es el único detectado por el segundo Case y no por el primero. Este procedimiento utiliza arreglos, un bucle, un Select Case y construcción de cadenas, todo funcionando en conjunto. Esto ya se acerca genuinamente a una lógica de calidad de producción, solo que se ejecuta con datos de ejemplo escritos directamente en el código en lugar de en una hoja de cálculo real.
Tarea
- Copia
CheckStockLevelsen tu libro de trabajo y ejecútalo. Confirma que el mensaje coincide con la captura de pantalla. - Cambia el stock del Wireless Mouse a 25 y vuelve a ejecutar: ahora también debería aparecer como "observar de cerca".
- Agrega un bucle
Do Whiledebajo que simule la venta de 15 unidades de Laptop Stand a la vez hasta que el stock baje a 20 o menos, imprimiendo el total acumulado en la ventana Inmediato después de cada venta. - Desafío: reescribe el bucle
For i = 1 To 5usandoFor Eachsobre un arreglo Variant en su lugar — ¿la lógica sigue funcionando?
2. Cambiar el stock del Mouse Inalámbrico
- Busca la línea que configura los datos del Mouse Inalámbrico:
products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30. - Solo necesitas cambiar el número del medio (
134) por25— deja el nombre del producto y el nivel de reposición tal como están. - Antes de ejecutarlo, analiza manualmente qué
Caselo capturará: ¿es 25 ≤ 30 (el nivel de reposición)? Compáralo específicamente con la líneaCase Is <= reorderLevels(i), no con la segunda.
3. Simulación de ventas por lotes con Do While
- Se necesita una variable para almacenar el stock actual del Laptop Stand — iníciala con el mismo valor que ya está en
stockLevels(1)(58), así no escribes un número nuevo que podría desincronizarse con el resto de la macro. - La condición del bucle debe comprobar si el stock sigue por encima de 20 — en el momento en que verifique y encuentre el stock en 20 o menos, debe detenerse.
- Resta 15 en cada iteración y muestra el nuevo valor justo después de restar — no antes — para que cada número impreso refleje una venta completada.
- Haz el seguimiento en papel primero: 58 → 43 → 28 → 13. Observa que el último valor cae por debajo de 20 en lugar de llegar exactamente a 20 — ese es el mismo comportamiento de "exceso" del
Do Whileque el diagrama de bucles del capítulo explicó antes, no es un error.
Punto 2 — dentro de CheckStockLevels, solo cambia un número:
products(2) = "Wireless Mouse": stockLevels(2) = 25: reorderLevels(2) = 30
Ejecuta el Sub nuevamente.
Punto 3 — agrega esto debajo del código existente, aún dentro de CheckStockLevels (antes de End Sub):
' --- Simulate selling Laptop Stand in batches of 15 ---
Dim laptopStandStock As Integer
laptopStandStock = stockLevels(1)
Do While laptopStandStock > 20
laptopStandStock = laptopStandStock - 15
Debug.Print laptopStandStock
Loop
¡Gracias por tus comentarios!
Pregunte a AI
Pregunte a AI
Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla
Bucles
Hasta ahora, cada técnica ha trabajado con un solo valor a la vez. Los bucles permiten aplicar la misma lógica a muchos valores en una fila — cinco productos, quinientos pedidos, o la cantidad de filas que contenga una tabla — sin necesidad de copiar y pegar el mismo bloque de código una y otra vez.
For...Next
Repite un bloque de código un número fijo y conocido de veces:
Dim i As Long
For i = 1 To 5
Debug.Print "Row " & i
Next i
' Step lets you skip or count backward
For i = 10 To 1 Step -1
Debug.Print i
Next i
En el primer bucle, i comienza en 1, el código dentro se ejecuta una vez con ese valor, luego i aumenta automáticamente en 1 y todo el bloque se ejecuta de nuevo — repitiendo hasta que i supera 5, momento en el que el bucle simplemente se detiene y la ejecución continúa después de Next. Step cambia el incremento: Step -1 cuenta hacia abajo en lugar del valor predeterminado de uno en uno hacia arriba, y Step 2 contaría de dos en dos. La variable de bucle i no es una sintaxis especial — es simplemente una variable Long ordinaria que VBA actualiza por ti en cada iteración.
For Each
Itera directamente sobre cada elemento de una colección, sin necesidad de saber cuántos elementos hay ni de gestionar un contador manualmente:
Dim cell As Range
For Each cell In ThisWorkbook.Worksheets("Products").Range("B2:B6")
Debug.Print cell.Value
Next cell
Aquí, cell toma cada celda individual en el rango B2:B6 en orden, y puedes leer lo que contiene usando .Value. Compáralo con For...Next: con For...Next cuentas a través de números y usas ese número para buscar algo; con For Each recorres directamente los elementos, lo que resulta más natural cuando trabajas con rangos de hojas de cálculo.
Do While
Repite mientras una condición siga siendo True — el bucle no sabe de antemano cuántas veces se ejecutará, lo que lo diferencia de For...Next:
Dim stock As Integer
stock = 134
Do While stock > 0
stock = stock - 30 ' simulate selling in batches of 30
Loop
Debug.Print stock ' whatever's left after the loop stops
VBA comprueba stock > 0 antes de cada pasada por el bucle, incluida la primera. Haz el seguimiento manualmente: 134 → 104 → 74 → 44 → 14, y luego la condición se verifica de nuevo — 14 sigue siendo mayor que 0, así que el bucle se ejecuta una vez más, llegando a -16. Solo entonces stock > 0 finalmente resulta Falso, y el bucle se detiene con stock en -16, no exactamente en 0 o 14. Esto merece ser analizado con cuidado la primera vez, porque es una fuente común de errores de un paso: un bucle Do While sigue ejecutándose mientras la condición sea verdadera en el momento en que se verifica, incluso si la acción dentro del bucle sobrepasa el límite que tenías en mente.
Do Until
También existe Do Until, que es la imagen inversa de Do While — repite mientras una condición sea False y se detiene en el momento en que esa condición se vuelve True, en lugar de al revés. Cuál resulta más natural depende de cómo expresarías la regla de negocio en voz alta: "seguir mientras quede stock" sugiere Do While; "seguir hasta que se acabe el stock" sugiere Do Until — pueden producir el mismo comportamiento, solo que expresados desde direcciones opuestas.
Sentencias Exit
Permiten salir de un bucle antes de que se alcance su condición final natural:
For i = 1 To 100
If i = 10 Then Exit For ' stop the loop immediately
Debug.Print i
Next i
Este bucle está configurado para contar hasta 100, pero en el momento en que i llega a 10, Exit For lo detiene de inmediato — nada después de Exit For se ejecuta, y la ejecución salta directamente a la línea después de Next i. Este es el patrón que usarías para buscar en una lista y detenerte tan pronto como encuentres lo que buscas, en lugar de seguir comprobando innecesariamente cada elemento restante.
Integrando todo
Cada técnica de este capítulo — variables, operadores, funciones, lógica condicional y ahora bucles — se combina en el procedimiento hacia el que ha ido construyendo este capítulo:
Option Explicit
Sub CheckStockLevels()
' Sample data standing in for the Products table
Dim products(1 To 5) As String
Dim stockLevels(1 To 5) As Integer
Dim reorderLevels(1 To 5) As Integer
Dim i As Long
Dim alertMessage As String
products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20
products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30
products(3) = "USB-C Hub": stockLevels(3) = 44: reorderLevels(3) = 15
products(4) = "Monitor Arm": stockLevels(4) = 18: reorderLevels(4) = 10
products(5) = "Keyboard": stockLevels(5) = 61: reorderLevels(5) = 20
alertMessage = ""
For i = 1 To 5
Select Case stockLevels(i)
Case Is <= reorderLevels(i)
alertMessage = alertMessage & products(i) & _
" — REORDER NOW" & vbNewLine
Case Is <= reorderLevels(i) + 10
alertMessage = alertMessage & products(i) & _
" — watch closely" & vbNewLine
End Select
Next i
If alertMessage = "" Then
MsgBox "All products are adequately stocked."
Else
MsgBox "Stock Alerts:" & vbNewLine & alertMessage
End If
End Sub
- Dim products(1 To 5) As String y las dos líneas similares debajo declaran arreglos — cada uno es una fila numerada de cinco casillas en lugar de una sola, así que products(1) es el nombre del primer producto, products(2) el segundo, y así sucesivamente;
- Las cinco líneas que usan dos puntos (
:) entre sentencias agrupan varias asignaciones en una sola línea solo por legibilidad aquí —products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20es exactamente equivalente a escribirlas como tres líneas separadas; For i = 1 To 5 ... Next irecorre los cinco productos uno a uno, usando i tanto como contador del bucle como índice de cada arreglo;Select Case stockLevels(i)vuelve a ejecutar la misma decisión basada en rangos de la sección 2.4, pero ahora con datos reales de arreglos en lugar de un solo número fijo;- Case Is <= reorderLevels(i) detecta cualquier producto cuyo stock haya caído en o por debajo de su propio nivel de reposición — observa que reorderLevels(i) es en sí mismo una variable, no un número fijo, así que cada producto se evalúa contra su propio umbral en lugar de un umbral para todos;
alertMessage = alertMessage & ... & vbNewLineconstruye una cadena creciente línea por línea —vbNewLinees una constante incorporada que inserta un salto de línea, así que cada producto marcado aparece en su propia línea en el mensaje final;- La comprobación final
If alertMessage = "" Thenes la que decide cuál de las dos variantes deMsgBoxve realmente el usuario — una cadena vacía significa que el bucle nunca encontró nada que señalar.
Ejecuta esto y deberías ver que el Monitor Arm está marcado como "observar de cerca" (18 unidades frente a un nivel de reposición de 10); sigue el bucle manualmente para i = 4 si quieres confirmar exactamente por qué es el único detectado por el segundo Case y no por el primero. Este procedimiento utiliza arreglos, un bucle, un Select Case y construcción de cadenas, todo funcionando en conjunto. Esto ya se acerca genuinamente a una lógica de calidad de producción, solo que se ejecuta con datos de ejemplo escritos directamente en el código en lugar de en una hoja de cálculo real.
Tarea
- Copia
CheckStockLevelsen tu libro de trabajo y ejecútalo. Confirma que el mensaje coincide con la captura de pantalla. - Cambia el stock del Wireless Mouse a 25 y vuelve a ejecutar: ahora también debería aparecer como "observar de cerca".
- Agrega un bucle
Do Whiledebajo que simule la venta de 15 unidades de Laptop Stand a la vez hasta que el stock baje a 20 o menos, imprimiendo el total acumulado en la ventana Inmediato después de cada venta. - Desafío: reescribe el bucle
For i = 1 To 5usandoFor Eachsobre un arreglo Variant en su lugar — ¿la lógica sigue funcionando?
2. Cambiar el stock del Mouse Inalámbrico
- Busca la línea que configura los datos del Mouse Inalámbrico:
products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30. - Solo necesitas cambiar el número del medio (
134) por25— deja el nombre del producto y el nivel de reposición tal como están. - Antes de ejecutarlo, analiza manualmente qué
Caselo capturará: ¿es 25 ≤ 30 (el nivel de reposición)? Compáralo específicamente con la líneaCase Is <= reorderLevels(i), no con la segunda.
3. Simulación de ventas por lotes con Do While
- Se necesita una variable para almacenar el stock actual del Laptop Stand — iníciala con el mismo valor que ya está en
stockLevels(1)(58), así no escribes un número nuevo que podría desincronizarse con el resto de la macro. - La condición del bucle debe comprobar si el stock sigue por encima de 20 — en el momento en que verifique y encuentre el stock en 20 o menos, debe detenerse.
- Resta 15 en cada iteración y muestra el nuevo valor justo después de restar — no antes — para que cada número impreso refleje una venta completada.
- Haz el seguimiento en papel primero: 58 → 43 → 28 → 13. Observa que el último valor cae por debajo de 20 en lugar de llegar exactamente a 20 — ese es el mismo comportamiento de "exceso" del
Do Whileque el diagrama de bucles del capítulo explicó antes, no es un error.
Punto 2 — dentro de CheckStockLevels, solo cambia un número:
products(2) = "Wireless Mouse": stockLevels(2) = 25: reorderLevels(2) = 30
Ejecuta el Sub nuevamente.
Punto 3 — agrega esto debajo del código existente, aún dentro de CheckStockLevels (antes de End Sub):
' --- Simulate selling Laptop Stand in batches of 15 ---
Dim laptopStandStock As Integer
laptopStandStock = stockLevels(1)
Do While laptopStandStock > 20
laptopStandStock = laptopStandStock - 15
Debug.Print laptopStandStock
Loop
¡Gracias por tus comentarios!