Para trabalhar efetivamente no VBA, você deve entender os Loops.
Os loops permitem repetir um bloco de código um determinado número de vezes ou repetir um bloco de código em cada objeto em um conjunto de objetos.
Primeiro, mostraremos alguns exemplos para mostrar do que os loops são capazes. Em seguida, ensinaremos tudo sobre loops.
Exemplos rápidos de VBA Loop
Para Cada Loops
For Each Loops percorre cada objeto em uma coleção, como cada planilha na pasta de trabalho ou cada célula em um intervalo.
Percorrer todas as planilhas na pasta de trabalho
Este código percorrerá todas as planilhas na pasta de trabalho, exibindo cada planilha:
12345678 | Sub LoopThroughSheets ()Dim ws como planilhaPara cada ws nas planilhasws.Visible = TruePróximoEnd Sub |
Loop por todas as células no intervalo
Este código fará um loop por um intervalo de células, testando se o valor da célula é negativo, positivo ou zero:
1234567891011121314 | Sub If_Loop ()Dim Cell como RangePara cada célula no intervalo ("A2: A6")Se Cell.Value> 0 ThenCell.Offset (0, 1) .Value = "Positivo"ElseIf Cell.Value <0 ThenCell.Offset (0, 1) .Value = "Negativo"OutroCell.Offset (0, 1) .Value = "Zero"Fim sePróxima CélulaEnd Sub |
Para os próximos loops
Outro tipo de loop “For” é o loop For Next. O For Next Loop permite que você faça um loop por inteiros.
Este código fará um loop pelos inteiros de 1 a 10, exibindo cada um com uma caixa de mensagem:
123456 | Sub ForLoop ()Dim i As IntegerPara i = 1 a 10MsgBox iProximo euEnd Sub |
Loops Do While
Os Loops Do While farão um loop enquanto uma condição for atendida. Esse código também fará um loop pelos inteiros de 1 a 10, exibindo cada um com uma caixa de mensagem.
12345678 | Sub DoWhileLoop ()Dim n As Integern = 1Faça enquanto n <11MsgBox nn = n + 1CicloEnd Sub |
Loops Do Até
Por outro lado, os Loops Do Until farão um loop até que uma condição seja atendida. Este código faz a mesma coisa que os dois exemplos anteriores.
12345678 | Sub DoUntilLoop ()Dim n As Integern = 1Faça até n> = 10MsgBox nn = n + 1CicloEnd Sub |
Discutiremos isso a seguir, mas você precisa ser extremamente cuidadoso ao criar loops Do While ou Do Until para que você não crie um loop sem fim.
VBA Loop Builder
Esta é uma captura de tela do “Loop Builder” de nosso Suplemento VBA Premium: AutoMacro. O Loop Builder permite que você crie loops de forma rápida e fácil para percorrer diferentes objetos ou números. Você pode executar ações em cada objeto e / ou selecionar apenas objetos que atendam a determinados critérios.
O suplemento também contém muitos outros criadores de código, uma extensa biblioteca de código VBA e uma variedade de ferramentas de codificação. É essencial para qualquer desenvolvedor VBA.
Agora vamos cobrir os diferentes tipos de loops em profundidade.
VBA para o próximo loop
For Loop Syntax
O For Next Loop permite repetir um bloco de código um determinado número de vezes. A sintaxe é:
12345 | [Dim Contador como Inteiro]Para contador = início ao fim [valor do passo][Faça alguma coisa]Próximo [contador] |
Onde os itens entre colchetes são opcionais.
- [Dim Counter tão longo] - Declara a variável do contador. Obrigatório se Option Explicit for declarado na parte superior do seu módulo.
- Contador - Uma variável inteira usada para contar
- Começar - O valor inicial (Ex. 1)
- Fim - O valor final (Ex. 10)
- [Step Value] - Permite contar a cada n inteiros em vez de cada 1 inteiro. Você também pode fazer o inverso com um valor negativo (por exemplo, Etapa -1)
- [Faça alguma coisa] - O código que se repetirá
- Próximo [contador] - Declaração de fechamento para o For Next Loop. Você pode incluir o Contador ou não. No entanto, recomendo fortemente incluir o contador, pois torna seu código mais fácil de ler.
Se isso é confuso, não se preocupe. Vamos revisar alguns exemplos:
Conte até 10
Este código contará até 10 usando um For-Next Loop:
12345678 | Sub ForEach_CountTo10 ()Dim n As IntegerPara n = 1 a 10MsgBox nPróximo nEnd Sub |
For Loop Step
Conte até 10 - apenas números pares
Este código contará até 10, contando apenas os números pares:
12345678 | Sub ForEach_CountTo10_Even ()Dim n As IntegerPara n = 2 a 10 Etapa 2MsgBox nPróximo nEnd Sub |
Observe que adicionamos a “Etapa 2”. Isso diz ao For Loop para "avançar" no contador em 2. Também podemos usar um valor de passo negativo para retroceder:
For Loop Step - Inverso
Contagem regressiva de 10
Este código fará uma contagem regressiva a partir de 10:
123456789 | Sub ForEach_Countdown_Inverse ()Dim n As IntegerPara n = 10 a 1 etapa -1MsgBox nPróximo nMsgBox "Lift Off"End Sub |
Excluir linhas se a célula estiver em branco
Tenho usado com mais frequência um loop For de etapa negativa para percorrer intervalos de células, excluindo linhas que atendem a certos critérios. Se você fizer um loop das linhas superiores para as linhas inferiores, conforme exclui as linhas, você bagunçará seu contador.
Este exemplo excluirá linhas com células em branco (começando da linha inferior):
12345678910 | Sub ForEach_DeleteRows_BlankCells ()Dim n As IntegerPara n = 10 a 1 etapa -1Se Range ("a" & n) .Value = "" ThenRange ("a" & n) .EntireRow.DeleteFim sePróximo nEnd Sub |
Aninhado For Loop
Você pode “aninhar” um For Loop dentro de outro For Loop. Usaremos Loops For aninhados para criar uma tabuada:
1234567891011 | Sub Nested_ForEach_MultiplicationTable ()Dim row As Integer, col As IntegerPara linha = 1 a 9Para col = 1 a 9Células (linha + 1, col + 1) .Valor = linha * colPróxima colPróxima linhaEnd Sub |
Sair para
A instrução Exit For permite que você saia de um loop For Next imediatamente.
Você normalmente usaria Exit For junto com uma instrução If, saindo do For Next Loop se uma determinada condição fosse atendida.
Por exemplo, você pode usar um For Loop para localizar uma célula. Depois que essa célula for encontrada, você pode sair do loop para acelerar seu código.
Este código fará um loop pelas linhas 1 a 1000, procurando por "erro" na coluna A. Se for encontrado, o código selecionará a célula, alertará você sobre o erro encontrado e sairá do loop:
12345678910111213 | Sub ExitFor_Loop ()Dim i As IntegerPara i = 1 a 1000Se Range ("A" & i) .Value = "erro" EntãoIntervalo ("A" e i). SelecioneMsgBox "Erro encontrado"Sair paraFim seProximo euEnd Sub |
Importante: No caso de Loops For aninhados, Exit For apenas sai do Loop For atual, nem de todos os Loops ativos.
Continue para
O VBA não tem o comando “Continue” encontrado no Visual Basic. Em vez disso, você precisará usar “Sair”.
VBA para cada loop
O VBA For Each Loop percorrerá todos os objetos em uma coleção:
- Todas as células em um intervalo
- Todas as planilhas em uma pasta de trabalho
- Todas as formas em uma planilha
- Todas as pastas de trabalho abertas
Você também pode usar Nested For Each Loops para:
- Todas as células em um intervalo em todas as planilhas
- Todas as formas em todas as planilhas
- Todas as planilhas em todas as pastas de trabalho abertas
- e assim por diante…
A sintaxe é:
123 | Para cada objeto na coleção[Faça alguma coisa]Próximo [objeto] |
Onde:
- Objeto - Variável que representa um intervalo, planilha, pasta de trabalho, forma, etc. (por exemplo, rng)
- Coleção - Coleção de objetos (ex. Range (“a1: a10”)
- [Faça alguma coisa] - Bloco de código a ser executado em cada objeto
- Próximo [objeto] - Declaração de encerramento. [Object] é opcional, embora fortemente recomendado.
Para cada célula no intervalo
Este código percorrerá cada célula em um intervalo:
123456789 | Sub ForEachCell_inRange ()Dim cell como rangePara cada célula no intervalo ("a1: a10")cell.Value = cell.Offset (0,1) .ValuePróxima célulaEnd Sub |
Para cada planilha na pasta de trabalho
Este código percorrerá todas as planilhas em uma pasta de trabalho, desprotegendo cada planilha:
123456789 | Sub ForEachSheet_inWorkbook ()Dim ws como planilhaPara cada ws nas planilhasws.Desproteger "senha"Próximo wsEnd Sub |
Para cada pasta de trabalho aberta
Este código salvará e fechará todas as pastas de trabalho abertas:
123456789 | Sub ForEachWB_inWorkbooks ()Dim wb como pasta de trabalhoPara cada wb nas pastas de trabalhowb.Close SaveChanges: = TruePróximo wbEnd Sub |
Para cada forma na planilha
Este código excluirá todas as formas da planilha ativa.
123456789 | Sub ForEachShape ()Dim shp como formaPara cada shp em ActiveSheet.Shapesshp.DeletePróximo shpEnd Sub |
Para cada forma em cada planilha na pasta de trabalho
Você também pode aninhar For Each Loops. Aqui, percorreremos todas as formas em todas as planilhas na pasta de trabalho ativa:
1234567891011 | Sub ForEachShape_inAllWorksheets ()Dim shp As Shape, ws As WorksheetPara cada ws nas planilhasPara cada shp em ws.Shapesshp.DeletePróximo shpPróximo wsEnd Sub |
Para cada um - IF Loop
Como mencionamos antes, você pode usar uma instrução If dentro de um loop, realizando ações apenas se determinados critérios forem atendidos.
Este código ocultará todas as linhas em branco em um intervalo:
12345678910 | Sub ForEachCell_inRange ()Dim cell como rangePara cada célula no intervalo ("a1: a10")Se cell.Value = "" Então _cell.EntireRow.Hidden = TruePróxima célulaEnd Sub |
VBA Do While Loop
O VBA Do While e Do Until (consulte a próxima seção) são muito semelhantes. Eles irão repetir um loop enquanto (ou até) uma condição ser atendida.
O Do While Loop repetirá um loop enquanto uma condição for atendida.
Esta é a sintaxe Do While:
123 | Condição Do While[Faça alguma coisa]Ciclo |
Onde:
- Doença - A condição para testar
- [Faça alguma coisa] - O bloco de código para repetir
Você também pode configurar um loop Do While com a Condição no final do loop:
123 | Fazer[Faça alguma coisa]Loop While Condition |
Faremos uma demonstração de cada um e mostraremos como eles diferem:
Fazer enquanto
Aqui está o exemplo de loop Do While que demonstramos anteriormente:
12345678 | Sub DoWhileLoop ()Dim n As Integern = 1Faça enquanto n <11MsgBox nn = n + 1CicloEnd Sub |
Loop While
Agora vamos executar o mesmo procedimento, exceto que moveremos a condição para o final do loop:
12345678 | Sub DoLoopWhile ()Dim n As Integern = 1FazerMsgBox nn = n + 1Loop enquanto n <11End Sub |
VBA Do Until Loop
Os Loops Do Until irão repetir um loop até que uma determinada condição seja atendida. A sintaxe é essencialmente a mesma dos loops Do While:
123 | Até a condição[Faça alguma coisa]Ciclo |
e da mesma forma a condição pode ir no início ou no final do loop:
123 | Fazer[Faça alguma coisa]Loop até a condição |
Fazer até
Este loop do until contará até 10, como nossos exemplos anteriores
12345678 | Sub DoUntilLoop ()Dim n As Integern = 1Faça até n> 10MsgBox nn = n + 1CicloEnd Sub |
Loop até
Este loop Loop Até contará até 10:
12345678 | Sub DoLoopUntil ()Dim n As Integern = 1FazerMsgBox nn = n + 1Loop até n> 10End Sub |
Sair do Loop
Semelhante a usar Exit For para sair de um For Loop, você usa o comando Exit Do para sair de um Do Loop imediatamente
1 | Sair Do |
Aqui está um exemplo de Exit Do:
123456789101112131415 | Sub ExitDo_Loop ()Dim i As Integeri = 1Faça até i> 1000Se Range ("A" & i) .Value = "erro" EntãoIntervalo ("A" e i). SelecioneMsgBox "Erro encontrado"Sair DoFim sei = i + 1CicloEnd Sub |
End or Break Loop
Como mencionamos acima, você pode usar Exit For ou Exit Do para sair dos loops:
1 | Sair para |
1 | Sair Do |
No entanto, esses comandos devem ser adicionados ao seu código antes de executar o loop.
Se você está tentando "quebrar" um loop que está em execução, você pode tentar pressionar ESC ou CTRL + Pausa no teclado. No entanto, isso pode não funcionar. Se não funcionar, você precisará aguardar o fim do loop ou, no caso de um loop infinito, usar CTRL + ALT + Excluir para forçar o fechamento do Excel.
É por isso que tento evitar os loops Do, é mais fácil criar acidentalmente um loop infinito forçando você a reiniciar o Excel, potencialmente perdendo seu trabalho.
Mais exemplos de loop
Loop Through Rows
Isso percorrerá todas as linhas de uma coluna:
123456789 | Public Sub LoopThroughRows ()Dim cell como rangePara cada célula no intervalo ("A: A")Ff cell.value "" então MsgBox cell.address & ":" & cell.valuePróxima célulaEnd Sub |
Loop Through Columns
Isso fará um loop por todas as colunas em uma linha:
123456789 | Public Sub LoopThroughColumns ()Dim cell como rangePara cada célula no intervalo ("1: 1")If cell.Value "" Then MsgBox cell.Address & ":" & cell.ValuePróxima célulaEnd Sub |
Percorrer os arquivos em uma pasta
Este código percorrerá todos os arquivos em uma pasta, criando uma lista:
12345678910111213141516171819 | Sub LoopThroughFiles ()Dim oFSO As ObjectDim oFolder As ObjectDim oFile As ObjectDim i As IntegerDefina oFSO = CreateObject ("Scripting.FileSystemObject")Defina oFolder = oFSO.GetFolder ("C: \ Demo)i = 2Para cada oFile em oFolder.FilesRange ("A" & i) .value = oFile.Namei = i + 1Próximo oFileEnd Sub |
Loop Through Array
Este código fará um loop pela matriz ‘arrList’:
123 | Para i = LBound (arrList) To UBound (arrList)MsgBox arrList (i)Proximo eu |
A função LBound obtém o “limite inferior” do array e o UBound obtém o “limite superior”.
Loops no Access VBA
A maioria dos exemplos acima também funcionará no Access VBA. No entanto, no Access, percorremos o objeto Recordset em vez do objeto Range.
123456789101112131415161718 | Sub LoopThroughRecords ()On Error Resume NextDim dbs como banco de dadosDim rst As RecordsetDefinir dbs = CurrentDbDefina rst = dbs.OpenRecordset ("tblClients", dbOpenDynaset)Com o primeiro.MoveLast.MoveFirstFaça até .EOF = VerdadeiroMsgBox (rst.Fields ("ClientName")).MoveNextCicloTerminar comprimeiro.FecharDefinir rst = NadaDefinir dbs = NothingEnd Sub |