Formulas matematicas em Realtime

12/02/2010

Boa Tarde,Como faço para executar formulas matemáticas em tempo de execução ? Explicando: Em uma tela existem determinados campos com seus respectivos valores, estes valores compõem a base de calculo de outros valores e assim por diante. A questão é que fixar estas formula direto no código seria fácil, mas estas formulas podem variar infinitamente. Dependendo de diversas características do cliente, por isto quero saber como fazer cálculos utilizando campos de um dataset e formulas editáveis pelo usuário. Exemplo: Para obter o valor total da nota fiscal seria utilizado a seguinte formula na empresa “A” Valor total da nota =Valor dos Produtos + Frete Para obter o valor total da nota fiscal seria utilizado a seguinte formula na empresa “B” Valor total da nota =Valor dos Produtos + Frete – Impostos + 50,00 Para obter o valor total da nota fiscal seria utilizado a seguinte formula na empresa “C” Valor total da nota =Valor dos Produtos + Frete – Impostos + Custos Operacionais   Sabendo que todos os campos utilizados são campos de um dataset, sendo utilizados na formula ou não dependendo de cada caso. podendo ser tambem utilizados misturados a formula valores fixos (Ex: 50,00 utilizados na formula da Empresa "B")
  Fico no aguardo Jorge Krone
Jorge Silva

Jorge Silva

Curtidas 0

Respostas

Wesley Yamazack

Wesley Yamazack

12/02/2010

Olá amigo,
   O que você pode fazer é criar functions no seu banco de dados, com parametros e passar para elas os respectivos valores, mas assim teria que ter uma formula para cada empresa, e de sua aplicação executar estas functions. Qual BD você usa ? Sabe criar functions no seu BD ?
  Ou então criar uma DLL com as formulas, e apenas consumir de sua aplicação, onde qualquer alteração que você tenha de fazer, basta atualizar na DLL, e enviar a mesma para seu cliente.
  Isso lhe ajudaria ?


Um abraço

Wesley Y
GOSTEI 0
Jorge Silva

Jorge Silva

12/02/2010

Boa Noite Wesley, Na verdade não, pois toda vez teria que ter uma intervenção minha para criar uma formula para um resultado que pode ser calculado de infinitas formas. Não quero fazer via banco, pois alem ficar dependente intervenção minha vou ficar vinculado a um banco, por isso não faço nada via banco, só via aplicação.
A meta principal e que o usuário defina como seus valores sejam calculados, digitando a formula e salvando em uma tabela, esta formula vai ser utilizada para chegar a um determinado resultado. Podemos tomar como idéia de exemplo uma expressão SQL que digitamos em um TEdit e depois executamos via ComandText  de um TClientDataSet e obtendo o resultado desta expressão tudo em tempo de execução. Esta funcionalidade vai ser utilizada praticamente em toda a aplicação para diversos cálculos em diversas telas e se ficar dependendo de um programador ou DBA para toda alteração o processo fica amarrado, estas formulas tem que ficar como uma parametrização simples para o usuário final. A questão é como vincular um texto/valor de um campo ao códigos sem fixar uma quantidade de parâmetros ou operadores pois os campos podem ser somados, subtraidos, divididos ou multiplicados e o resultado ser salvo em outro campo.Qualquer duvida é só falar.
GOSTEI 0
Jorge Silva

Jorge Silva

12/02/2010

Em anexo uma tela exemplo.

Neste caso utilizei os valores 01 e 02 igorando o 03 e ainda inclui um valor fixo (10) subtraido da formula.

resumido seria um esquema assim.
GOSTEI 0
Wesley Yamazack

Wesley Yamazack

12/02/2010

Olá amigo,
  Vou precisar de um tempo para bolar uma rotina destas ok ? Quanto a imagem não apareceu aqui não, teria como mandar novamente?
    Pelo que estou vendo você quer fazer um esquema tipo Excel, certo ?
    A1 = Soma(a2:a9)+10*B7. Seria isso?

Um abraço

Wesley Y
GOSTEI 0
Jorge Silva

Jorge Silva

12/02/2010

 Grande Wesley,

A1 = Soma(a2:a9)+10*B7

