Função IF para exec...
 
Notifications
Clear all

Função IF para executar parte da Macro

12 Posts
3 Usuários
0 Reactions
3,718 Visualizações
(@brunomendes)
Posts: 6
Active Member
Topic starter
 

Quem puder ajudar, fico muito agradecido!

Como pular parte da macro se uma condição for falsa. Por exemplo: preciso filtrar o nome de uma pessoa, copiar o resultado do filtro, abrir uma nova pasta de trabalho e salvar essa nova pasta num determinado diretório, porém se o resultado do filtro for vazio, não quero que salve a pasta de trabalho, ouo seja, sai sem salvar e passe para o próximo filtro: filtrar fulano A, se não localizar o fulano A, pular para próximo filtro, ou seja, fulano B, e assim por diante. Pensei numa condição se A2 na planilha nova estiver vazio então ... mas não sei como faz. Segue macro:

Sub salvar()
'
' salvar Macro

'Filtra pela coluna do nome da pessoa
'seleciona tudo
'copia
'cria uma nova pasta de trabalho
'cola
'salva no diretório c:dadosnomedapessoa

ActiveSheet.Range("$A$1:$AH$9656").AutoFilter Field:=3, Criteria1:= _
"FULANO A"
Cells.Select
Selection.Copy
Workbooks.Add
Cells.Select
ActiveSheet.Paste
Application.CutCopyMode = False
ActiveWorkbook.SaveAs Filename:="C:DADOSfulanoa.xlsx", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
ActiveWindow.Close
Range("A1").Select

'próximo

ActiveSheet.Range("$A$1:$AH$9656").AutoFilter Field:=3, Criteria1:= _
"FULANO B"
Cells.Select
Selection.Copy
Workbooks.Add
Cells.Select
ActiveSheet.Paste
Application.CutCopyMode = False
ActiveWorkbook.SaveAs Filename:="C:DADOSfulanob.xlsx", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
ActiveWindow.Close
Range("A1").Select

'próximo

ActiveSheet.Range("$A$1:$AH$9656").AutoFilter Field:=3, Criteria1:= _
"FULANO C"
Cells.Select
Selection.Copy
Workbooks.Add
Cells.Select
ActiveSheet.Paste
Application.CutCopyMode = False
ActiveWorkbook.SaveAs Filename:="C:DADOSfulanoc.xlsx", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
ActiveWindow.Close

End Sub

 
Postado : 13/11/2012 6:50 pm
(@hronconi)
Posts: 314
Reputable Member
 

Pode usar a instrução GOTO

Exemplo

codigo normal....
if condição = true then goto outrainstrucao
continua o código
else goto fim
:outrainstrucao
Vai fazer o que quer se condicao for igual a true

:fim
 
Postado : 13/11/2012 7:07 pm
(@hronconi)
Posts: 314
Reputable Member
 

só corrigindo... os : são depois e não antes do rótulo.

Public Sub TesteGoto()
MsgBox "Inicio da função"
GoTo Rotulo2
Rotulo1:
MsgBox "Executando Rotulo1"
GoTo Saida
Rotulo2:
MsgBox "Executando Rotulo2"
GoTo Rotulo1
Saida:
MsgBox "Fim da função"
End Sub

 
Postado : 13/11/2012 7:22 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

bruno, uma dica nesta sua rotina para podermos dar uma enxugada no código seria trocar estas instruções :

Cells.Select
Selection.Copy
Workbooks.Add
Cells.Select
ActiveSheet.Paste
Application.CutCopyMode = False
ActiveWorkbook.SaveAs Filename:="C:DADOSfulanoa.xlsx", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False

Por estas :
ActiveSheet.Copy

ActiveWorkbook.SaveAs Filename:="C:DADOSfulanoa.xls", _
FileFormat:=xlNormal, CreateBackup:=False

Adaptei a mesma conforme a versão excel 2003, pois estou sem o 2007 no momento, mas é só adaptar para a sua versão, explicando melhor as instruções :
Cells.Select - Seleciona TODAS as celulas
Selection.Copy - Depois copiamos as Celula Selecionadas
Workbooks.Add - Criamos um Novo Workbook
Cells.Select - Selecionamos TODAS as celulas deste novo workbook
ActiveSheet.Paste - Colamos as celulas copiadas na seleção anterior
Application.CutCopyMode = False - desabilitamos o Foco do Copy
ActiveWorkbook.SaveAs Filename:="C:DADOSfulanoa.xlsx", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
- Salvamos o Novo Workbook no caminho e nome definido.

Resumindo, copiamos uma Aba inteira para uma nova Pasta.

Ou seja se é para copiar a aba ativa para uma nova Pasta, as instruções que indiquei faz isto com menos linhas.

faça um teste e veja se melhora, com instruções a menos percorremos a macro com menos linhas e consequentemente ganhamos na performance.

