Notifications
Clear all

Verificar se uma célula consta em outro intervalo nomeado

10 Posts
2 Usuários
0 Reactions
1,403 Visualizações
(@jonascruz)
Posts: 64
Trusted Member
Topic starter
 

Boa tarde.
Sei que isso é fácil de resolver, mas empaquei nisso.
Por favor, conseguem me ajudar com essa macro?
Tenho uma coluna Classif. com alguns textos. Eu preciso verificar se esse texto consta na tabela AMX (intervalo nomeado). Se não existir, deleta a linha.
Pensei em criar uma variável Booleana para armazenar o true ou false da fórmula, mas não estou conseguindo sair disso.

For i = 3 To ultimalinha
       Cells(i, 1).FormulaR1C1 = "=ISTEXT(VLOOKUP(RC,AMX,1,0))" 
            Rows(i).Delete   'Deleta a Linha i
        End If
    Next i

Classif.
9.1
8.2
8.3 **
9.1
5.2
12.1 **
9.4
8.1 **
8.6
10.1

AMX
12.1
12.2
8.1
8.3

Se a informação ou resposta foi útil, clique na mãozinha próxima ao botão "CITAR no canto superior direito.

Se o seu problema foi resolvido, clique no V verde para aceitar como resposta.

 
Postado : 06/05/2016 2:22 pm
(@osvaldomp)
Posts: 858
Prominent Member
 

Experimente:

Sub DeletaLinha()
 Dim LR As Long, k As Long
 LR = Cells(1, 1).End(4).Row
 For k = LR To 2 Step -1
  If Application.CountIf(Range("AMX"), Cells(k, 1)) = 0 Then Rows(k).Delete
 Next k
End Sub

Osvaldo

 
Postado : 06/05/2016 6:35 pm
(@jonascruz)
Posts: 64
Trusted Member
Topic starter
 

Olá, Osvaldomp.
Muito obrigado pelo retorno.

Tentei adaptar assim:

No inicio do meu codigo eu pego a ultima linha da planilha "base" (coluna Classif)

ultima = Sheets("Base").Cells(Rows.Count, "B").End(xlUp).Row 

Uso um For nessa aba "base" até a ultima linha e vejo se no intervalo nomeado "DadosAMX" da aba "AMX" tem algum texto igual.

For i = 3 To ultima
  If Application.CountIf(Range("DadosAMX"), Cells(i, 45)) = 0 Then
     Rows(i).Delete
  End If
Next i

E encontrando dados iguais (Cells (i,45) da aba "Base" x Intervalo nomeado "DadosAMX" da aba AMX), a linha da planilha "base" é excluida.

Esse codigo me gerou um loop infinito. :cry:

Se a informação ou resposta foi útil, clique na mãozinha próxima ao botão "CITAR no canto superior direito.

Se o seu problema foi resolvido, clique no V verde para aceitar como resposta.

 
Postado : 09/05/2016 12:11 pm
(@osvaldomp)
Posts: 858
Prominent Member
 

Olá, Jonas.
Além de algumas divergências entre o seu primeiro e o seu último post, o loop que visa deletar/excluir linhas só é eficiente se for de baixo para cima, como está no exemplo que eu postei. De cima para baixo como você fez, havendo duas células consecutivas que atendem ao critério, a segunda não será detectada, e consequentemente a linha não será deletada/excluída.

Quanto ao loop infinito sugiro que você disponibilize uma amostra do seu arquivo com o código em uso que está provocando o erro.

Osvaldo

 
Postado : 09/05/2016 2:12 pm
(@jonascruz)
Posts: 64
Trusted Member
Topic starter
 

Segue a planilha em anexo.

Vou tentar seguir da forma como vc sugeriu

Obrigado.

Se a informação ou resposta foi útil, clique na mãozinha próxima ao botão "CITAR no canto superior direito.

Se o seu problema foi resolvido, clique no V verde para aceitar como resposta.

 
Postado : 09/05/2016 3:03 pm
(@osvaldomp)
Posts: 858
Prominent Member
 

Abaixo o código para deletar/excluir linhas. As referências estão de acordo com a sua planilha "Base".
Se atender a sua necessidade é só encaixá-lo no seu código já existente.
Neste código eu utilizei o 'Find' em substituição ao 'CountIf' visto que este segundo considera o conteúdo 9.1 como sendo igual a 9.10, que está no intervalo nomeado, em consequência a linha com 9.1 não é deletada. Entre o 'CountIf' e o 'Find' utilize o que melhor te atende.