É Exatamente isso em vez de celulas seriam os valores dos campos do DataSet e as operações seriam as basicas(*-+/), neste caso o "A1" Seria a variavel a ser alimentada.

é isso mesmo entendeu a ideia é transferir a resposabilidade da formula para o usuario final. Beleza!!!



GOSTEI 0
Wesley Yamazack

Wesley Yamazack

12/02/2010

Olá amigo, peço que aguarde mais um pouco, pois estou desenvolvendo uma solução para ti.   UM abraço   Wesley Y
GOSTEI 0
Jorge Silva

Jorge Silva

12/02/2010

Beleza Wesley,

Qualquer duvida é só falar

Jorge
GOSTEI 0
Jorge Silva

Jorge Silva

12/02/2010

Boa Tarde Wesley,

Como está com o aplicativo ?
GOSTEI 0
Wesley Yamazack

Wesley Yamazack

12/02/2010

Olá amigo,
   Vou te falar que esta complicado fazer isso, teria como você me mandar um exemplo, do que exatamente você quer, pois achei que fazendo igual ao excel, seria facil, mas esta muito complicado. Não teria como "amarramos" alguma coisa, me manda ai um exemplo pra ficar mais facil.

 Um abraço

Wesley Y
GOSTEI 0
Jorge Silva

Jorge Silva

12/02/2010

Wesley,

Eu estava procurando se existe uma função para transformar string em parametro que pode-se se lido pelo codigo fonte mas não encontrei.

exemplo

Em um Tedit digitamos: VTotalItens + VFrete + VSeguro - 10


no codigo teria declaradas todas as variaveis possiveis

Var
   XFormula, VTotalItens, VFret, VSegur, LBaseCalculo: String;

Begin
   VTotalItens:=strtoint(Edit2.text);
   VFrete :=strtoint(Edit3.text);
   VSeguro :=strtoint(Edit4.text);


XFormula:=Edit1.text; {Neste momento converter o conteudo do edit1 em formula que seria lido no codigo}


LBaseCalculo:=XFormula; {Onde XFormula seria: VTotalItens + VFrete + VSeguro - 10}

end.


Como no edit1 já estaria todos os nomes das variaveis declaradas a serem utilizadas e as operações matematicas  seria como um typecast ou uma conversão. tipo um StrToCodigo ou coisa parecida.

Deu para pegar a ideia ? o problema a ser resolvido é só fazer o sistema entender uma string como parte do código e executa-la.

fico no aguardo
GOSTEI 0
Jorge Silva

Jorge Silva

12/02/2010

Bom Dia Wesley,

Tem boas noticias pra mim ?

Jorge
GOSTEI 0
Wesley Yamazack

Wesley Yamazack

12/02/2010

Olá amigo, não venho trazendo boas noticiais, andei vendo possibilidade, conversando com a galera, e levantei algumas questões aqui para lhe falar.

   Fazer o sistema entender uma string como parte de código é difícil, porque quando vc compilar sua aplicação tudo é transformado de ObjectPascal para Assembler .
   O que você quer é complexo, não acho que haja uma solução muito simples para isso, mas vamos a algumas sugestões:
    Permitir o usuário digitar a fórmula num campo aberto, por exemplo VALOR_MATERIAIS + IMPOSTO + 50 Depois você iria ter que interpretar essa fórmula percorrendo toda ela e identificando os operadores para realizar as operações matemáticas. Nesse caso você tem o risco do usuário fazer besteira e digitar o nome de um campo errado, comprometendo seu cálculo.
    Você pode fornecer para o usuário uma interface para montagem das suas fórmulas, por exemplo, exibe um listBox com as possíveis variáveis e outro com os possíveis operadores e o usuário vai clicando duas vezes em cada um e a medida que ele clica você vai adicionando na fórmula. Nesse caso você também terá que ter a interpretação da fórmula para identificação dos operadores
