Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Macro de apagar linhas com zero, não apaga duas ou mais linhas seguidas.

Boa tarde, galera! Seguinte, tenho uma base de dados que muitas vezes vem com linhas cheias de zero. Escrevi um código para excluir essas linhas, mas quando existem duas ou mais linhas seguidas com zero, o código só exclui a primeira linha com zeros e pula as demais. Aí para funcionar certinho, teria que rodar a macro várias vezes.

Como posso corrigir essa falha? Muito obrigada desde já!

Segue o código:

Option Explicit
Sub tirarZeros()

Dim range1, cell as Range
Sheets("Sheet1").Activate

Set range1 = Range("A1:A200")

For Each cell In range1
    If analisarLinha(cell) Then 
    cell.Offset(0,6).Rows.Select
    Selection.EntireRow.Delete
    End If
Next

End Sub
________________________________________________

Function analisarLinha(ByVal cell As Range) As Boolean

If cell.Offset(0,6).Value = 0 and cell.Offset(0,7).Value = 0 Then
analisarLinha = True
End If 

End Function
4 respostas

Olá Nathalia, tudo bem? Espero que sim!

O que está acontecendo no código é que você está deletando células que estão passando pelo For, e ao deletá-las, o código não irá detectar o zero logo abaixo de um zero que foi deletado. Vamos utilizar um exemplo para que fique mais claro o que está acontecendo:

Suponha que tenha uma linha de zeros nas linhas 10 e 11. O código irá detectar que existe um 0 na linha 10 através da função analisarLinha. A linha inteira será selecionada e deletada. Portanto, todas as linhas abaixo da linha 10 irão subir para preencher o espaço vazio que a linha 10 deixou. Portanto, a linha 11 se tornará a 10, a linha 12 se tornará a 11 e assim por diante. Porém, o For não irá executar mais a linha 10 e partirá para a linha 11 que não mais tem um 0, uma vez que ele subiu para a linha 10.

Dessa forma dois zeros subsequentes não serão eliminados através do código que criou, já que estamos tirando elementos do próprio iterador do For.

Encontrei uma solução para o problema sem que seja necessário executar a macro mais de uma vez. Talvez não seja a melhor forma de solucionar o problema, porém funciona. Criei uma função responsável para contar a quantidade de zeros antes que sejam deletados e utilizei um For para executar um bloco de código que se repita a quantidade de zeros que existem.

O For interno, irá percorrer o intervalo já utilizado por você até detectar um zero, deletando a linha que possui esse zero. Utilizei o comando Exit For para sair do For caso esse 0 seja encontrado e deletado. Dessa forma o intervalo será percorrido desde o início novamente, eliminando o problema que havia em não verificar a linha subsequente.

O código que utilizei foi o seguinte:

Sub tirarZeros()

    Dim range1, cell As Range
    Sheets("Sheet1").Activate

    Set range1 = Range("A1:A200")

    Contador = contaZeros(range1)

    For i = 0 To Contador

        For Each cell In range1
            If analisarLinha(cell) Then
            cell.Offset(0, 6).Rows.Select
            Selection.EntireRow.Delete
            Exit For
            End If
        Next
    Next

End Sub

Function analisarLinha(ByVal cell As Range) As Boolean

    If cell.Offset(0, 6).Value = 0 And cell.Offset(0, 7).Value = 0 Then
    analisarLinha = True
    End If

End Function

Function contaZeros(ByVal cells As Range) As Integer

    Cont = 0
    For Each cell In cells
        If cell.Offset(0, 6).Value = 0 And cell.Offset(0, 7).Value = 0 Then
        Cont = Cont + 1
        End If
    Next
    contaZeros = Cont

End Function

Espero que tenha tirado sua dúvida.

Estou à disposição. Bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!
solução!

Boa noite, João! Muito obrigada pela explicação maravilhosa! Finalmente entendi o que estava acontecendo, jamais me ligaria que a linha estava subindo hahaha Agradeço demais a solução apresentada, funcionou perfeitamente.

Só tenho mais uma duvida rapidinha: das vezes que eu utilizei o For, eu sempre via o i de maneira explicita. Tipo assim "Cells(i, 0).value", ele sempre aparecia em algum canto. Nesse caso, digamos que o contador tenha encontrado 13 zeros, então i = 0 até 13, mas onde esse 13 é "lido"?

O for each vai ler cada célula no range1, e o i = até 13 é responsável por determinar quantas linhas serão deletadas ao atender a função analisarLinha, é isso?

Mais uma vez, muito obrigada! Abraços!

Olá Nathalia, tudo bem? Espero que sim!

Obrigado pelo feedback Nathalia, isso ajuda a melhorar cada vez mais as minhas explicações.

O contador i nesse caso não vai ser utilizado dentro do bloco do for, ele é apenas um valor numérico para o código repetir uma determinada quantidade de vezes. Se for encontrado 13 zeros, então o for será executado 13 vezes. A variável em si não é utilizada dentro do bloco for, mas o contador aumenta de 1 em 1 a cada execução, não necessariamente sendo utilizado em outro local.

Caso fosse um número fixo de zeros e você soubesse, poderia substituir pelo próprio valor (Mudando o código para For i = 0 To 13). Porém como esse número é variável, foi utilizado uma função para gravar em uma variável e utilizá-la no For.

Espero que tenha tirado sua dúvida.

Estou à disposição. Bons estudos!

Boa noite, João! Tudo bem sim e com você?

Mais uma vez, agradeço de coração a explicação! Entendi! Nunca tinha pensado assim, mas faz sentido! Vou aproveitar a empolgação e fazer o curso de VBA daqui da plataforma, o curso que eu fiz já tem muito tempo ahahah

Abraços e muito obrigada!