AX2012 XppCompiler create method动态创建方法并运行
在用友系列的软件中经常可以看到可配置的计算公式,AX中其实也有可配置的公式,如call center呼叫中心的欺诈Fraud rule的配置,AX后台可以根据配置规则,变量,条件来动态产生方法并执行,如下:
public static boolean executeRule(MCRUpSellRule _rule, RecId _salesLineRecId)
{
      str                     condition;
      str                     andOr;
      MCRUpSellVarRule        mcrUpSellVarRule;
      MCRUpSellVarRuleDetail  mcrUpSellVarRuleDetail;
      //BP Deviation Documented
      XppCompiler             xppCompiler;
      MCRFraudRule            mcrFraudRule;
      MCRUpSellRule           rule = _rule;
  new ExecutePermission().assert();
      // BP Deviation Documented
      xppCompiler = new xppCompiler();
      condition = "";
      andOr     = "";
      while select Operand, LeftParen, RightParen, ConditionName from mcrUpSellVarRuleDetail where mcrUpSellVarRuleDetail.RuleID == rule
      {
            switch (mcrUpSellVarRuleDetail.Operand)
            {
                  case MCRUpSellOperandType::None: andOr = "";      break;
                  case MCRUpSellOperandType::AND: andOr = ' && ';  break;
                  case MCRUpSellOperandType::OR: andOr = ' || ';  break;
            }
            condition = condition
                        + enum2str(mcrUpSellVarRuleDetail.LeftParen)
                        + 'MCRUpSellCrossSell::executeCondition('
                        + strfmt('%1', _salesLineRecId) + ', \''
                        + mcrUpSellVarRuleDetail.ConditionName + '\')'
                        + enum2str(mcrUpSellVarRuleDetail.RightParen) + andOr;
      }
      condition = 'boolean retstuff(){ return ' + condition + '; }';
      xppCompiler.compile(condition);
      if (xppCompiler.errorText() != "")
      {
            select firstOnly RecId from mcrUpSellVarRule
                where mcrUpSellVarRule.RuleID == rule;
             
            select firstonly RecId from mcrFraudRule
                  where mcrFraudRule.RuleId == rule;
            if (!mcrUpSellVarRule && !mcrFraudRule)
            {
                  error(strfmt("@MCR11882", rule));
            }
            else
            {
                
                  if (mcrFraudRule)
                  {
                        rule = MCRFraudRule::find(rule).RuleName;
                        error(strfmt("@MCR24889", rule, xppCompiler.errorText()));
                  }
                  else //the problem is with an upsellCrossSell Rule
                  {
                        error(strfmt("@MCR11883", rule, xppCompiler.errorText()));
                  }
           }
            return false;
        }
        return xppCompiler.execute();
  }
配置规则里的逻辑不复杂,下面例子说明,如果创建带参数的动态方法:
new ExecutePermission().assert();
  xppCompiler = new XppCompiler();
          condition = '';
  condition =     strFmt(this.Notes,
                          enum2int(curSettlement.PurchCoalIncentiveClaims),
                          num2str(curDetails.PurchQty,0,2,0,0),
                          num2str(curDetails.PurchPrice,0,2,0,0),
                          num2str(this.LoadPortValue,0,2,0,0),
                          num2str(this.UnLoadPortValue,0,2,0,0),
                          num2str(this.LowerLimit,0,2,0,0),
                          num2str(this.UpperLimit,0,2,0,0));
  xppCompiler.compile(condition);
          if (xppCompiler.errorText() != '')
                error(strfmt("@HVL1634",xppCompiler.errorText()));
          return xppCompiler.execute();