quanto aos campos seriam só passar no FieldByName do dataset, o campo da fórmula
     No caso 2 você você ganha em segurança pois evita que o usuário digite fórmulas mirabolantes que o sistema nção esteja preparado ou digite campos e operadores errados
     Há de se lembrar ainda que se houver a possibilidade de inclusão de alíquotas, percentuais, valores, vai aumentar a complexidade destas situações, porém não vejo como fazer o que você deseja de outra forma que não seja a leitura da fórmula, interpretação da mesma para posterior cálculo
     Outra complexidade que precisa ser analisada é a ordem de execução, primeiro multiplicação, depois soma, além de possíveis parênteses na fórmula
     A forma de armazenar isso no banco vai variar de acordo com suas possibilidades de fórmula
        se vai ser por usuário
        por empresa
        por filial
       por contrato
    É complexo mas é possível
    E infelismente não vejo outra forma senão esta, armazendando a fórmula e interpretando a mesma quando for realizar o cálculo.

Um abraço

Wesley Y

GOSTEI 0
Jorge Silva

Jorge Silva

12/02/2010

Fazer o sistema entender uma string como parte de código é difícil, porque quando vc compilar sua aplicação tudo é transformado de ObjectPascal para Assembler .

A questão de transformar String para código foi só uma idéia, uma possibilidade, pois a formula não pode nem deve ser inserida no momento da compilação, mas foi só uma maneira de ilustrar

   O que você quer é complexo, não acho que haja uma solução muito simples para isso, mas vamos a algumas sugestões:
    Permitir o usuário digitar a fórmula num campo aberto, por exemplo VALOR_MATERIAIS + IMPOSTO + 50 Depois você iria ter que interpretar essa fórmula percorrendo toda ela e identificando os operadores para realizar as operações matemáticas. Nesse caso você tem o risco do usuário fazer besteira e digitar o nome de um campo errado, comprometendo seu cálculo.
    Você pode fornecer para o usuário uma interface para montagem das suas fórmulas, por exemplo, exibe um listBox com as possíveis variáveis e outro com os possíveis operadores e o usuário vai clicando duas vezes em cada um e a medida que ele clica você vai adicionando na fórmula. Nesse caso você também terá que ter a interpretação da fórmula para identificação dos operadores

A questão de erros do usuário é quase certa, mas contornável, pois a responsabilidade seria do próprio usuário e as correções seriam dadas em forma de suporte, a interface para criação de formulas já é a idéia inicial que não foi exposta para não entrar no mérito de duas aplicações uma para escrever e outra para ler, mas lógico que vai ser criado um gerador de formulas para minimizar os erros.

quanto aos campos seriam só passar no FieldByName do dataset, o campo da fórmula
     No caso 2 você ganha em segurança pois evita que o usuário digite fórmulas mirabolantes que o sistema não esteja preparado ou digite campos e operadores errados
     Há de se lembrar ainda que se houver a possibilidade de inclusão de alíquotas, percentuais, valores, vai aumentar a complexidade destas situações, porém não vejo como fazer o que você deseja de outra forma que não seja a leitura da fórmula, interpretação da mesma para posterior cálculo
     Outra complexidade que precisa ser analisada é a ordem de execução, primeiro multiplicação, depois soma, além de possíveis parênteses na fórmula
     A forma de armazenar isso no banco vai variar de acordo com suas possibilidades de fórmula
        se vai ser por usuário
        por empresa
        por filial
       por contrato
    É complexo mas é possível
    E infelizmente não vejo outra forma senão esta, armazenando a fórmula e interpretando a mesma quando for realizar o cálculo.

Armazenar a formula é a exatamente a intenção, pois seria inviável toda vez para realização de um calculo redigitar a formula toda, o vinculo vai ser feito de diversas formas vamos tomar como base a seguinte: preencho uma tela com valores(ex: Nota Fiscal), no momento do calculo em um dbLookupcombobox escolho a formula que quero usar, estas formulas já foram cadastradas pelo usuário anteriormente e armazenadas em uma tabela.

agora como seria interpretar Esta formula salva em um campo e gerar um resultado a partir dela.
me dê um exemplo simples que depois programamos as mais complexas. na verdade esta funcionalidade é só uma entre muitas em um sistema bem maior

Obrigado pela atenção.

Jorge
 
GOSTEI 0
Jorge Silva

Jorge Silva

12/02/2010

Para ilustrar uma tela que criei para teste



Abaixo uma tela utilizada em um ERP produzido e amplamente utilizado



