Array
(
)

Operar uma Fórmula

Susi
   - 29 jan 2006

Olá colegas,

Tenho uma tabela de produtos com os seguintes campos: CODPRO,NOMPRO,UNIPRO e FORMULA.

Os 3 primeiros nem preciso comentar, porém o campo FORMULA é preenchido com algumas fórmulas, assim:
H*L-(H1/2)/4
H/2*4
H2*5+100
(5+H1)/4+(H/H3)

Onde H, L, H1,H2 e H3 são variáveis que serão substituidas por valores que serão informados na hora do orçamento.

Em Clipper, a solução é simples e rápida. Ex:
H1:=0
H2:=0
H3:=0
L:=0
MFORMULA:=´H1/2*H2/H3+L´
H1:=10
H2:=4
H3:=5
L:=7
? &MFORMULA

O resultado final será 11, pois com o comando ´&´ o Clipper não olhará MFORMULA como uma string e sim olhará para o conteúdo das letras da string que por acaso são variáveis previamente criadas e preenchidas.

Como fazer isto em Delphi? Existe alguma função?

Aguardo ajuda.


Susana


Aroldo Zanela
   - 30 jan 2006

Colega,

O Delphi é uma linguagem compilada e não pseudo-compilado como o Clipper, consequentemente, não consegue fazer macro-expansão/compilação em tempo de execução (nativamente). Entretanto, existem diversos componentes especializados para suprir essa necessidade, entre eles, o mais comum é jvInterpreterProgram do pacote JediVCL.

Veja exemplos aqui: http://homepages.borland.com/jedi/jvcl/JvInterpreter.htm


Massuda
   - 30 jan 2006

Algumas formas possíveis para calcular expressões/fórmulas:[list:06310c705a][*:06310c705a]Nesta [url=http://www.torry.net/pages.php?id=307]página[/url] do [url=http://www.torry.net/]Torry.net[/url] tem alguns componentes que são capazes de analisar e avaliar expressões/fórmulas.[*:06310c705a]Na [url=http://homepages.borland.com/jedi/jcl/]JCL[/url] (Jedi Code Library) tem uma unit chamada JclExprEval onde você encontrará as classes TEvaluator e TCompiledEvaluator[*:06310c705a]Para uma solução mais sofisticada, tem o [url=http://www.remobjects.com/page.asp?id={9A30A672-62C8-4131-BA89-EEBBE7E302E6}]Pascal Script[/url]; com ele você poderia escrever pequenos scripts ao invés de fórmulas para fazer os cálculos[/list:u:06310c705a]Precisa dar uma boa olhada no código fonte (em especial, no caso do JCL) e (se tiver) nos demos para entender como funciona.

A maior dificuldade é ver como encaixar isso no seu código; como isso depende do que você tem, é difícil dar um exemplo de uso.


Susi
   - 30 jan 2006

Olá...

Valeu pelas dicas, Aroldo e Massuda...

Estou pesquisando sobre o JVCL...

Meu caso é o seguinte:

Estou desenvolvendo um software de uma fábrica de esquadrias, onde
cada modelo de janela, por exemplo, tem determinadas características.
Dependendo da característica e do perfil, é gerada uma fórmula para calcular a quantidade de material utilizado.
Essas fórmulas são padrão da ALCOA, só que para cada tipo de janela/caracterísitcas/perfil e acessórios utilizados é aplicada uma fórmula diferente...Assim, por exemplo, em um só modelo de janela posso ter mais de 30 fórmulas diferentes...
Tenho uma tabela de cadastro das fórmulas, onde o operador entrará com cada uma delas a medida que for surgindo a necessidade.
Ora... até aí tudo bem...
Só que é armazenado em string...e como o exemplo mais acima em clipper, preciso que na hora de orçar funcione como uma fórmula, substituindo os valores digitados e executando o cálculo...

Ex, de fórmulas: H3-57
(L-180,4):4
[(L+H)x2]:500+4 ,onde H, H3 são alturas e L é o comprimento

Mais alguma sugestão , ficarei grata...

Um abraço,

Susana


Apontador
   - 30 jan 2006

analisei o seu problema e desenvolvi um código simples, por enquanto em pascal, analise e veja se é mais ou menos isso que procura:
descrição: ele recebe uma string digitada do teclado, aloca em tempo real variáveis p/ cada elemento da stgring separada por ´()´ ou sinais operacionais, pede q vc escolha uma variável (isso pode ser descartado no caso de implantação em um db), e calcula a expressão algébrica.

detalhe mais importante, como tudo o que faço procura ser ilimitado, tb esse protótipo é, ele trabalha c/ endereçamento direto da memória (ponteiros) o que permite que a expressão algébrica digitada seja infinita (desde que haja memória primária e virtual livre suficiente no pc).

espero ter ajudado.

se for mais ou menos isso que vc está procurando p/ o seu db, podemos conversar p/ mim lhe fornecer uma amostra, ou até mesmo o código...
t+

e caso concorte em receber uma amostra, me diga como fazer, pq é o meu primeiro dia aqui neste fórum[/img]


Massuda
   - 30 jan 2006

Um pequeno exemplo, baseado no JclExprEval...#Código

uses
SysUtils, JclExprEval, Dialogs;
...
var
evaluator: TEvaluator;
L: Double;
H: Extended;
begin
evaluator := TEvaluator.Create;
try
evaluator.AddVar(´L´, L);
evaluator.AddVar(´H´, H);

L := 3.5;
H := 0.7;

ShowMessage(Format(´TEvaluator: ¬.4g´,
[evaluator.Evaluate(´((L + H) * 2) / 500 + 4´)]));
finally
evaluator.Free;
end;
end.



Susi
   - 31 jan 2006

Olá,

Agradeço o empenho do Apontador.... brigadão mesmo, mas já consegui resolver o problema com o exemplo do Massuda...

Funcionou perfeitamente...

Sou principiante em Delphi/Firebird e estou aprendendo muito com o pessoal aqui do Forum...

Um abraço a todos, e até a proxima dúvida :D :D :D

Susana


Rodc
   - 31 jan 2006

Mesmo que você já esteja usando outra solução, resolvi postar para ajudar futuros programadores. :)

Tive este problema também, e não posso comprar componentes. Eu uso banco de dados SQLite e resolvi meu problema assim:
Tenho uma string com a expressão: ´[IDADE] * (12 + [TAMANHO])´;
Troco o texto [IDADE] e [TAMANHO] pelo valor correspondente usando StringReplace().
Executo o SQL ´SELECT *expressão* AS RETORNO FROM TESTE´. Onde *expressão* é a expressão é o texto trocado, por exemplo ´21 * (12 + 1.75)´. E a tabela TESTE tem apenas um registro.
Depois é só pegar o valor do campo RETORNO contendo o resultado da expresão.
Sei que o Oracle tb faz isto, talvês Firebird também.