this.Notes的方法体如下,其中%1表示接收第一个参数.
public LineAmount executeFormula( )
{
      LineAmount      curLineAmount1,curLineAmount2;
      ; 
      if(%4 ==0)
      {
            curLineAmount1 = 0;
            curLineAmount2 = 0;
      }
      else
      {
	    curLineAmount1 = decRound((%4-%6)*decRound(%3/%6,3),2)*%2;
            curLineAmount2= (%4>=(%6-200) ? 0 : (%4-%6-200)*decRound(%3/%6,3))*%2;
      }    
      return decRound(curLineAmount1+curLineAmount2,2) ;
}
以下例子也可以参考
http://www.van-veldhuizen.eu/blog/2012/04/19/run-custom-code-microsoft-dynamics-ax-2012/
n previous versions we used the RunBuff() method to run configured scripts. This is not allowed when you run in CIL.
There is a simple work around as there is new class: XppCompiler
http://msdn.microsoft.com/en-us/library/xppcompiler.executeex.aspx
A small sample is shown below:
static void Job12(Args _args)
{
XppCompiler compiler = new XppCompiler();
source source = strFmt("anyType runMethod()\n{\n return %1\n}\n", 'today();');
;
compiler.compile(source);
test = compiler.execute();
}
AX2012 XppCompiler create method动态创建方法并运行的更多相关文章
- Python中使用type、metaclass动态创建方法和属性
		1: type() 我们知道动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个Person的class: class Person(obj ... 
- C#动态创建和动态使用程序集、类、方法、字段等
		C#动态创建和动态使用程序集.类.方法.字段等 分类:技术交流 (3204) (3) 首先需要知道动态创建这些类型是使用的一些什么技术呢?其实只要相关动态加载程序集呀,类呀,都是使用反射,那么动 ... 
- python-获取类名和方法名,动态创建类和方法及属性
		获取类名和方法名1.在函数外部获取函数名称,用.__name__获取2.在函数内部获取当前函数名称,用sys._getframe().f_code.co_name方法获取3.使用inspect模块动态 ... 
- silverlight依据json字符串动态创建实体类
		1.接收json字符串: //用JsonValue转换json字符串是为了之后获得json字符串的每行数据和每一列的列名 JsonValue jv = JsonValue.Parse(json); ... 
- C# 动态创建SQL数据库(二)  在.net core web项目中生成二维码  后台Post/Get 请求接口 方式  WebForm 页面ajax 请求后台页面 方法  实现输入框小数多 自动进位展示,编辑时实际值不变  快速掌握Gif动态图实现代码  C#处理和对接HTTP接口请求
		C# 动态创建SQL数据库(二) 使用Entity Framework 创建数据库与表 前面文章有说到使用SQL语句动态创建数据库与数据表,这次直接使用Entriy Framwork 的ORM对象关 ... 
- ASM(四) 利用Method 组件动态注入方法逻辑
		这篇继续结合样例来深入了解下Method组件动态变更方法字节码的实现.通过前面一篇,知道ClassVisitor 的visitMethod()方法能够返回一个MethodVisitor的实例. 那么我 ... 
- C#反射动态创建实例并调用方法
		在.Net 中,程序集(Assembly)中保存了元数据(MetaData)信息,因此就可以通过分析元数据来获取程序集中的内容,比如类,方法,属性等,这大大方便了在运行时去动态创建实例. MSDN解释 ... 
- odoo 动态创建字段的方法
		动态创建字段并非一个常见的的需求,但某些情况下,我们确实又需要动态地创建字段. Odoo 中创建字段的方法有两种,一种是通过python文件class中进行定义,另一种是在界面上手工创建,odoo通过 ... 
- js动态创建及移除div的方法
		本文实例讲述了js动态创建及移除div的方法.分享给大家供大家参考.具体实现方法如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ... 
随机推荐
- 二十五、JDK1.5新特性---枚举
			与上篇文章介绍的相同,本文也是介绍jdk 1.5出现的新特性,本文将介绍枚举的相关用法. 在jdk 1.5 之前.Java可以有两种方式定义新类型:类和接口.对于大部分面向对象来说.这两种方法看起来似 ... 
- C++ new和delete具体操作符是怎样的
			在C语言中,动态分配内存用 malloc() 函数,释放内存用 free() 函数.如下所示: int *p = (int*) malloc( sizeof(int) * 10 ); //分配10个i ... 
- python之编写三层菜单(第一天)
			作业三:多级菜单 三级菜单 可依次选择进入各子菜单 所需新知识点:列表.字典 针对此菜单程序的设计,使用了yaml格式的文本,由python对其内容进行解析为多重字典,然后对字典进行遍历,判断并输出三 ... 
- Core Data 使用映射模型
			Core Data 使用映射模型 如果新版本的模型存在较复杂的更改,可以创建一个映射模型,通过该模型指定源模型如何映射到目标模型. 创建映射模型,新建File, Core Data 选择Mappin ... 
- css3样式控制(鼠标滑过 显示标注信息)
			<div class="item"> <h1>A</h1> <div class="tooltip"> < ... 
- linux下打开、关闭tomcat,实时查看tomcat运行日志
			启动:一般是执行sh tomcat/bin/startup.sh 停止:一般是执行sh tomcat/bin/shutdown.sh脚本命令 查看:执行ps -ef |grep tomcat 输出如下 ... 
- C# 线程通信 一
			C#多线程通信 using System; using System.Collections.Generic; using System.Linq; using System.Text; using ... 
- angular的$scope
			angularJS是一个MVVM的前端js框架. $scope的作用是angular向视图(html)传递数据的通道,它不负责处理和操作数据.也就是说要想向视图传递数据的话,必须定义$scope变量. ... 
- Jquery页面初始化的4种方式
			<script src="Scripts/jquery-1.8.2.min.js"></script> <script type="text ... 
- python sys模块
			sy模块主要用于:解析器及环境 命令行参数 python xx.py xx1 xx2注:xx.py: sys.argv[0] 脚本名称 xx1 sys.argv[1] 第1个参数退出程序 sys.ex ... 
