Notifications
Clear all

2 Macros automáticas após alteração de célula

9 Posts
4 Usuários
0 Reactions
2,310 Visualizações
(@danyahoo)
Posts: 49
Trusted Member
Topic starter
 

Prezados, bom dia!

Gostaria de saber como automatizar duas macros.

Célula de referência: P3

Gostaria que o Excel executasse esta macro automaticamente sempre que eu inserisse dados na Celula P3:

Sub Lista_Cursos()
    Range("W1").Select
    Range(Selection, Selection.End(xlDown)).Select
    Selection.Copy
    Range("X1").Select
    ActiveWindow.SmallScroll Down:=-12
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Application.CutCopyMode = False
    ActiveWorkbook.Worksheets("Relatório_IRRF").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("Relatório_IRRF").Sort.SortFields.Add Key:=Range( _
        "X1"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:= _
        xlSortTextAsNumbers
    With ActiveWorkbook.Worksheets("Relatório_IRRF").Sort
        .SetRange Range("X1:X2999")
        .Header = xlGuess
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
    ActiveSheet.Range("$X$1:$X$2999").RemoveDuplicates Columns:=1, Header:=xlNo
End Sub

E gostaria que o Excel executasse esta macro sempre que eu limpasse o conteúdo da célula P3:

Sub Limpar_Cursos()
    Range("X1:X3000").Select
    Selection.ClearContents
End Sub

Já pesquisei diversos códigos, porem sem sucesso.

Aguardo retorno dos mestres!

Obrigado.

 
Postado : 25/04/2012 8:32 am
(@felipesalomao)
Posts: 103
Estimable Member
 

Para insersao de dados use:

Private Sub Worksheet_Change(ByVal Target As Range)
        
        Application.EnableEvents = False
        If Not Intersect(Target, Range("P3:P3")) Is Nothing Then
                Call Módulox.Lista_Cursos
         End If
         
End Sub

Sendo que em modulox você vai substituir o x pelo numero do modulo da sua macro.

Ja se apagar e executar outra macro, no momento não sei te ajudar.

Abs

 
Postado : 25/04/2012 10:48 am
(@danyahoo)
Posts: 49
Trusted Member
Topic starter
 

Obrigado Felipe!

Agora só aguardando uma solução para a outra.

Pensei em algo assim: inserir no código acima um IF "P3" = "" ai chama a macro de Limpar...

 
Postado : 25/04/2012 12:06 pm
(@danyahoo)
Posts: 49
Trusted Member
Topic starter
 

Tentei editar a postagem anterior mas não deu...

A execução automática da macro somente ocorre na primeira execução quando abro a planilha, depois que deleto os dados e insiro outros a macro não roda.

O que está dando errado?

 
Postado : 25/04/2012 12:19 pm
(@dlhunsil)
Posts: 21
Eminent Member
 

oq pode ser q de certo é vc construir a estrutura dentro

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)

End Sub

ele faz a macro execultar apos alguma alteração

 
Postado : 25/04/2012 3:24 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Boa noite!!

Nõ sei se entendi mas, você já tentou...?

Private Sub Worksheet_Change(ByVal Target As Range)
        
        Application.EnableEvents = False
        If Not Intersect(Target, Range("P3:P3")) Is Nothing Then
                Call Módulox.Lista_Cursos
                [b]Call SuaMacroLimpar[/b]


         End If
         
End Sub
 
Postado : 25/04/2012 6:27 pm
(@dlhunsil)
Posts: 21
Eminent Member
 

essa estrutura não fica em modulo e sim, no proprio vba , na propria pasta

Private Sub Worksheet_Change(ByVal Target As Range)

if activecell = "" then
      Range("X1:X3000").Select
      Selection.ClearContents