[]s

 
Postado : 13/11/2012 8:03 pm
(@brunomendes)
Posts: 6
Active Member
Topic starter
 

Mauro Coutinho, vou fazer o teste com sua dica, seria ótimo se a Macro for executado mais rápido, como está ela já roda muito rápido. Ficou dessa forma porque usei o recurso de gravar macro excel 2007, não criei a escrita no VBA.

Só para entender melhor o objetivo da macro: Tenho mais ou menos 20 nomes para filtro na coluna C, que na macro será filtrado um por um, copiar toda a planilha, que após o filtro terá somente os dados do nome filtrado, copia, cria uma pasta de trabalho nova, cola e salva num determinado diretório com o nome da pessoa filtrada. Fiz isso usando Gravar Macro no excel 2007. Mas surgiu um problema, nem sempre terá as 20 pessoas no relatório onde será rodado a Macro, com isso irá salvar uma pasta de trabalho somente com dados de cabeçalho das colunas, porque o nome filtrado não estava presente no arquivo, o que não quero que faça. Se isso ocorrer quero que saia da pasta sem salvar e passe para a próxima etapa da macro, para o próximo filtro e assim por diante. O que não quero é gravar uma nova pasta de trabalho vazia, sem informação.

Tem alguma dica? Pensei numa condição se A2 da plan1 da nova pasta de trabalho for igual a vazio, então ActiveWindow.Close, mas aparece uma mensagem se deseja salvar (sim, não, cancela) e se tiver algum valor, então ActiveWorkbook.SaveAs Filename:="C:DADOSfulanoc.xlsx".
Porém não sei como e nem onde vai as intruções dentro do VBA.

Agadeço pela atenção.

 
Postado : 14/11/2012 5:14 am
(@brunomendes)
Posts: 6
Active Member
Topic starter
 

Hronconi, entendi como funciona a função IF em analogia à função se usada normalmente nas células, porém não sei escrever isso dentro do VBA. Fiz a macro usando o gravador de macro excel 2007.

Pensei na seguinte condição: se A2 da plan1 da nova pasta de trabalho for igual a vazio, então ActiveWindow.Close, mas aparece uma mensagem se deseja salvar (sim, não, cancela) e se tiver algum valor, então ActiveWorkbook.SaveAs Filename:="C:DADOSfulanoc.xlsx".
Porém não sei como e nem onde vai as intruções dentro do VBA.

Alguma dica?

Agradeço desde já.

 
Postado : 14/11/2012 5:28 am
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Bruno, aqui no forum temos vários exemplos de arquivos utilizando Auto Filtro de diversas formas, vou postar alguns links interessantes, mas se utilizar a Busca no Forum por AdvancedFilter, Auto Filtro etc, encontrara varios outros, espero que algum deles ajudem .

Filtrar conteúdo em Novo Arquivo .XLS
viewtopic.php?f=10&t=2522

Separar uma planilha em varias planilhas no mesmo arquivo
viewtopic.php?f=16&t=2472

Macro Copiar valores Iguais
viewtopic.php?f=10&t=2635&hilit=auto+filtro

Filtrar dados em 8 colunas e apresentar dados de apenas 4 col
viewtopic.php?f=10&t=4305&hilit=advancedfilter

Filtro Avançado COLUNAS ESPECÍFICAS
viewtopic.php?f=16&t=3681&hilit=advancedfilter

[]s

 
Postado : 14/11/2012 8:27 am
(@brunomendes)
Posts: 6
Active Member
Topic starter
 

Mauro, boa tarde!

Consultei os links, porém acho que não tem relação com meu problema, pois o filtro eu consegui fazer. Meu problema é em não salvar o novo arquivo quando o resultado do filtro foi vazio, ou seja, quando não houver a pessoa pesquisada pela macro na planilha de dados. A dica que me deu para melhorar a macro foi ótima, fiz a alteração conforme me explicou e ficou super rápido, muito obrigado.

Tentei usar a função IF dentro da macro como abaixo, porém não deu certo, continua salvando os arquivo quando não tem dados no filtro. Na planilha anexo, não tem informação para "NOME C" e "NOME E" presentes coluna C onde é feito o filtro, mas em outras ocasiões pode ser que tenha dados para essas pessoas, por isso quero que conste tudo na macro. Segue anexo planilha com macro:

Obrigado desde já pela atenção.

Sub teste()
'
' teste Macro
'

