Página 1 de 1
VBA copia e cola mediante cada lançamento (linha a linha)
Enviado: 05 Mai 2018 às 16:07
por AlexandreJos
Prezados,
Boa tarde.
No código VBA abaixo eu tento validar duas condições na aba Saldos (que acontecerão na coluna D e G). Estas condições são lançadas manualmente linha a linha.
Quando as duas condições ocorrerem juntas, então a planilha vai para a aba Cálculos, copia o conteúdo da célula F10 a cola na na célula AD26 da aba Saldos. Meu código VBA não funciona. Alguém, por favor, poderia dar uma olhada em meu código VBA?
SE FOSSE uma fórmula ficaria assim... (talvez ajude):
=SE(E(G25="Ativa";D25="MBT");Cálculos!F6;
SE(E(G25="Ativa";D25="Falou(A)");Cálculos!J6;
SE(E(G25="Ativa";D25="Falou(B)");Cálculos!N6;
SE(E(G25="Ativa";D25="BTD");Cálculos!N6;
SE(E(G25="Ativa";D25="BRZ");Cálculos!R6;
SE(E(G25="Ativa";D25="FBT");Cálculos!V6;
SE(E(G25="Ativa";D25="ARN");Cálculos!Z6;
SE(E(G25="Ativa";D25="B2U");Cálculos!AH6;
SE(E(G25="Ativa";D25="NEG");Cálculos!AL6;
SE(E(G25="Ativa";D25="FOX");Cálculos!AP6;
SE(E(G25="Ativa";D25="WAL");Cálculos!AT6;
SE(E(G25="Ativa";D25="TEM");Cálculos!AX6;
SE(E(G25="Ativa";D25="MBT Dentro");Cálculos!BB6;
))))))))))))))
Acontece que a aba Saldos é uma aba de lançamentos, isto é, o VBA tem que reconhecer os lançamentos manuais, linha a linha, nas colunas D e G da aba Saldos.
NOTA: Pensei e usar o Seletc Case porque serão muitas condições para validar.
**************************************** esta é minha tentativa de código ****************************************
Private Sub Worksheet_OrdemAtiva(ByVal Target As Range)
'Determina a coluna G como a linha ativa da planilha
If Target.Column = 7 Then
Application.EnableEvents = False
'Variável da linha ativa
OrdemAtiva = Target.Row
'Identifica a Exchange lançada na coluna D e identifica se a ordem na coluna G é Ativa
Select Case Range("D").Value = "D25" And Range("G" & OrdemAtiva).Value = "Ativa"
'Busca na aba Cálculos, da Exchange lançada, o resultado do cálculo feito para uma Ordem Ativa
Case Is = Sheets("Cálculos").Cells(10, 6).Value
'Inputa o resultado (acima) do cálculo feito na aba Cálculos, da Exchange lançada para uma Ordem Ativa
Range("AD" & OrdemAtiva).Value = Sheets("Cálculos").Cells(10, 6).Value
'Elimina a fórmula e deixa o seu resultado na célula
Range("AD" & OrdemAtiva).Value = Range("AD" & OrdemAtiva).Value
End Select
Application.EnableEvents = True
End If
**********************************************************************************************************************
Desde já fico muito agradecido pela ajuda.
Re: VBA copia e cola mediante cada lançamento (linha a linh
Enviado: 05 Mai 2018 às 18:01
por osvaldomp
Veja se ajuda. Instale o código abaixo no módulo da planilha "Saldos".
Código: Selecionar todosPrivate Sub Worksheet_Change(ByVal Target As Range)
Dim OrdemAtiva As Long, Origem As String
If Target.Count > 1 Then Exit Sub
If Target.Column <> 4 And Target.Column <> 7 Then Exit Sub
If Cells(Target.Row, "G") <> "Ativa" Then Exit Sub
Select Case Cells(Target.Row, "D")
Case "MBT": Origem = "F6"
Case "Falou(A)": Origem = "J6"
Case "Falou(B)": Origem = "N6"
Case "BTD": Origem = "N6"
Case "BRZ": Origem = "R6"
Case "FBT": Origem = "V6"
Case "ARN": Origem = "Z6"
Case "B2U": Origem = "AH6"
Case "NEG": Origem = "AL6"
Case "FOX": Origem = "AP6"
Case "WAL": Origem = "AT6"
Case "TEM": Origem = "AX6"
Case "MBT Dentro": Origem = "BB6"
Case Else: Exit Sub
End Select
Cells(Target.Row, "AD") = Sheets("Cálculos").Range(Origem).Value
End Sub
VBA copia e cola mediante cada lançamento (linha a linha)
Enviado: 05 Mai 2018 às 18:58
por AlexandreJos
Caro Osvaldomp,
Muito obrigado pelo retorno.
Duas perguntas (me desculpe a ignorância em VBA):
1) Devo substituir a palavra "Origem" pela célula onde quero ver o resultado da fórmula? Se sim, poderia me dar um exemplo de como a escrevo? Ex: Sheet("Saldos").Cell("AD",25). Não tenho certeza se é assim que se escreve.
2) O que significa a expressão "Target.Count > 1 " descrita no código?
OBS: Colei seu código no Módulo 1 da Aba Saldos. Nada aconteceu, mesmo eu relançando as células com as condições.
VBA copia e cola mediante cada lançamento (linha a linha)
Enviado: 05 Mai 2018 às 19:06
por AlexandreJos
Agora que vi no final do código que você escreveu:
Cells(Target.Row, "AD") = Sheets("Cálculos").Range(Origem).Value
Então, minha pergunta não faz sentido. O que pode estar acontecendo para nada acontecer?
Re: VBA copia e cola mediante cada lançamento (linha a linh
Enviado: 05 Mai 2018 às 20:08
por osvaldomp
AlexandreJos escreveu:
1) Devo substituir a palavra "Origem"... ~~~> não é preciso qualquer substituição no código que passei
2) O que significa a expressão "Target.Count > 1 " ~~~> como o código trata da alteração efetuada manualmente somente em uma célula, então se for efetuada alguma alteração que envolve mais de uma célula (ex. inserir/excluir linha/coluna, inserir/remover conteúdo em mais de uma célula por vez) o código retorna erro, por isso coloquei esse comando para não executar o código naqueles casos.
OBS: Colei seu código no Módulo 1 da Aba Saldos. ~~~> não existe Módulo 1 da aba Saldos; Módulo 1, Módulo 2, ... são os nomes dados automaticamente pelo Excel ao se inserirem módulos comuns; para inserir o código no módulo da planilha "Saldos" faça assim: clique com o direito na guia da planilha "Saldos" / Exibir Código / a janela em branco que irá se abrir é o módulo daquela planilha / cole o código nessa janela
funcionamento
1. o código será disparado ao alterar/inserir/colar/deletar conteúdo ou na coluna D ou na coluna G da planilha "Saldos", em qualquer ordem
2. se na coluna G o conteúdo for diferente de "Ativa" então a execução será encerrada
3. se na coluna D o conteúdo for igual a algum dos critérios do
Select Case então a coluna AD receberá cópia do conteúdo da planilha "Cálculos" da célula indicada no
Select Case, sendo o endereço da célula atribuido à variável "Origem"; exemplo: se D = "MBT" então Origem = "F6", portanto o conteúdo da célula "F6" da planilha "Cálculos" será replicado na coluna AD da planilha "Saldos".
Como eu não entendi com exatidão a sua necessidade este código pode servir como ponto de partida. Aí você informa o que deseja manter e o que deseja alterar/acrescentar.
Re: VBA copia e cola mediante cada lançamento (linha a linh
Enviado: 07 Mai 2018 às 10:16
por AlexandreJos
Caro Osvaldomp,
Bom dia.
Muito obrigado pelas explicações e pelo código!
Eu tive dificuldades para fazê-lo funcionar porque no VBE, na mesma aba Saldos, já havia outro importante código.
Quado eu tirei o código que já havia e coloquei somente o seu, ele funcionou perfeitamente. Muito bom! Estou tentando fazê-los funcionar juntos, motivo pelo qual não eu lhe dei um retorno antes. Mas por hora, sem sucesso. Você acha que pode me ajudar a organizar isso?
O primeiro erro é que ele não deixa te dois "Private Sub Worksheet_Change(ByVal Target As Range)" juntos. Então imagino tenho que colocá-los tudo dentro da mesma Private Sub.
O segundo ponto que imagino ser o problema é a ordem das "Sub Exit". Acho o VBA está tirando da Sub antes da hora.
Abaixo seguem os dois códigos (eles são curtos).
****************** este é o código que já estava ******************
Private Sub Worksheet_Change(ByVal Target As Range)
'Determina a coluna F como a linha ativa da planilha
If Target.Column = 6 Then ' (Coluna F)
Application.EnableEvents = False
'Variável da linha ativa
LinhaModificada = Target.Row
'Procura por Compra ou Venda na coluna F
If Range("F" & LinhaModificada).Value = "Compra" Or Range("F" & LinhaModificada).Value = "Venda" Then
'Multiplica a Quantidade pela Cotação e soma o Total dos Custos
Range("T" & LinhaModificada + 1).Value = (Range("T" & LinhaModificada).Value * Range("N" & LinhaModificada).Value) + Range("U" & LinhaModificada + 1).Value
'Elimina a fórmula e deixa o seu resultado na célula
Range("T" & LinhaModificada + 1).Value = Range("T" & LinhaModificada + 1).Value
End If
Application.EnableEvents = True
End If
End Sub
****************** este é o código que você propôs ******************
Private Sub Worksheet_Change(ByVal Target As Range)
Dim OrdemAtiva As Long, Origem As String
If Target.Count > 1 Then Exit Sub
If Target.Column <> 4 And Target.Column <> 7 Then Exit Sub
If Cells(Target.Row, "G") <> "Ativa" Then Exit Sub
Select Case Cells(Target.Row, "D")
Case "MBT": Origem = "F6"
Case "FLW(A)": Origem = "J6"
Case "FLW(B)": Origem = "N6"
Case "BTD": Origem = "N6"
Case "BRZ": Origem = "R6"
Case "FBT": Origem = "V6"
Case "ARN": Origem = "Z6"
Case "B2U": Origem = "AH6"
Case "NEG": Origem = "AL6"
Case "FOX": Origem = "AP6"
Case "WAL": Origem = "AT6"
Case "TEM": Origem = "AX6"
Case "MBT Dentro": Origem = "BB6"
Case Else: Exit Sub
End Select
Cells(Target.Row, "AD") = Sheets("Cálculos").Range(Origem).Value
End Sub
*********************************************************************
Estou muito, muito agradecido pela ajuda.
Re: VBA copia e cola mediante cada lançamento (linha a linh
Enviado: 07 Mai 2018 às 11:11
por osvaldomp
Juntei os dois códigos. Veja se atende.
Código: Selecionar todosPrivate Sub Worksheet_Change(ByVal Target As Range)
Dim Origem As String
If Target.Count > 1 Then Exit Sub
'verifica se a alteração ocorreu na coluna F e se a célula ativa contém Compra ou Venda
If Target.Column = 6 And (Target.Value = "Compra" Or Target.Value = "Venda") Then
'Multiplica a Quantidade pela Cotação e soma o Total dos Custos
Range("T" & Target.Row + 1).Value = Range("T" & Target.Row).Value * Range("N" & Target.Row).Value + Range("U" & Target.Row + 1).Value
End If
If Target.Column <> 4 And Target.Column <> 7 Then Exit Sub
If Cells(Target.Row, "G") <> "Ativa" Then Exit Sub
Select Case Cells(Target.Row, "D")
Case "MBT": Origem = "F6"
Case "FLW(A)": Origem = "J6"
Case "FLW(B)": Origem = "N6"
Case "BTD": Origem = "N6"
Case "BRZ": Origem = "R6"
Case "FBT": Origem = "V6"
Case "ARN": Origem = "Z6"
Case "B2U": Origem = "AH6"
Case "NEG": Origem = "AL6"
Case "FOX": Origem = "AP6"
Case "WAL": Origem = "AT6"
Case "TEM": Origem = "AX6"
Case "MBT Dentro": Origem = "BB6"
Case Else: Exit Sub
End Select
Cells(Target.Row, "AD") = Sheets("Cálculos").Range(Origem).Value
End Sub
VBA copia e cola mediante cada lançamento (linha a linha)
Enviado: 07 Mai 2018 às 15:44
por AlexandreJos
Caro Osvaldo,
Boa tarde e muito obrigado pelo retorno.
Seu código funcionou perfeitamente! Meu caro, você foi de uma precisão incrível! Me impressiona estaa habilidade de resolver estas questões assim.
Como eu tenho que aplicar a lógica do código que vc fez para outras situações (outros custos) seria legal eu entender melhor algumas partes do código, assim tentarei diminuir esta dependência e lhe dar sossego. (rs)
Então, sem querer abusar de sua boníssima vontade, se puder responder, logo abaixo eu relacionei três dúvidas. Vamos a elas.
1) No primeiro código, antes de juntar-se ao seu, ele tinha algumas expressões (me desculpe se esta não é a denominação correta), com finalidades específicas e eu as entendia. Depois da junção elas foram retiradas. São elas:
a) "Application.EnableEvents = False / Application.EnableEvents = True": servia para a planilha não ficar atualizando cálculos
desnecessariamente diante e alguma alteração na aba. Considerando que ela realmente cumpria este papel, ao termos retirado esta
expressão, esta funcionalidade também deixou de existir?
b) Ainda no primeiro código, existia a expressão "Range("T" & LinhaModificada + 1).Value = Range("T" & LinhaModificada + 1).Value"
A ideia aqui era de elimina a fórmula e deixa o seu resultado na célula, porque se o banco de dados mudar, o cálculo no decorrer do
histórico seria mantido. Considerando que ela realmente cumpria este papel, ao termos retirado esta expressão, esta também
funcionalidade eixou de existir?
c) baseado no seu código eu vou juntar outros nesta aba. Serão outros códigos de custos, parecidos com o que você fez. Por favor, onde
devo inseri-los?
Mais uma vez, muito obrigado pela ajuda!
Re: VBA copia e cola mediante cada lançamento (linha a linh
Enviado: 08 Mai 2018 às 10:46
por osvaldomp
AlexandreJos escreveu:
1) No primeiro código, antes de juntar-se ao seu, ele tinha algumas expressões (me desculpe se esta não é a denominação correta), com finalidades específicas e eu as entendia. Depois da junção elas foram retiradas. São elas:
a) "Application.EnableEvents = False / Application.EnableEvents = True": servia para a planilha não ficar atualizando cálculos desnecessariamente diante e alguma alteração na aba. Considerando que ela realmente cumpria este papel, ao termos retirado esta expressão, esta funcionalidade também deixou de existir?
Se em um código atrelado ao evento Worksheet_Change houver um comando que altere o conteúdo de alguma célula então essa alteração irá disparar novamente o evento. Se a alteração ocorrer na célula que está sendo tratada pelo código isso acarretará um Loop interminável (já viu um cão girando, tentando morder o próprio rabo).
Para evitar essa ocorrência usa-se a desativação de eventos (EnableEvents=False) antes do comando que faz alteração de conteúdo.
No seu caso não há a possibilidade da ocorrência de Loop interminável visto que na primeira parte do código a coluna alterada pelo comando é a T e a coluna tratada é a F. E na segunda parte a coluna alterada é a AD e as colunas tratadas são D e G. Então sem o uso do comando que desativa eventos o código se auto dispara porém se auto encerra tendo em vista o que já comentei que as células alteradas pelo código são diferentes das células tratadas pelo próprio código. A diferença ao usar aquele comando é que o código não se auto dispara, reduzindo o tempo de execução, o que no caso do seu código é irrelevante.
No entanto, o uso daquele comando traz algum risco. Se o código travar durante a execução em algum comando localizado entre o False e o True então a execução de macros não mais funcionará no Excel até que a desativação de eventos seja resetada manualmente (veja abaixo), por isso eu utilizo esse comando somente nos casos em que há a necessidade de impedir Loops intermináveis.
b) Ainda no primeiro código, existia a expressão "Range("T" & LinhaModificada + 1).Value = Range("T" & LinhaModificada + 1).Value"
A ideia aqui era de elimina a fórmula e deixa o seu resultado na célula, porque se o banco de dados mudar, o cálculo no decorrer do
histórico seria mantido. Considerando que ela realmente cumpria este papel, ao termos retirado esta expressão, esta também
funcionalidade eixou de existir?
Esse comando insere na célula já o resultado dos cálculos, ou seja, insere um valor e não uma fórmula.
c) baseado no seu código eu vou juntar outros nesta aba. Serão outros códigos de custos, parecidos com o que você fez. Por favor, onde
devo inseri-los?
Sem ver os outros códigos fica inviável comentar algo. Tente seguir a estrutura que está funcionando a contento, se não conseguir retorne.
Quanto a resetar a desativação de eventos:
Antes, para saber se a desativação está ativada/desativada ~~~> no editor de VBA aperte Ctrl+G para abrir a janela "Verificação imediata" / naquela janela digite ?Application.EnableEvents e em seguida aperte Enter. Logo abaixo será exibido ou Verdadeiro ou Falso.
Duas formas para resetar:
1. em um módulo comum cole o código abaixo e execute-o via tecla F8 a partir do editor de VBA
Sub Reseta()
Application.EnableEvents=True
End Sub
ou
2. na janela "Verificação imediata" digite Application.EnableEvents=True e aperte Enter
Re: VBA copia e cola mediante cada lançamento (linha a linh
Enviado: 09 Mai 2018 às 10:27
por AlexandreJos
Osvaldo,
Muito obrigado pelas explicações e paciência. Não sou programador, mas vou lhe dizer, que me fez sentir vontade de aprender cada vez mais sobre programação. Adoro automações e é muito legal ver a coisa toda funcionando a partir de um código de programação.
Obrigado mais uma vez. Espero poder encontrá-lo outras vezes por aqui. Você é o cara.
OBS: Eu tenho interesse em conhecer melhor sua formação e competências para futuros negócios ou parcerias. Acha que podemos trocar nossos contatos fora do fórum?