else
      Range("W1").Select
      Range(Selection, Selection.End(xlDown)).Select
      Selection.Copy
      Range("X1").Select
      ActiveWindow.SmallScroll Down:=-12
      Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
          :=False, Transpose:=False
      Application.CutCopyMode = False
      ActiveWorkbook.Worksheets("Relatório_IRRF").Sort.SortFields.Clear
      ActiveWorkbook.Worksheets("Relatório_IRRF").Sort.SortFields.Add Key:=Range( _
          "X1"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:= _
          xlSortTextAsNumbers
      With ActiveWorkbook.Worksheets("Relatório_IRRF").Sort
          .SetRange Range("X1:X2999")
          .Header = xlGuess
          .MatchCase = False
          .Orientation = xlTopToBottom
          .SortMethod = xlPinYin
          .Apply
      End With
      ActiveSheet.Range("$X$1:$X$2999").RemoveDuplicates Columns:=1, Header:=xlNo
End Sub

vou ser sincero não consegui testar
mas pensando não sei se vai te ajudar pois cada alteração em qualquer celula vai fazer ela rodar
se caso tenha somente esse ponto de alteração pode ser q funcione

 
Postado : 26/04/2012 5:56 am
(@danyahoo)
Posts: 49
Trusted Member
Topic starter
 

Prezados, boa tarde!

Desculpe por ainda não ter dado feedback.

Não precisarei mas de automatizar as macros, consegui resolver meu problema apenas por fórmulas matriciais, o que acelerou incrivelmente o processamento dos dados.

Vou descrever qual era meu objetivo e como cheguei a solução, talves ajude outras pessoas.

As macros automatizadas seriam para uma planilha de mensalidades pagas onde em uma das abas tenho um modelo de declaração para IR.

Para montar esta declaração são necessários 3 preenchimentos: 1º é o CPF, colocando este dado a planilha busca todos os cursos que a pessoa já fez e cria uma lista para selecionar o curso, que é o 2º campo a se selecionar. O 3º campo é o ano de referência que a pessoa quer.

Após inserir estes 3 dados a planilha gera automaticamente uma declaração para IR com todos valores que a pessoa pagou naquele determinado ano.

Quando o 1º problema surgiu: Após colocar o CPF eu precisava selecionar o curso, inicialmente usei o PROCV porem ele busca apenas a primeira correspondência, ai eu tive que colocar chave (CPF+numero sequencial) em todas as linhas da planilha de dados para buscar todas as referências para o CPF. Resolvi este problema colocando a seguinte função matricial em apenas 100 linas (acredito que não aconteça de alguem pagar 100 parcelas :shock: ):

{=SE(LINS($1:1)>CONT.SE(Cursos_teste;$P$3);"";ÍNDICE(Cursos_teste2;MENOR(SE(Cursos_teste=$P$3;LIN(Cursos_teste)-LIN(P$5)+1;FALSO);LINS($1:1))))}

Com ela em vez de ter chave em todas as linhas, agora ela busca apenas as correspondências para o CPF, se tem 10 ele busca as 10, se tem 20 ele busca as 20.

Quando o 2º problema surgiu: Após o procedimento anterior eu precisei criar uma Lista com o resultado, porem deveria ser apenas os valores únicos. Ai veio as duas macros do tópico, copiava, colava ao lado, copiava, colava por cima, tirava os duplicados e ordenava.... Resolvi isso usando outra fórmula matricial:

{=SEERRO(ÍNDICE($AE$1:$AE$100; MENOR(SE(CORRESP(SE($AE$1:$AE$100="";"";$AE$1:$AE$100); SE($AE$1:$AE$100="";"";$AE$1:$AE$100);0)= LIN(INDIRETO("1:"&LINS($AE$1:$AE$100))); CORRESP(SE($AE$1:$AE$100="";"";$AE$1:$AE$100); SE($AE$1:$AE$100="";"";$AE$1:$AE$100);0);""); LIN(INDIRETO("1:"&LINS($AE$1:$AE$100)))));"")}

Com essa fórmula vem apenas os valores únicos.

Quando o 3º problema surgiu: Quando precisei formar uma lista para seleção do curso. Não queria valores em branco na lista, e como uma pessoa poderia ter mais de um curso coloquei estes dois códigos no Gerenciador de nomes para criar a lista com valores únicos:

Lista_cursos_IRRF
=DESLOC(Relatório_IRRF!$AF$1;0;0;CONT.VALORES(Relatório_IRRF!$AF:$AF);1)

Lista_cursos_IRRF2
=DESLOC(Relatório_IRRF!$AF$1;0;0;CONT.VALORES(Relatório_IRRF!$AF:$AF)-CONT.SE(Lista_cursos_IRRF;"");1)

Agora se o CPF tem apenas 1 curso, aparece apenas uma opção na lista, se ela tem 20, aparecem 20 opções!

O processamento da planilha está fantástico, coloco o CPF e quase que instantaneamente já aparece a lista dos cursos. Antes era um Deus nos acuda! :lol:

Agora vou tentar agregar esta nova "tecnologia" para minhas outras planilhas.... :shock: :mrgreen: :lol:

Bom é isso! Obrigados a todos que me ajudaram de alguma forma! :D

 
Postado : 27/04/2012 11:09 am
(@dlhunsil)
Posts: 21
Eminent Member
 

apesar de não ser mais util nesse caso vou postar a forma de ativar uma macro apartir da alteração de uma celula especifica

Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$C$3" Then
Range("a1").Select
End If
End Sub

essa é uma macro simples para exemplicar sendo q a alteração do valor de C3 faz com q ai seja selecionada
resaltando q essa função não é modulo e é construida na fonte da planilha

 
Postado : 27/04/2012 12:15 pm