Cálculo automático por Macro de fórmula arquivada em célula

Não entendi muito bem o que você quer. Talvez com uma planilha de exemplo… Mas, pensei no que o Olivier comentou e também no que respondi aqui: Macro procv.

@Grafeno / @ohallot, com base nesta macro Cálculo automático por Macro sem fórmula na célula (excelente pois não tenho que repetir formula célula por célula), tomando como exemplo o caso da “question/61432”, onde o cálculo foi “escrito na Macro”, existe alguma possibilidade de uma MACRO executar uma formula que esta em uma célula? Se isto for possível seria ótimo, pois com uma MACRO seria possível executar qualquer comando do Calc. (continua)…

(continuando)… Ou seja nesta MACRO as únicas variáveis seriam a área que ela deve atuar e o endereço da célula que está a formula à executar.

Talvez eu ainda não tenha entendido o que vc quer, mas vou arriscar colocar o que penso: sem “transcrever” a fórmula no próprio código da macro, ela não a “executará”. De outro modo, sempre será necessário um método para servir de ponte ente a macro e o Calc, que é quem de fato “executará” a fórmula.

“[…]seja qual for a fórmula existindo referencias relativas e absolutas, comportando-se igual a cópia de fórmulas.” ==> Uma macro que funcione como uma espécie de ctrl+C e ctrl+V da fórmula atenderia seu objetivo? Na célula de destino vc quer a fórmula com as referências ajustadas ou só o valor já processado?

Oi @Grafeno, sim só o valor. Esclarecendo a necessidade: A intenção é ter uma planilha que execute grande quantidade de formulas, porém não gostaria que estivessem na planilha milhares de células com fórmulas a espera de informações para cálculo. Então, pegando como modelo a Macro da questão 61432, já mencionada, onde foi definida a área de abrangência do evento (coluna A e B) se positiva executa a operação (Ax+Bx) e grava na coluna C correspondente, que funciona perfeitamente OK. (continua…)

(…continuando) A Macro seria semelhante, porém na Macro só teria a informação da abrangência do evento (exemplo: G45:K78) e indicaria na Macro a célula da formula a executar (exemplo: AA2) na qual estaria a formula por exemplo: =SE(G45<>0;PROCV(G45;matriz;Indice;Ordem);""). Desta maneira uma Macro atenderia diversas situações pois a “área de abrangência” e “a célula da formula a executar” seriam facilmente alteráveis nesta Macro, não teria que a cada caso definir o cálculo na Macro.

Oi @Grafeno, pensando bem, poderia até ter a opção de gravar a formula ajustada ou só o valor, ficaria mais completa.

@Gilberto: Se seu objetivo é economizar fórmulas com uma macro, eu sugiro você usar uma fórmula de matriz no intervalo, por que com formula de matriz, temos 1 fórmula que se aplica N células ao invés de N formulas para N células. A redução do tamanho do arquivo e a velocidade do calculo melhoram.

Se este for o caso, a fórmula de matriz seria na coluna C

= A1:A5555 + B1:B5555 

e ao invés de teclar Enter, tecle Ctrl+Shift+Enter

@ohallot, conheço alguma coisa sobre fórmula de matriz, mas no exemplo que deu se houver dados até a linha 3000 as demais (C3001:C5555) ficarão com a formula replicada, então a matriz só automatiza a duplicação da célula para as demais (neste caso), quanto a redução do tamanho do arquivo não tem ganho, se olhar o arquivo interno “content.xml” do arquivo ods vera a formula duplicada para todas as linhas.

Segue o trecho colocando uma formula qualquer na sua célula A1 da Planilha1

oPlanilha  = ThisComponent.Sheets.getByName("Planilha1")
oCell = oPlanilha.getCellRangeByName("A1")
oCell.Formula = "=SIN(PI()*B3/A20)"

Note que a expressão da fórmula tem de ser como se fosse no idioma inglês, sempre. Na célula A1 ela vai aparecer em português.

Não quero colocar a formula na célula e sim “ter possibilidade de uma MACRO executar uma FORMULA que esta em uma célula?”.

Não é copiar a formula para a célula e sim executar a que esta em uma célula…vide arquivo anexo com a macro escrita por @Grafeno com exemplo básico, observações no arquivo…

