Pessoal, Bom dia, gostaria de saber se é possível o usuário digitar uma formula em uma variável CHAR e depois calcular o resultado e mostrar em um campo DECIMAL. Exemplo: digitaria a fórmula: ((13+5)*(10/5)) Alguém tem um exemplo de como executar este procedimento ?
O @tcoutinho mostrou um exemplo de como usar query dinamica para simular formulas. http://www.4each.com.br/threads/calcular-fórmula-cadastrada.7239/#post-20776
Aqui uma variação baseada no exemplo do @tcoutinho PHP: /* Variáveis exigidas pelo programa */DEFINE VARIABLE resultadoDaFormula AS DECIMAL.DEFINE VARIABLE parametro AS DECIMAL EXTENT 10./* Temp-table para poder fazer a query rodar */DEFINE TEMP-TABLE ttDummy FIELD campo AS DECIMAL EXTENT 10.DEFINE QUERY ttDummy FOR ttDummy./* Variáveis para o exemplo apenas */DEFINE VARIABLE quantidade AS DECIMAL.DEFINE VARIABLE preco AS DECIMAL.DEFINE VARIABLE desconto AS DECIMAL.DEFINE VARIABLE resposta AS DECIMAL./* Para teste, temp-table com as fórmulas. Seria uma tabela do banco na realidade */DEFINE TEMP-TABLE ttFormulas FIELD id AS INTEGER FIELD nome AS CHARACTER FIELD formula AS CHARACTER FIELD expressao AS CHARACTER.CREATE ttFormulas.ASSIGN ttFormulas.id = 1 ttFormulas.nome = "Valor do Produto" ttFormulas.formula = "(quantidade * preço)" ttFormulas.expressao = "(campo[1] * campo[2])".CREATE ttFormulas.ASSIGN ttFormulas.id = 2 ttFormulas.nome = "Valor do Produto com desconto de 10%" ttFormulas.formula = "((quantidade * preço) - ((quantidade * preço) * 0.1))" ttFormulas.expressao = "((campo[1] * campo[2]) - ((campo[1] * campo[2]) * 0.1))".CREATE ttFormulas.ASSIGN ttFormulas.id = 3 ttFormulas.nome = "Valor do Produto com percentual do desconto informado pelo usuário" ttFormulas.formula = "((quantidade * preço) - ((quantidade * preço) * (desconto / 100)))" ttFormulas.expressao = "((campo[1] * campo[2]) - ((campo[1] * campo[2]) * (campo[3] / 100)))"./* As duas funções que são usadas para realizar o calculo */FUNCTION GetDecimal RETURNS LOGICAL (INPUT valor AS DECIMAL). resultadoDaFormula = valor. RETURN TRUE.END FUNCTION. /* GetDecimal RETURNS LOGICAL (INPUT valor AS DECIMAL) */FUNCTION calculaFormula RETURNS DECIMAL (formula AS INTEGER, parametros AS DECIMAL EXTENT 10). ASSIGN resultadoDaFormula = 0. FIND FIRST ttFormulas WHERE ttFormulas.id = formula NO-LOCK NO-ERROR. IF AVAILABLE ttFormulas THEN DO: CREATE ttDummy. ASSIGN ttDummy.campo = parametros. SESSION:NUMERIC-FORMAT = "American". QUERY ttDummy:QUERY-PREPARE("FOR EACH ttDummy WHERE DYNAMIC-FUNCTION( 'GetDecimal', " + ttFormulas.expressao + ") = TRUE"). SESSION:NUMERIC-FORMAT = "European". QUERY ttDummy:QUERY-OPEN(). QUERY ttDummy:QUERY-CLOSE. END. ELSE MESSAGE "Fórmula não cadastrada" VIEW-AS ALERT-BOX. RETURN resultadoDaFormula.END FUNCTION. /* calculaFormula RETURNS DECIMAL (formula AS INTEGER, parametros AS DECIMAL EXTENT 10) *//* Valor das variáveis de teste */ASSIGN quantidade = 2 preco = 3.2 desconto = 20. /* percentual de desconto *//* Passa os valores para os parâmetros da fórmula que se deseja calcular */parametro[1] = quantidade.parametro[2] = preco./* calcula o valor do produto, id=1 na tabela de fórmulas *//* chama a função de calculo passando o id da fórmula e a variável extent que possui os parâmetros para ela */resposta = calculaFormula(1,parametro).DISPLAY resposta LABEL "Valor do produto" WITH FRAME tela1 TITLE "Resultado" SIDE-LABELS./* Passa os valores para os parâmetroos da fórmula que se deseja calcular */ASSIGN parametro[1] = quantidade parametro[2] = preco./* calcula o valor do produto com desconto de 10%, id=2 na tabela de fórmulas */resposta = calculaFormula(2,parametro).DISPLAY resposta LABEL "Valor do produto com 10% desc" WITH FRAME tela2 TITLE "Resultado" SIDE-LABELS./* Passa os valores para os parâmetros da fórmula que se deseja calcular */ASSIGN parametro[1] = quantidade parametro[2] = preco parametro[3] = desconto./* Calcula o valor do produto com desconto informado pelo usuário, id=3 na tabela de fórmulas */resposta = calculaFormula(3,parametro).DISPLAY resposta LABEL "Valor do produto com desc informado" WITH FRAME tela3 TITLE "Resultado" SIDE-LABELS.