SAP-ABAP:SAP基础数据校验工具开发系列博客(共5篇) 第二篇:校验规则引擎设计:实现可配置的SAP数据校验逻辑

SAP-ABAP:SAP基础数据校验工具开发系列博客(共5篇) 第二篇:校验规则引擎设计:实现可配置的SAP数据校验逻辑 SAP基础数据校验工具开发系列博客共5篇第二篇校验规则引擎设计实现可配置的SAP数据校验逻辑传统的主数据校验往往是“需求来了 → 开发改代码 → 传输请求 → 用户测试 → 上线”一个简单的校验逻辑调整也需要走完整的开发流程。如果校验规则有几十条、涉及多个模块硬编码方式的维护成本将成倍增加。本文介绍如何设计一个可配置的规则引擎将字段合法性、主数据关联关系、业务合规性三类校验逻辑从代码中抽离通过配置表实现低代码维护。同时讲解规则的版本管理、优先级调整机制让你告别频繁修改代码的困扰。一、为什么需要规则引擎1.1 硬编码校验的痛点在实际项目中我们经常遇到以下场景需求变化快物料组的取值范围每季度调整一次每次都要改代码。规则分散相同校验逻辑在不同事务码MM01、MM02、MM06等中重复编写容易遗漏。测试成本高任何规则调整都需要重新激活程序、传输请求。业务人员依赖IT业务无法自主调整规则只能排队等待开发。1.2 规则引擎的目标配置化将校验条件、提示信息、严重级别等存储在数据库表中修改一条记录即可生效无需激活程序。可扩展支持新增规则类型无需改动核心引擎代码。可管理提供规则的启用/停用、优先级控制、版本追溯。二、规则引擎整体架构规则引擎在工具中的位置如下图所示┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 数据获取模块 │────▶│ 规则引擎 │────▶│ 结果输出模块 │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ ┌──────┴──────┐ ▼ ▼ ┌────────────┐ ┌────────────┐ │ 规则配置表 │ │ 规则日志表 │ └────────────┘ └────────────┘核心组件规则解析器读取配置表动态生成校验条件。规则执行器遍历主数据逐条应用规则。结果收集器记录每条失败规则的详细信息主数据键值、规则ID、错误描述。三、规则配置表设计3.1 主规则表ZMD_RULE字段名类型说明示例RULE_IDCHAR10规则唯一编号ZMM_001OBJECT_TYPECHAR2主数据对象类型01物料02供应商03客户RULE_TYPECHAR1规则类型1字段格式2关联检查3业务合规RULE_NAMECHAR40规则名称物料号长度校验SEVERITYCHAR1严重级别E错误W警告I提示ENABLEDCHAR1是否启用X启用空停用PRIORITYNUMC2执行优先级数字越小越先执行10VALID_FROMDATS生效起始日期20260101VALID_TODATS生效截止日期99991231RULE_EXPRSTRING校验表达式见下文MATNR LENGTH 18ERROR_MSGCHAR100错误提示文本支持占位符物料号长度应为18当前为{1}3.2 规则类型与表达式设计为了便于配置我们设计了一套类自然语言的表达式语法由解析器转换为ABAP代码逻辑。类型1字段合法性校验验证单个字段的格式、取值范围、长度等。表达式格式字段名 运算符 期望值支持的运算符EQ、NE、GT、LT、GE、LE、LENGTH、REGEX正则、IN枚举。规则示例表达式说明物料号长度为18MATNR LENGTH EQ 18供应商税号格式为15位数字STCD1 REGEX ^[0-9]{15}$物料组属于指定集合MATKL IN 01,02,03类型2主数据关联关系校验验证当前主数据与其他表或同一表不同字段的关联是否有效。表达式格式EXISTS IN 表名 WHERE 条件规则示例表达式说明物料必须至少分配给一个工厂EXISTS IN MARC WHERE MATNR MATNRMATNR 会被替换为当前物料号供应商必须已维护采购组织EXISTS IN LFM1 WHERE LIFNR LIFNR AND EKORG 1000类型3业务合规性校验验证主数据的组合是否符合业务规则例如物料类型与物料组的匹配关系。表达式格式字段A 关系 字段B或自定义条件规则示例表达式说明物料类型为ROH时物料组必须为原料组IF MTART ROH THEN MATKL IN 001,002需要扩展语法客户行业必须与公司代码行业匹配INDUSTRY T001-BRANCH需要跨表为了简化实际开发中可以将复杂逻辑封装成函数模块在表达式中调用FUNCTION ZMD_CHECK_MATKL_BY_MTART四、规则解析与执行实现4.1 表达式解析器伪代码我们以最简单的字段长度校验为例展示解析逻辑。FORM parse_rule USING iv_expression TYPE string is_data TYPE any CHANGING cv_result TYPE abap_bool cv_msg TYPE string. DATA: lv_field TYPE string, lv_op TYPE string, lv_value TYPE string, lv_field_value TYPE string, lv_len TYPE i. 按空格分割表达式假设格式为 FIELD OP VALUE SPLIT iv_expression AT space INTO lv_field lv_op lv_value. 获取字段实际值通过动态分配 ASSIGN COMPONENT lv_field OF STRUCTURE is_data TO FIELD-SYMBOL(fs). IF sy-subrc 0. cv_result abap_false. cv_msg |字段{ lv_field }不存在|. RETURN. ENDIF. CASE lv_op. WHEN LENGTH. lv_len strlen( fs ). IF lv_op2 EQ AND lv_len lv_value. cv_result abap_false. cv_msg |长度应为{ lv_value }实际为{ lv_len }|. ENDIF. WHEN EQ... ENDCASE. ENDFORM.实际项目中可使用正则表达式解析更复杂的表达式或直接采用ABAP标准逻辑库。4.2 规则执行引擎FORM execute_rules USING iv_object_type TYPE char2 it_data TYPE STANDARD TABLE CHANGING ct_result TYPE zmd_result_t. DATA: lt_rules TYPE TABLE OF zmd_rule, ls_rule LIKE LINE OF lt_rules, ls_result LIKE LINE OF ct_result. 1. 获取启用的规则按优先级排序 SELECT * FROM zmd_rule INTO TABLE lt_rules WHERE object_type iv_object_type AND enabled X AND valid_from sy-datum AND valid_to sy-datum ORDER BY priority. 2. 遍历主数据 LOOP AT it_data ASSIGNING FIELD-SYMBOL(fs_data). 3. 遍历规则 LOOP AT lt_rules INTO ls_rule. 解析表达式执行校验 PERFORM parse_rule USING ls_rule-rule_expr fs_data CHANGING DATA(lv_pass) DATA(lv_msg). IF lv_pass abap_false. ls_result-rule_id ls_rule-rule_id. ls_result-object_key fs_data-key 需要根据主数据类型提取键值 ls_result-msg lv_msg. ls_result-severity ls_rule-severity. APPEND ls_result TO ct_result. ENDIF. ENDLOOP. ENDLOOP. ENDFORM.五、版本管理与优先级调整5.1 版本管理为了避免规则修改后影响正在运行的批量校验任务引入版本控制机制每次修改规则时不直接更新原记录而是新增一条记录RULE_ID不变VERSION自增。当前活动版本由IS_ACTIVE标志标识。批量校验任务启动时锁定当时的活动版本号后续执行使用该版本快照避免中途规则变化导致结果不一致。 规则表增加字段 VERSION NUMC4 版本号 IS_ACTIVE CHAR1 是否为当前活跃版本5.2 优先级调整PRIORITY字段控制执行顺序。建议前置规则基础格式校验如必填项优先级最高数字小。中间规则关联关系校验。后置规则复杂的业务逻辑校验。当一条记录违反高优先级规则如物料号为空时可以跳过后续规则减少无效计算。引擎支持STOP_ON_ERROR标志位配置。六、实战案例物料主数据校验规则配置6.1 需求物料号必须为18位字符。物料描述不能包含特殊字符!#$%。物料类型为ROH时物料组必须是001或002。物料必须分配至少一个工厂视图。6.2 配置记录RULE_IDRULE_TYPERULE_EXPRSEVERITYPRIORITYZMM_0011MATNR LENGTH EQ 18E10ZMM_0021MAKTX REGEX ^[^!#$%]*$E10ZMM_0033IF MTART ROH THEN MATKL IN 001,002E20ZMM_0042EXISTS IN MARC WHERE MATNR MATNRE156.3 优势体现当物料组范围从001,002扩展到003时只需修改ZMM_003规则的RULE_EXPR值保存后即时生效。新增加一批需要校验的物料类型如FERT只需复制ZMM_003规则调整条件即可。七、注意事项与最佳实践表达式安全性避免使用EVALUATE或动态编译ABAP代码防止SQL注入或性能问题。建议使用白名单函数。性能优化对于EXISTS IN类型规则应该批量查询关联表到哈希表避免在循环中逐条SELECT。引擎设计时应支持“规则预加载”和“批量数据准备”。日志记录每次规则执行应记录执行时间、命中次数便于分析低效规则。规则冲突检测同一字段的多个规则可能产生矛盾提示需提供规则依赖分析功能。八、总结通过规则引擎我们将校验逻辑的维护从“开发语言”下沉到“配置表”实现了快速响应业务变化非技术用户经授权可直接修改规则。统一管理所有规则集中存储便于审计和追溯。降低测试成本规则调整无需重新传输程序。但规则引擎并非银弹复杂的跨表、跨系统校验可能仍需少量代码支撑。下一篇文章将详细讲解工具与SAP系统的多种对接方式包括实时校验RFC/增强和批量校验IDoc/OData敬请期待。 你在项目中尝试过规则引擎吗遇到过哪些挑战欢迎留言讨论。作者你的SAP学习伙伴版本记录2026年6月