https://dl.dropboxusercontent.com/u/107127435/ask.libreoffice/Calculo%20automatico%20por%20macro.ods

Pode explicar por que precisa de uma macro para fazer a soma de dois números em colunas diferentes? Não ficou v

Como disse acima “exemplo básico” a pergunta é simples: É possível uma macro executar a FORMULA, seja qual for, que esteja inserida em uma célula?

Penso, só penso! Uma fórmula tem o sinal “=” (sinal de igual) para valer. Então, se a macro, sob determinada condição substituir uma sequência de caracteres pelo sinal de “=” irá "disparar a fórmula. Ou seja, acredito que sim. Tudo depende mais de como tratar o evento, ou seja: em que situação isso ocorreria.

Gilberto, Isso é o que você quer: a diferença que você atinge por concatenação de células o que a torna extremamente versátil, no meu ponto de vista.
Resposta/colaboração do Olivier

Na prática seria isso que pensei: Um exemplo de uso da funcao BETO :wink: criada pelo Olivier para baixar

Um vídeo e um texto: Meu blog

[…] pensando bem, poderia até ter a opção de gravar a formula ajustada ou só o valor, ficaria mais completa.

Adaptei o código da outra resposta para incluir uma chamada (Call) a uma sub-rotina (InserirValorFormula) que copia a fórmula da célula “C1” e cola (ajustando as referências) na célula “Cn”, onde “n” é a linha do evento que dispara a marcro principal. A sub-rotina ainda faz a “conversão” da fórmula de “Cn” em seu valor.

REM  >>> Evento de Planilha => Conteúdo Alterado <<<
Sub Plan1_ConteudoAlterado( oCelula )
Dim oPlan as Object, oControl As Object
Dim oCelFor As Object, oDestino As Object
Dim nLin as Long, nCol as Long
Dim vCel As Double, vCelA As Double, vCelB As Double

    ' Sair se não for uma célula
    If oCelula.ImplementationName <> "ScCellObj" Then Exit Sub

    nLin = oCelula.CellAddress.Row
    nCol = oCelula.CellAddress.Column
    vCel = oCelula.Value
    oPlan = oCelula.getSpreadsheet

    ' Sair se a cél. estiver na linha 1 ou
    ' se o valor da cél. for 0
    If vCel = 0 or nLin = 0 Then Exit Sub
    
    ' Controlador e a célula com a fórmula
    oControl = ThisComponent.CurrentController
    oCelFor = oPlan.getCellRangeByName( "C1" )

    ' Verificar se a cél. está na col. A 
    If nCol = 0 Then
        vCelB = oPlan.getCellByPosition( 1,nLin ).Value

        ' Inserir o ValorFormula na col. C se a col. B não estiver vazia    
        If vCelB <> 0 Then
            oDestino = oPlan.getCellByPosition( 2,nLin )
			Call InserirValorFormula(oControl, oCelFor, oDestino )
            oControl.Select( oCelula )
        End Sub
    End If 

    ' Verificar se a cél. está na col. B 
    If nCol = 1 Then
        vCelA = oPlan.getCellByPosition( 0,nLin ).Value

        ' Inserir o ValorFormula na col. C se a col. A não estiver vazia        
        If vCelA <> 0 Then
            oDestino = oPlan.getCellByPosition( 2,nLin )
			Call InserirValorFormula(oControl, oCelFor, oDestino )
			oControl.Select( oCelula ) ' Fica
         End Sub
    End If
End Sub

Sub InserirValorFormula (oControlador, oCelFormula, oCelDestino)
	' Copiar e colar a fórmula
    oControlador.Select( oCelFormula )
	oFormula = oControlador.getTransferable()
    oControlador.Select( oCelDestino )
    oControlador.insertTransferable( oFormula )
    'Apagar o formato da célula que veio com a fórmula
    oCelDestino.clearContents( 32 )
    ' Converter a fórmula em valor na célula
    ' Exclua ou comente as duas linhas abaixo para que na célula
    ' fique a fórmula
    v = oCelDestino.Value
    oCelDestino.Value = v
End Sub

Acredito que seja o mais próximo que posso chegar do que você pretente.

Atte,
Grafeno

1 Like