Onde:
Código seria a primary key da formula;
algumas paramentrizações;
o campo formula onde seriam indicados os calculos a serem feitos

note que os valores são indicados por códigos, Exemplo: &1018, &1027

em um determinado momento o codigo da formula (Ex:100,101,102)é indicado e realizada a interpletação da formula gerando um resultado.






GOSTEI 0
Wesley Yamazack

Wesley Yamazack

12/02/2010

Olá amigo,
   Estou analisando seu chamado, porém devido a complexidade estou levando um pouco de tempo, em breve retornarei com uma resposta, peço que aguarde.

Um abraço

Wesley Y
GOSTEI 0
Jorge Silva

Jorge Silva

12/02/2010

Ok Wesley,

Fico no aguardo

Grato pela atenção.

Jorge

GOSTEI 0
Wesley Yamazack

Wesley Yamazack

12/02/2010

Olá amigo, vou lhe passar algumas dicas aqui..

Para interpretar a fórmula vc precisa percorrer a mesma procurando por caracteres + - * /, além de parenteses
estes caracteres serão os delimitadores, sendo assim, voce teria um while nessa formula percorrendo cada caracter da mesma
e verificando se o caracter é um dos delmitadores definidos, se não for, precisamos armazenar o caracter em uma variavel para formar o nome da variável da fómula.
se um dos delimitadoresf or encontrado,  o sistema faz a lógica necessária para aquele operador. Veja se você consegue interpretar e desenvolver alguma ideia sobre estas dicas.


Desculpe a demora, mas é que este mes estamos com muitos chamdos.

Um abraço

Wesley Y
GOSTEI 0
Jorge Silva

Jorge Silva

12/02/2010

Wesley,

Na verdade indentificar os Delimitadores/Operadores  e os valores em um loop não é problema, o problema é somente: Como pegar estes valores e operadores e executar. Somente isso, Favor envie um exemplo.
GOSTEI 0
Wesley Yamazack

Wesley Yamazack

12/02/2010

Olá amigo,
  Se você esta achando tranquilo fazer os operadores no loop, o próximo passo seria você fazer as posiveis funções que existam no seu código. Exemplo para somar;

 if( vOperador = "+") then
begub
  vTotal := vTotal + cds.fieldByname(vNomeCampo).asFloat;
end;

Um abraço

Wesley Y

GOSTEI 0
Jorge Silva

Jorge Silva

12/02/2010

Wesley,

Não consegui pegar a ideia do if seria um para cada operador ?

GOSTEI 0
Wesley Yamazack

Wesley Yamazack

12/02/2010

Olá amigo,
   Você terá que fazer isso para cada operador sim.

Abs

Wesley Y
GOSTEI 0
Jorge Silva

Jorge Silva

12/02/2010

Wesley,

Vou fazer uns testes. 
GOSTEI 0
Wesley Yamazack

Wesley Yamazack

12/02/2010

Blz amigo, vai mandando o código fonte para eu te ajudar também se precisar.

Um abraço

Wesley Y
GOSTEI 0
Wesley Yamazack

Wesley Yamazack

12/02/2010

Olá amigo,
   Consegui algum progresso ?

Um abraço

Wesley Y
GOSTEI 0
Jorge Silva

Jorge Silva

12/02/2010

Boa tarde Wesley,

Ainda não consegui terminar o teste, pois estou empacado com outro problema no mesmo projeto com o ApplyUpdates que não está funcionando.

pesso só mais um pouco de paciência.

Grande abraço

Jorge



GOSTEI 0
Wesley Yamazack

Wesley Yamazack

12/02/2010

Blz amigo, fico no aguardo então

Um abraço

Wesley Y
GOSTEI 0
Wesley Yamazack

Wesley Yamazack

12/02/2010

Olá amigo, consegui algum avanço ? Podemos fechar o chamado ?

Um abraço

Wesley Y
GOSTEI 0
Devmedia

Devmedia

12/02/2010

Jorge,
por falta de retorno estamos encerrando o seu chamado. Caso tenha mais dúvidas sobre o assunto é só postar aqui mesmo que o consultor voltará a lhe atender.
GOSTEI 0
POSTAR