小弟我想自定义一种公式,然后存在字段里
调用的时候调出来
但不知道要怎么实现
比如我定义的公式 M=(长+0.5)*(宽+0.1)*(高+0.2)
取出的时候(长+0.5)*(宽+0.1)*(高+0.2)
要怎么赋值给'长','宽','高'呢,且让他们相乘,得到结果

解决方案 »

  1.   

    使用系统的脚本引擎:====转贴一位高手写的(不好意思,名字忘了)====//////////// TParserEdit for Microsoft scriptControl ////////////
    // version 1.0
    // Author :s.f.
    // Date : 2004/3/25
    /////////////////////////////////////////////////////////////////unit uParserEdit;interfaceuses
      Windows,SysUtils, Variants, Classes, ComObj, StdCtrls;
    type
      TParserEdit = class(TEdit)
      private
        function getEvaluatedVariant: Variant;
      public
        property TextValue: Variant read getEvaluatedVariant;
      end;procedure Register; //这里可以注解掉,不注册为静态组件,需要动态建立
    implementationprocedure Register;                     //不注册请注解该过程
    begin
      RegisterComponents('IBSSoft', [TParserEdit]);
    end;function TParserEdit.getEvaluatedVariant: Variant;
    var
      Parser            : OleVariant;
      Tls               : TStrings;
      Code              : string;
    begin
      Code := Text;
      try
        Parser := CreateOLEObject('ScriptControl');
        try
          try
            Parser.Language := 'VbScript';
            Parser.AllowUI := TRUE;
            Result := Parser.Eval(Code);
          except
            Tls := TstringList.Create;
            try
              with Tls do
              begin
                Add('错误号:' + inttostr(Parser.Error.Number));
                Add('源:' + Parser.Error.Source);
                Add('描述:' + Parser.Error.Description);
                Add('行:' + intToStr(Parser.Error.Line) + ',列:' +
                  Inttostr(Parser.Error.Column));
                Add('代码:' + Parser.Error.Text);
                Add('帮助文件:' + Parser.Error.helpFile);
                Add('帮助主题:' + inttostr(Parser.Error.HelpContext));
              end;
              MessageBox(getforegroundwindow, pchar(Tls.Text), '执行错误',
                mb_ok or mb_IconError);
            finally
              tls.free;
            end;
          end;
        finally
          Parser := null;
        end;
      except
        MessageBox(getforegroundwindow, 'Com 对象错误', '无法解析', mb_ok or
          mb_IconError);
      end;
    end;
    end.
    /////////////测试窗体调用/////////////
    //1.注册为组件
    //2.加入该组件到form
    //3.修改ParserEdit1的text内容为 10*(1+2)+20
    //4.放个button 并编写OnClick事件
    //////////////////////////////////procedure TForm1.Button1Click(Sender: TObject);
    begin
      showmessage(String(ParserEdit1.TextValue));  //取回结果
    end;
      

  2.   

    把'长','宽','高'作为变量,赋值后再运算;
    function cubecount(l,w,h:real):real;
    begin
    result := (l+0.5)*(w+0.1)*(h+0.2);
    end;
      

  3.   

    to: cosmart(CoolSmart) 
    这样的话,那我定义的公式,存在字段里了
    要怎么联系起来?
      

  4.   

    建议你还是在字段里存放公式的名称吧,当用户调用完后再做名称对应调出相应的公式。
    比如将公式(如果你有很多)存放成ini文件的格式呀,ini本身就是名-值对称的,也就是可以变成你的公式名-公式对应的。
      

  5.   

    >>M=(长+0.5)*(宽+0.1)*(高+0.2)
    >>我调用出来了,长宽高要怎么赋值啊公式定义中的变量“长、宽...”最好采用特殊的标记法,
    比如: M=(@长+0.5)*(@宽+0.1)*(@高+0.2) 运算时先做字符串替换,再用我上面贴的脚本引擎“执行”这个字符串
      

  6.   

    先把公式取出来,
    再用字符串替换,
    再用SQL语句执行!
      

  7.   

    变量替换成数值: AnsiReplaceStr()函数可以。将替换后的字符串送到编译器里执行就可以了。如:AnsiReplaceStr('M=(长+0.5)*(宽+0.1)*(高+0.2)','长','20'),替换后就变成M=(20+0.5)*(宽+0.1)*(高+0.2),将替换后的字符串送到编译器里执行就可以了。
      

  8.   

    是啊,先替换成数值,然后往scriptcontrol里送,很简单的
      

  9.   

    指点一下吧scriptcontrol,要怎么用,谢谢
      

  10.   

    select 长,宽,高,(长+0.5)*(宽+0.1)*(高+0.2) as M from Table
      

  11.   

    同意楼上的,select 长,宽,高,(长+0.5)*(宽+0.1)*(高+0.2) as M from Table
    就可以了(如果你用的数据库的话,就是说可以让数据库完成相关的简单计算功能)
      

  12.   

    呵呵,想强大的就用
    RemObject或IFPS 3简单的参考http://dev.csdn.net/Develop/article/12/12464.shtm
    灵活运用Format和StringReplace函数就能做到了
      

  13.   

    Ms的scriptcontrol不支持复杂表达式的
    但我写的完全支持三角函数那些复杂的,所以应用面更广,最重要还是纯Native PAS代码,不需要ActiveX的支持把那个DLL该写为Unit就OK了
      

  14.   

    var
      Parser            : OleVariant;
      Tls               : TStrings;
      Code              : string;
    begin
      //先替换成数值,假设变成(20+0.5)*(10+0.1)*(20+0.2)  Code := '(20+0.5)*(10+0.1)*(20+0.2)';
      try
        Parser := CreateOLEObject('ScriptControl');
        try
            Parser.Language := 'VbScript';
            Parser.AllowUI := TRUE;
            Result := Parser.Eval(Code);
        except
          Tls := TstringList.Create;
          try
            with Tls do
            begin
                Add('错误号:' + inttostr(Parser.Error.Number));
                Add('源:' + Parser.Error.Source);
                Add('描述:' + Parser.Error.Description);
                Add('行:' + intToStr(Parser.Error.Line) + ',列:' +
                  Inttostr(Parser.Error.Column));
                Add('代码:' + Parser.Error.Text);
                Add('帮助文件:' + Parser.Error.helpFile);
                Add('帮助主题:' + inttostr(Parser.Error.HelpContext));
            end;
            MessageBox(0, pchar(Tls.Text), '执行错误',
                mb_ok or mb_IconError);
          finally
            tls.free;
          end;
        end;
      except
        MessageBox(0, 'Com 对象错误', '无法解析', mb_ok or
          mb_IconError);
      end;
    end;
      

  15.   

    要将‘长’、‘宽’、‘高’替换为数值不难吧?
    最直接的办法:搜索字符串“(长+0.5)*(宽+0.1)*(高+0.2)”
    遇到‘长’、‘宽’、‘高’字符时就进行替换啊。至于计算嘛,简单的办法就是用数据库本身的计算功能,一条SQL就搞定了。若想做得灵活强大些,可以用《编译原理》中最经典的“算符优先算法”,对字符串表达式进行解释和计算。
      

  16.   

    我帮邦总结一下(我来帮助邦兄总结一下,不要以为是在打铁):
    1.邦兄的问题身处数据库领域,其实完全可以采用SQL语句的方法,不知邦兄为何迟迟不表明立场,让大家又是脚本引擎又是编译器的。
    2.使用数据库的方法操作步骤如下:
    ⑴取出公式;
    ⑵将公式回显给用户,用户可以采用任何方式提交数据,比如使用最普通的TEdit组件;
    ⑶将用户输入的数据替换掉公式中的相应字符或字符串;
    ⑷送回数据库执行SQL语句,取出结果。
    ==注意==类似于:
    SELECT 1 + 2
    这样的SQL语句数据库依然是能够处理的并且可以返回结果,不信你可以试试。既然这样,你就可以将刚才替换了用户输入的数值的新的公式字符串送入数据库中执行,从而达到了你的目的。