Laços
Deslize para mostrar o menu
Até agora, cada técnica funcionou com um valor por vez. Os loops permitem aplicar a mesma lógica a vários valores em sequência — cinco produtos, quinhentos pedidos, ou quantas linhas uma tabela tiver — sem precisar copiar e colar o mesmo bloco de código repetidas vezes.
For...Next
Repete um bloco de código um número fixo e conhecido de vezes:
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
No primeiro loop, i começa em 1, o código dentro executa uma vez com esse valor, depois i aumenta automaticamente em 1 e todo o bloco executa novamente — repetindo até que i ultrapasse 5, momento em que o loop simplesmente para e a execução continua após o Next. Step altera o incremento: Step -1 conta para baixo em vez do padrão de subir de um em um, e Step 2 contaria de dois em dois. A variável do loop i não é uma sintaxe especial — é apenas uma variável Long comum que o VBA atualiza a cada passagem.
For Each
Percorre diretamente cada item em uma coleção, sem precisar saber quantos itens existem ou gerenciar um contador manualmente:
Dim cell As Range
For Each cell In ThisWorkbook.Worksheets("Products").Range("B2:B6")
Debug.Print cell.Value
Next cell
Aqui, cell assume cada célula individual no intervalo B2:B6 em sequência, e você lê o conteúdo dela com .Value. Compare com For...Next: com For...Next você conta números e usa esse número para buscar algo; com For Each você percorre diretamente os próprios itens, o que se torna mais natural ao trabalhar com intervalos de planilha.
Do While
Repete enquanto uma condição permanecer True — o loop não sabe de antemão quantas vezes irá rodar, o que é diferente do 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
O VBA verifica stock > 0 antes de cada passagem pelo loop, inclusive na primeira. Acompanhe manualmente: 134 → 104 → 74 → 44 → 14, e então a condição é verificada novamente — 14 ainda é maior que 0, então o loop roda mais uma vez, chegando a -16. Só então stock > 0 retorna False, e o loop para com stock em -16, não exatamente em 0 ou 14. Vale a pena acompanhar cuidadosamente na primeira vez, pois é uma fonte comum de erros de um a mais ou a menos: um loop Do While continua rodando enquanto a condição for verdadeira no momento da verificação, mesmo que a ação dentro do loop ultrapasse o limite esperado.
Do Until
Existe também o Do Until, que é o oposto do Do While — repete enquanto uma condição for False e para assim que a condição se tornar True, ao invés do contrário. Qual deles soa mais natural depende de como você expressaria a regra de negócio: "continuar enquanto houver estoque" sugere Do While; "continuar até acabar o estoque" sugere Do Until — ambos podem produzir o mesmo comportamento, apenas expressos de formas opostas.
Exit Statements
Permitem sair de um loop antes do término natural da condição:
For i = 1 To 100
If i = 10 Then Exit For ' stop the loop immediately
Debug.Print i
Next i
Este loop está configurado para contar até 100, mas no momento em que i chega a 10, Exit For interrompe imediatamente — nada após o Exit For é executado, e a execução salta direto para a linha após o Next i. Este é o padrão usado para buscar em uma lista e parar assim que encontrar o que procura, em vez de continuar verificando todos os itens restantes desnecessariamente.
Juntando Tudo
Todas as técnicas deste capítulo — variáveis, operadores, funções, lógica condicional e agora loops — se combinam no procedimento que este capítulo vem construindo:
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 e as duas linhas semelhantes abaixo declaram arrays — cada uma é uma linha numerada de cinco caixas em vez de uma única caixa, então products(1) é o nome do primeiro produto, products(2) o segundo, e assim por diante;
- As cinco linhas usando dois-pontos (
:) entre comandos agrupam várias atribuições em uma linha apenas para facilitar a leitura aqui —products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20é exatamente equivalente a escrever essas atribuições em três linhas separadas; For i = 1 To 5 ... Next ipercorre todos os cinco produtos um de cada vez, usando i tanto como contador do loop quanto como índice de cada array;Select Case stockLevels(i)executa novamente a mesma decisão baseada em faixa da seção 2.4, mas agora com dados reais de array em vez de um único número fixo;- Case Is <= reorderLevels(i) captura qualquer produto cujo estoque caiu até ou abaixo do seu próprio nível de reposição — repare que reorderLevels(i) é uma variável, não um número fixo, então cada produto é avaliado pelo seu próprio limite em vez de um limite único para todos;
alertMessage = alertMessage & ... & vbNewLineconstrói uma string crescente linha a linha —vbNewLineé uma constante interna que insere uma quebra de linha, então cada produto sinalizado aparece em uma linha separada na mensagem final;- O teste final
If alertMessage = "" Thené o que decide qual das duas variantes doMsgBoxo usuário verá — uma string vazia significa que o loop não encontrou nada que merecesse destaque.
Execute isto e você verá o Monitor Arm sinalizado como "observar de perto" (18 unidades contra um nível de reposição de 10) — acompanhe o loop manualmente para i = 4 se quiser confirmar exatamente por que é o único capturado pelo segundo Case e não pelo primeiro. Este procedimento utiliza arrays, um loop, um Select Case e construção de strings, todos trabalhando juntos. Isso já está genuinamente próximo de uma lógica de qualidade de produção, apenas rodando contra dados de exemplo digitados diretamente no código em vez de uma planilha real.
Tarefa
- Copie
CheckStockLevelspara sua pasta de trabalho e execute. Confirme se a mensagem corresponde à captura de tela. - Altere o estoque do Wireless Mouse para 25 e execute novamente — agora ele também deve aparecer como "observar de perto".
- Adicione um loop
Do Whileabaixo que simule a venda de 15 unidades de Laptop Stand por vez até que o estoque caia para 20 ou menos, imprimindo o total acumulado na Janela Imediata após cada venda. - Desafio: reescreva o loop
For i = 1 To 5usandoFor Eachsobre um array Variant — a lógica ainda funciona?
2. Alterando o estoque do Wireless Mouse
- Localizar a linha que configura os dados do Wireless Mouse:
products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30. - É necessário apenas alterar o número do meio (
134) para25— mantenha o nome do produto e o nível de reposição inalterados. - Antes de executar, calcule manualmente qual
Caseirá capturá-lo: 25 ≤ 30 (o nível de reposição)? Compare especificamente com a linhaCase Is <= reorderLevels(i), não com a segunda.
3. Simulando vendas em lote com Do While
- É preciso uma variável para armazenar o estoque atual do Laptop Stand — inicie com o mesmo valor já presente em
stockLevels(1)(58), assim não será necessário digitar um novo número que possa ficar fora de sincronia com o restante da macro. - A condição do loop deve verificar se o estoque ainda está acima de 20 — no momento em que verificar e encontrar o estoque em 20 ou menos, deve parar.
- Subtraia 15 a cada passagem e imprima o novo valor logo após subtrair — não antes — para que cada número impresso reflita uma venda concluída.
- Faça o rastreamento no papel primeiro: 58 → 43 → 28 → 13. Observe que o último valor fica abaixo de 20 em vez de chegar exatamente a 20 — esse é o mesmo comportamento de "ultrapassagem" do
Do Whilemostrado anteriormente no diagrama de loops do capítulo, não é um erro.
Ponto 2 — dentro de CheckStockLevels, basta alterar um número:
products(2) = "Wireless Mouse": stockLevels(2) = 25: reorderLevels(2) = 30
Execute o Sub novamente.
Ponto 3 — adicione este trecho abaixo do código existente, ainda dentro de CheckStockLevels (antes do 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
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo