Notifications
Clear all

Criar um código em VBA baseado numa Fórmula Matricial

15 Posts
2 Usuários
0 Reactions
1,792 Visualizações
(@fernandofernandes)
Posts: 43750
Illustrious Member
Topic starter
 

Boa noite amigos,

solicito a ajuda de vcs para desenvolver um código em VBA baseado numa Fórmula Matricial. No arquivo em anexo tenho na (plan1 = Lançamentos) e na plan2 (Demonstrativo de valores baseado em Ano/Mês/Produto/Cliente/Tipo de Movimentação e por tipo de entrada (saída ou entrada). Os lançamentos já são mais de 10 mil e essa fórmula esta ficando lenta. Gostaria de saber se alguem pode ajudar a desenvolver ela em VBA. Desde já agradeço pela colaboração.

Segue a fórmula matricial usada.

{=SOMA(SE($A4&B$3&$B$1&$D$1&$F$1&$H$1=TEXTO(Plan1!$E$2:$E$20;"MMM")&TEXTO(Plan1!$E$2:$E$20;"AAA")&SE($B$1="";"";Plan1!$F$2:$F$20)&SE($D$1="";"";Plan1!$D$2:$D$20)&SE($F$1="";"";Plan1!$I$2:$I$20)&SE($H$1="";"";Plan1!$B$2:$B$20);Plan1!$H$2:$H$20))}

Segue o arquivo em anexo.

 
Postado : 24/09/2014 5:22 pm
(@gtsalikis)
Posts: 2373
Noble Member
 

Essa fórmula não te ajuda?

=SOMARPRODUTO((Plan1!$H$2:$H$20)*(TEXTO(Plan1!$E$2:$E$20;"MMM")=$A4)*(ANO(Plan1!$E$2:$E$20)=B$3)*SE($B$1="";1;(Plan1!$F$2:$F$20=$B$1))*SE($D$1="";1;(Plan1!$D$2:$D$20=$D$1))*SE($F$1="";1;(Plan1!$I$2:$I$20=$F$1))*SE($H$1="";1;(Plan1!$B$2:$B$20=$H$1)))
 
Postado : 24/09/2014 5:56 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
Topic starter
 

Boa noite!!

Tente...

Sub AleVBA_13039()
With Range("B4:H15")
    .Formula = "=SUMPRODUCT((Plan1!$H$2:$H$20)*(TEXT(Plan1!$E$2:$E$20,""MMM"")=$A4)*(YEAR(Plan1!$E$2:$E$20)=B$3)*IF($B$1="""",1,(Plan1!$F$2:$F$20=$B$1))*IF($D$1="""",1,(Plan1!$D$2:$D$20=$D$1))*IF($F$1="""",1,(Plan1!$I$2:$I$20=$F$1))*IF($H$1="""",1,(Plan1!$B$2:$B$20=$H$1)))"
    .Value = .Value
End With
End Sub
 
Postado : 24/09/2014 6:23 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
Topic starter
 

Boa noite!!

Baixe arquivo em
https://www.sendspace.com/file/9fo8xl

Att

 
Postado : 24/09/2014 6:26 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
Topic starter
 

Alexandrevba, obrigado por responder, estive testanto o seu codigo e tem algo que nao fechou.

Se eu limpar os campos b1, d1, f1 e h1 e depois colocar em d1 = 2.....vera que nao aparece a informacao. Obs.: fui na plan1 e no cod. cliente (na pimeira linha) eu coloquei 2....ou seja a informacao que deveria puxar seria R$ 5.000,00 e nao trouxe esse resultado

 
Postado : 24/09/2014 6:51 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
Topic starter
 

Primeiro que, função matricial come mesmo muito processamento, não deve ser usada quando a tabela é gigante ou quando vc tem milhares delas... mas como meu lema desde a época do Orkut é, "existem mil maneiras", eu aceitei seu desafio, mas resolvi melhorar sua fórmula, usando um somase() simples, sem matricial e sem macro.

Então eu pensei: soma matricial precisa cair fora. Somase ou somases()?
Pensei SOMASES(), claro. Tem vários critérios. Mas montar os intervalos matricialmente no somases é difícil e inviável, principalmente por causa da forma que vc tratou as datas. Então resolvi por usar o SOMASE() mesmo.

Decidi criar uma coluna de chave na sua base. Concatenar as colunas da base, na própria base, usando o mesmo critério que vc colocou dentro da soma matricial (vide coluna A do arquivo anexo). Uma vez que a chave está fora da função, reduzir-se-ia o impacto dentro do modelo de decisão (http://www.decisionmodels.com/calcsecretsc.htm) que o Excel usa para definir o que precisa ser calculado...
Uma vez calculada a coluna da chave, o Excel só precisaria usar o somase(), que são poucos, e é infinitamente mais rápido que qualquer soma matricial.

Como não tenho aqui a "gigantesa" do seu arquivo, não consigo testar a melhoria (ou não) no desempenho do recálculo.
Portanto, estou postando de volta seu modelo já com a solução que eu propus e você aplica no seu arquivo e compartilha o resultado.

Abs,

FF

 
Postado : 24/09/2014 8:29 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
Topic starter
 

Boa tarde!!

Veja se te ajuda...

Sub AleVBA_13039V2()
With Range("B4:H15")
    .Formula = "=SUMIF(Plan1!$A$2:$A$20,($A4&B$3&$B$1&$D$1&$F$1&$H$1),Plan1!$I$2:$I$20)"
    .Value = .Value
End With
End Sub
 
Postado : 25/09/2014 10:12 am
(@fernandofernandes)
Posts: 43750
Illustrious Member
Topic starter
 

Boa tarde!!

Veja se te ajuda...

Sub AleVBA_13039V2()
With Range("B4:H15")
    .Formula = "=SUMIF(Plan1!$A$2:$A$20,($A4&B$3&$B$1&$D$1&$F$1&$H$1),Plan1!$I$2:$I$20)"
    .Value = .Value
End With
End Sub

Caro amigo Alexandrevba, não executou (apresentou nenhum dado), nem usando filtro e nem sem filtros

 
Postado : 25/09/2014 11:02 am
(@fernandofernandes)
Posts: 43750
Illustrious Member
Topic starter
 

Primeiro que, função matricial come mesmo muito processamento, não deve ser usada quando a tabela é gigante ou quando vc tem milhares delas... mas como meu lema desde a época do Orkut é, "existem mil maneiras", eu aceitei seu desafio, mas resolvi melhorar sua fórmula, usando um somase() simples, sem matricial e sem macro.

Então eu pensei: soma matricial precisa cair fora. Somase ou somases()?
Pensei SOMASES(), claro. Tem vários critérios. Mas montar os intervalos matricialmente no somases é difícil e inviável, principalmente por causa da forma que vc tratou as datas. Então resolvi por usar o SOMASE() mesmo.

Decidi criar uma coluna de chave na sua base. Concatenar as colunas da base, na própria base, usando o mesmo critério que vc colocou dentro da soma matricial (vide coluna A do arquivo anexo). Uma vez que a chave está fora da função, reduzir-se-ia o impacto dentro do modelo de decisão (http://www.decisionmodels.com/calcsecretsc.htm) que o Excel usa para definir o que precisa ser calculado...
Uma vez calculada a coluna da chave, o Excel só precisaria usar o somase(), que são poucos, e é infinitamente mais rápido que qualquer soma matricial.

Como não tenho aqui a "gigantesa" do seu arquivo, não consigo testar a melhoria (ou não) no desempenho do recálculo.
Portanto, estou postando de volta seu modelo já com a solução que eu propus e você aplica no seu arquivo e compartilha o resultado.

Abs,

FF

Caro amigo fernando.fernandes, apliquei a sua solução ao meu projeto e o resultado foi positivo, as informações foram processadas com rapidez e o resultado foi correto. Te agradeço pela ajuda prestada. Com certeza será aproveitado a sua solução em inumeros outros casos.

 
Postado : 25/09/2014 11:13 am
(@fernandofernandes)
Posts: 43750
Illustrious Member
Topic starter
 

Favor marcar o tópico como resolvido clicando no v'zinho verde da minha resposta.

p.s.: uma tabela dinâmica também seria uma ótima solução sem macro (melhor até).

Segue anexo!

FF

 
Postado : 26/09/2014 1:38 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
Topic starter
 

Bom dia!!

Veja o anexo, favor habilitar as macros!

Att

 
Postado : 27/09/2014 7:25 am
(@fernandofernandes)
Posts: 43750
Illustrious Member
Topic starter
 

Alexandrevba,

Boa tarde amigo, apliquei o código na minha planilha, porém estou recebendo essa mensagem abaixo:

Erro em tempo de execução '1004':
Não é possivel definir a propriedade FormulaArray da classe Range

O que poderia estar errado, haja visto que no modelo funcionou perfeitamente.

 
Postado : 29/09/2014 11:15 am
(@fernandofernandes)
Posts: 43750
Illustrious Member
Topic starter
 

O problema de todas repostas do Alexandre neste tópico, é que ele transformou em VBA, sem analisar nada, todas as respostas dadas anteriormente.

Eu conclui que sua melhor solução seria fugir da matricial e usar o somase()... Se tem q ser VBA, daí talvez alguma das respostas dele te atendam, mas vc deixou claro que seu problema é com o desempenho. Vc é um caso clássico (por favor não se ofenda) de membro que pede uma solução que pode não ser a melhor para seu caso. E eu sempre tento oferecer a melhor solução. A não ser que você tenha um bom motivo pq tem que ser VBA, eu diria que vc deve desconsiderar as propostas do Alexandre e ficar com o somase ou a tabela dinâmica que enviei.

Alexandre, por favor não se ofenda. Sei q vc tentou responder claramente como foi perguntado, ou seja, com vba. E aplicou o VBA em tudo q foi postado aqui.
o VBA do sumif por exemplo, soh funcionaria se aplicado no arquivo que eu mandei, mesmo assim não melhoraria o desempenho... Enfim, acho que não foi dessa vez.

Kalebe, sua solicitação já foi atendida... Sugiro marcar como resolvido.

Abraço. FF

FF

 
Postado : 29/09/2014 3:42 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
Topic starter
 

fernando.fernandes,

Agradeci sua solução, que por sinal É EXCELENTE. A razão de estar procurando uma solução em VBA é que no meu entender (que é bem escasso) haverá um recalculo de todas as fórmulas a cada vez que eu entrar na base de dados para inserir novos dados fazendo uso da sua solução. Nesse momento mantenho a minha base de dados sem fazer uso de nenhuma formula, apenas DADOS PUROS. A tua solução é ótima, perfeita, atende minha necessidade, já testei. FUNCIONA, só que teria que colocar uma formula na base de dados, e isso eu não queria. Apenas optei pela solução em VBA para manter a base de dados "pura". Sinto muito pela confusão amigo.

 
Postado : 29/09/2014 5:31 pm
(@fernandofernandes)
Posts: 43750
Illustrious Member
Topic starter
 

Leia isso que mandei la no começo:
http://www.decisionmodels.com/calcsecretsc.htm

 
Postado : 29/09/2014 8:01 pm