Sub DeletaLinhas()
 Dim ultima As Long, c As Range, i As Long
  ultima = ActiveSheet.Cells(Rows.Count, "B").End(xlUp).Row
   For i = ultima To 4 Step -1
    Set c = Range("DadosAMX").Find(Cells(i, 45), lookat:=xlWhole)
     If c Is Nothing Then Rows(i).Delete
   Next i
End Sub

dica - no seu código vi este loop

For i = 3 To ultima
        Cells(i, 1).Value = i - 2
    Next i

experimente substituir por esta linha (é mais rápida na execução)

Range("A3").Value = 1: Range("A3").AutoFill Range("A3:A" & ultima), xlFillSeries

Osvaldo

 
Postado : 09/05/2016 7:10 pm
(@jonascruz)
Posts: 64
Trusted Member
Topic starter
 

Vou testar aqui para ver como ficou.

Mas vc deve ter visto no meu código que eu coloco quase tudo na mesma sub.
Vc considera uma boa prática separar em subs menores e chamar cada sub sempre que necessário?

Por exemplo, chamar a sub Deletar linhas dentro do meu código.

Se a informação ou resposta foi útil, clique na mãozinha próxima ao botão "CITAR no canto superior direito.

Se o seu problema foi resolvido, clique no V verde para aceitar como resposta.

 
Postado : 10/05/2016 7:23 am
(@jonascruz)
Posts: 64
Trusted Member
Topic starter
 

Testei aqui e realmente ficou muito lento.

Tem algum email que eu possa enviar a planilha real (16,5MB) pra vc olhar?

A planilha não pode ser compartilhada no forum, pois ela tem dados confidenciais, mas nada impede que seja postada a parte da solução.

Se a informação ou resposta foi útil, clique na mãozinha próxima ao botão "CITAR no canto superior direito.

Se o seu problema foi resolvido, clique no V verde para aceitar como resposta.

 
Postado : 10/05/2016 9:03 am
(@jonascruz)
Posts: 64
Trusted Member
Topic starter
 

A planilha original tem 100.000 linhas.

Estou tentando ver se tem algo errado, mas com essas poucas linhas que deixei de "amostra" funciona bem, mas quando uso a tabela original, fica rodando por muito tempo.
Será que dá para deixar mais eficiente? Ainda tenho alguns procv s pra adicionar :(

Se a informação ou resposta foi útil, clique na mãozinha próxima ao botão "CITAR no canto superior direito.

Se o seu problema foi resolvido, clique no V verde para aceitar como resposta.

 
Postado : 11/05/2016 10:36 am
(@jonascruz)
Posts: 64
Trusted Member
Topic starter
 

Abaixo o código para deletar/excluir linhas. As referências estão de acordo com a sua planilha "Base".
Se atender a sua necessidade é só encaixá-lo no seu código já existente.
Neste código eu utilizei o 'Find' em substituição ao 'CountIf' visto que este segundo considera o conteúdo 9.1 como sendo igual a 9.10, que está no intervalo nomeado, em consequência a linha com 9.1 não é deletada. Entre o 'CountIf' e o 'Find' utilize o que melhor te atende.

Sub DeletaLinhas()
 Dim ultima As Long, c As Range, i As Long
  ultima = ActiveSheet.Cells(Rows.Count, "B").End(xlUp).Row
   For i = ultima To 4 Step -1
    Set c = Range("DadosAMX").Find(Cells(i, 45), lookat:=xlWhole)
     If c Is Nothing Then Rows(i).Delete
   Next i
End Sub

dica - no seu código vi este loop

For i = 3 To ultima
        Cells(i, 1).Value = i - 2
    Next i

experimente substituir por esta linha (é mais rápida na execução)

Range("A3").Value = 1: Range("A3").AutoFill Range("A3:A" & ultima), xlFillSeries

Sua solução foi fantástica, e adaptei colorindo as células da primeira coluna ao invés de excluir. Ficou muito mais rápido.
Ainda tenho que incluir outros critérios e essa é a melhor opção para o meu caso.

Osvaldomp, muitíssimo obrigado por sua ajuda.

For i = ultima To 4 Step -1 'Rotina colorir linhas que constam no intervalo AMX
    Set intervalo = Range("DadosAMX").Find(Cells(i, 45), lookat:=xlWhole)
     If Not intervalo Is Nothing Then Cells(i, 1).Interior.ColorIndex = 36
   Next i

Se a informação ou resposta foi útil, clique na mãozinha próxima ao botão "CITAR no canto superior direito.

Se o seu problema foi resolvido, clique no V verde para aceitar como resposta.

 
Postado : 13/05/2016 9:03 am