ActiveSheet.Range("$A$1:$AH$9656").AutoFilter Field:=3, Criteria1:= _
"NOME A"
ActiveSheet.Copy
ActiveWorkbook.SaveAs Filename:="c:Usersc2063910Desktoptestenomea.xlsx", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
If "A2" <> "" Then 'Se A2 for diferente de vazio, então sava o arquivo no diretório
ActiveWindow.Close
Else 'Se A2 for vazio, então sai da nova pasta de trabalho (sem salvar)
Range("A1").Select
End If
ActiveSheet.Range("$A$1:$AH$9656").AutoFilter Field:=3, Criteria1:= _
"NOME B"
ActiveSheet.Copy
ActiveWorkbook.SaveAs Filename:="c:Usersc2063910Desktoptestenomeb.xlsx", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
If "A2" <> "" Then
ActiveWindow.Close
Else
Range("A1").Select
End If
ActiveSheet.Range("$A$1:$AH$9656").AutoFilter Field:=3, Criteria1:= _
"NOME C"
ActiveSheet.Copy
ActiveWorkbook.SaveAs Filename:="c:Usersc2063910Desktoptestenomec.xlsx", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
If "A2" <> "" Then
ActiveWindow.Close
Else
Range("A1").Select
End If
ActiveSheet.Range("$A$1:$AH$9656").AutoFilter Field:=3, Criteria1:= _
"NOME D"
ActiveSheet.Copy
ActiveWorkbook.SaveAs Filename:="c:Usersc2063910Desktoptestenomed.xlsx", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
If "A2" <> "" Then
ActiveWindow.Close
Else
Range("A1").Select
End If
ActiveSheet.Range("$A$1:$AH$9656").AutoFilter Field:=3, Criteria1:= _
"NOME E"
ActiveSheet.Copy
ActiveWorkbook.SaveAs Filename:="c:Usersc2063910Desktoptestenomee.xlsx", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
If "A2" <> "" Then
ActiveWindow.Close
Else
Range("A1").Select
End If
ActiveSheet.Range("$A$1:$AH$9656").AutoFilter Field:=3, Criteria1:= _
"NOME F"
ActiveSheet.Copy
ActiveWorkbook.SaveAs Filename:="c:Usersc2063910Desktoptestenomef.xlsx", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
If "A2" <> "" Then
ActiveWindow.Close
Else
Range("A1").Select
End If

End Sub

 
Postado : 14/11/2012 12:04 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Bruno, se entendi é só colocar a instrução Exit Sub após a verificação se A2 for diferente de vazio :

If "A2" <> "" Then 'Se A2 for diferente de vazio, CONTINUA a ROTINA
'Se não sai da mesma
Exit Sub

Faça os testes se é isto.

[]s

 
Postado : 15/11/2012 7:05 am
(@brunomendes)
Posts: 6
Active Member
Topic starter
 

Mauro, inda não deu certo, pelo que entendi, o END SUB sai da macro se satisfazer a condição de IF, assim que ele encontra o primeiro filtro vazio, finaliza a macro. Quero que ele rode a macro por inteiro, apenas pule a parte da macro que salva o arquivo quando A2 da nova pasta de trabalho for igual a vazio, ou seja, o falso de IF. Quando encontrar um A2 vazio, nao salva e continua o processo para o próximo filtro.

Explicando melhor:

Filtra NOME A, copia, cria uma nova pasta, cola, se A2 for diferente de vazio, salva no diretório
se A2 for igual a vazio, sai sem salvar da nova pasta de trabalho e passa para próximo filtro
Filtra NOME B, copia, cria uma nova pasta, cola, se A2 for diferente de vazio, salva no diretório
se A2 for igual a vazio, sai sem salvar da nova pasta de trabalho e passa para próximo filtro
Filtra NOME C, copia, cria uma nova pasta, cola, se A2 for diferente de vazio, salva no diretório
se A2 for igual a vazio, sai sem salvar da nova pasta de trabalho e passa para próximo filtro
Filtra NOME D, copia, cria uma nova pasta, cola, se A2 for diferente de vazio, salva no diretório
se A2 for igual a vazio, sai sem salvar da nova pasta de trabalho e passa para próximo filtro
Filtra NOME E, copia, cria uma nova pasta, cola, se A2 for diferente de vazio, salva no diretório
se A2 for igual a vazio, sai sem salvar da nova pasta de trabalho e passa para próximo filtro
Filtra NOME F, copia, cria uma nova pasta, cola, se A2 for diferente de vazio, salva no diretório
se A2 for igual a vazio, sai sem salvar da nova pasta de trabalho e passa para próximo filtro
Até ao final da macro, ou seja, End Sub.

Agradeço pela atenção!

 
Postado : 15/11/2012 8:11 am
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Bruno, com relação a sua macro, não é possivel utilizar a celula A2 como base, pois o filtro a "esconderá" na maioria das vezes.
Para tanto é possivel utilizar em uma outra celula fora do filtro a formula subtotal, que tem o "dom" de sómente considerar os itens visiveis.
Então em Ai1 (por exemplo) coloque =SUBTOTAL(2;AG2:AG10000)
e a sua Macro ficará assim:

Sub teste()
'
' teste Macro

ActiveSheet.Range("$A$1:$AH$9656").AutoFilter Field:=3, Criteria1:="NOME A"
    If Range("AI1") > 0 Then 'Se A2 for diferente de vazio, então salva no diretório
        ActiveSheet.Copy
        ActiveWorkbook.SaveAs Filename:="c:dadosnomea.xlsx", _
        FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
        ActiveWindow.Close
        Range("A1").Select
    End If

ActiveSheet.Range("$A$1:$AH$9656").AutoFilter Field:=3, Criteria1:="NOME B"
    If Range("AI1") > 0 Then
        ActiveSheet.Copy
        ActiveWorkbook.SaveAs Filename:="c:dadosnomeb.xlsx", _
        FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
        ActiveWindow.Close
        Range("A1").Select
    End If
    
ActiveSheet.Range("$A$1:$AH$9656").AutoFilter Field:=3, Criteria1:="NOME C"
    If Range("AI1") > 0 Then
        ActiveSheet.Copy
        ActiveWorkbook.SaveAs Filename:="c:dadosnomec.xlsx", _
        FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
        ActiveWindow.Close
        Range("A1").Select
    End If

ActiveSheet.Range("$A$1:$AH$9656").AutoFilter Field:=3, Criteria1:="NOME D"
    If Range("AI1") > 0 Then
        ActiveSheet.Copy
        ActiveWorkbook.SaveAs Filename:="c:dadosnomed.xlsx", _
        FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
        ActiveWindow.Close
        Range("A1").Select
    End If
    
ActiveSheet.Range("$A$1:$AH$9656").AutoFilter Field:=3, Criteria1:="NOME E"
    If Range("AI1") > 0 Then
        ActiveSheet.Copy
        ActiveWorkbook.SaveAs Filename:="c:dadosnomee.xlsx", _
        FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
        ActiveWindow.Close
        Range("A1").Select
    End If

ActiveSheet.Range("$A$1:$AH$9656").AutoFilter Field:=3, Criteria1:="NOME F"
    If Range("AI1") > 0 Then
        ActiveSheet.Copy
        ActiveWorkbook.SaveAs Filename:="c:dadosnomef.xlsx", _
        FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
        ActiveWindow.Close
        Range("A1").Select
    End If

End Sub

Contudo é possivel utilizar um codigo um pouco mais enxuto:

Sub Filtra()
Dim Cr As Integer, R As Integer, Nome As String
    Cr = Cells(Rows.Count, "A").End(xlUp).Row
    'Range("C1:C" & Cr).Select
    Range("C1:C" & Cr).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range("AK1"), Unique:=True
    R = Cells(Rows.Count, "ak").End(xlUp).Row
For R = 2 To Cells(Rows.Count, "ak").End(xlUp).Row
    Nome = Range("AK" & R).Value

    ActiveSheet.Range("$A$1:$AH$" & Cr).AutoFilter Field:=3, Criteria1:=Nome
    ActiveSheet.Copy
    ActiveWorkbook.SaveAs Filename:="c:dados" & Nome & ".xlsx", _
    FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
    ActiveWindow.Close
Next
Columns("AK:AK").Select
Selection.Clear
Range("A1").Select
End Sub
 
Postado : 15/11/2012 10:13 am
(@brunomendes)
Posts: 6
Active Member
Topic starter
 

Reinaldo,

Primeiro gostaria de agradecer imensamente sua ajuda, ambas as opções deu certinho. É exatamente isso que eu preciso. Muitíssimo obrigado.
Tenho limitações no VBA pois não sei nenhuma linguagem de programação, sei o básico do básico mesmo.

Quando eu me referi a célula A2, estava pensando na A2 da nova pasta de trabalho, o que não expliquei foi que a minha macro copiará e colará especial somente conteúdo na nova pasta de trabalho, isso fará com que somente os dados filtrados apareçam no novo arquivo, evitando a visualização dos demais dados de outras pessoas quando selecionar tudo no filtro por exemplo.
A célula A2 da nova pasta com certeza não estará oculta. Realmente o exemplo que mandei não está copiando especial, deixei assim pois recebi uma sugestão para macro ficar mais enxuta e rápida, porém com a mudança perdeu o objetivo. Percebi isso só depois de publicar, acho que está muito fácil agora pra juntar as rotinas da macro.

Bem, creio que eu terei de usar a primeira opção sua, pois preciso necessariamente do nome do arquivo sem espaços e caracteres especiais e acentos, pois um segundo programa aplicativo pegará esses arquivos pra tratar a informação em outra aplicação.

Amanhã vou fazer os testes pra valer e posto aqui se deu certinho.

Mais uma vez muito obrigado.

 
Postado : 18/11/2012 7:11 pm