Formel in einem Textfeld berechnen lassen

17. Februar 2009 22:19

Hallo zusammen,

heute wurde ich gefragt, ob es irgendwie möglich ist, eine mathematische Formel (welche in einem Textfeld steht) berechnen zu lassen.
Z. B.: 2 / 125 + 13 * 27

Ich bin mir ziemlich sicher, dass es irgendwo im NAV-Standard bereits eine Funktion/Codeunit gibt, welche soetwas kann, leider stehe ich zur Zeit scheinbar so auf dem Schlauch, dass ich noch nicht einmal ansatzweise weiß, wo ich suchen soll.

Kann mir hier zufällig jemand auf die Sprünge helfen?

Optimal wäre natürlich, wenn diese Funktion die mathematischen Grundregeln (Punkt- vor Strichrechnung, Klammerung, ...) beherrschen würde.
Absolut perfekt wäre es sogar, wenn diese Funktion auch noch Potenzen errechnen könnte.
Z. B.: 2^8 / (125 + 13) + 7 * 27
Man wird ja wohl noch Träume haben dürfen. ;-)

Re: Formel in einem Textfeld berechnen lassen

18. Februar 2009 09:18

Mensch Timo,
das hab ich dir doch gestern sofort nach unserem Gespräch geschickt ;-)
Des Rätsels Lösung:
Codeunit 8, Funktion EvaluateExpression.

Wer diese Funktion für seine eigene Zwecke missbrauchen will, muss sie etwas umstricken (= diese kopieren und ändern). Meine derzeitige Lösung sieht so aus:

Code:
Result := 0;

Expression := DELCHR(Expression,'<>',' ');
IF STRLEN(Expression) > 0 THEN BEGIN
  Parantheses := 0;
  IsExpression := FALSE;
  Operators := '+-*/^%';
  OperatorNo := 1;
  REPEAT
    i := STRLEN(Expression);
    REPEAT
      IF Expression[i] = '(' THEN
        Parantheses := Parantheses + 1
      ELSE
        IF Expression[i] = ')' THEN
          Parantheses := Parantheses - 1;
      IF (Parantheses = 0) AND (Expression[i] = Operators[OperatorNo]) THEN
        IsExpression := TRUE
      ELSE
        i := i - 1;
    UNTIL IsExpression OR (i <= 0);
    IF NOT IsExpression THEN
      OperatorNo := OperatorNo + 1;
  UNTIL (OperatorNo > STRLEN(Operators)) OR IsExpression;
  IF IsExpression THEN BEGIN
    IF i > 1 THEN
      LeftOperand := COPYSTR(Expression,1,i - 1)
    ELSE
      LeftOperand := '';
    IF i < STRLEN(Expression) THEN
      RightOperand := COPYSTR(Expression,i + 1)
    ELSE
      RightOperand := '';
    Operator := Expression[i];
    LeftResult := EvaluateExpression(LeftOperand);
    RightResult := EvaluateExpression(RightOperand);
    CASE Operator OF
      '^':
        Result := POWER(LeftResult,RightResult);
      '%' :
        IF RightResult = 0 THEN BEGIN
          Result := 0;
        END ELSE
          Result := 100 * LeftResult / RightResult;
      '*':
        Result := LeftResult * RightResult;
      '/':
        IF RightResult = 0 THEN BEGIN
          Result := 0;
        END ELSE
          Result := LeftResult / RightResult;
      '+':
        Result := LeftResult + RightResult;
      '-':
        Result := LeftResult - RightResult;
    END;
  END ELSE
    IF (Expression[1] = '(') AND (Expression[STRLEN(Expression)] = ')') THEN
      Result :=
        EvaluateExpression(COPYSTR(Expression,2,STRLEN(Expression) - 2))
    ELSE BEGIN
      EVALUATE(Result,Expression);
    END;
END;
EXIT(Result);


Die Funktion hab ich u.a. so abgeändert, dass sie keine Filter als Ausdruck berücksichtigt. Als Übergabeparameter ist nur "Expression" geblieben.

Wer Verbesserungspotenzial sieht, bitte melden. Die Umstrickung erfolgte nämlich spontan.

Re: Formel in einem Textfeld berechnen lassen

18. Februar 2009 10:31

Hallo Timo,

habe da vor kurzem was bei mibuso ausgegraben. Die Lösung ist noch ein wenig komfortabler, da Sie mit Variablen, Konstanten, und selbst definierten Funktionen (in C/AL) umgehen kann.

Gruß, Fiddi