ABAP中多条件深层结构表的字段符号分配优化方案问询
ABAP内表更新优化:基于结构字段筛选并修改EDIDD表数据
需求
从内表t_edidd中筛选满足以下条件的行,将对应sdata结构(类型为E1IDB02)的fiibkont字段更新为01:
segnam = 'E1IDB02'- 关联
sdata结构的fiiquali = 'BB'
现有方案及不足
已有两种可行方案,但存在明显缺陷:
方案一(依赖字符串截取)
FIELD-SYMBOLS: <ls_e1idb02> TYPE e1idb02. LOOP AT t_edidd ASSIGNING FIELD-SYMBOL(<lv_edidd>) WHERE segnam = 'E1IDB02' AND sdata(2) = 'BB'. ASSIGN <lv_edidd>-sdata TO <ls_e1idb02> CASTING. <ls_e1idb02>-fiibkont = `01`. ENDLOOP.
缺点:通过sdata(2)截取字符串判断字段值,完全依赖fiiquali在结构中的固定位置,一旦结构定义变更就会出错,也不符合通过结构字段名判断的设计意图。
方案二(循环内判断)
FIELD-SYMBOLS: <ls_e1idb02> TYPE e1idb02. LOOP AT t_edidd ASSIGNING FIELD-SYMBOL(<lv_edidd>) WHERE segnam = 'E1IDB02'. ASSIGN <lv_edidd>-sdata TO <ls_e1idb02> CASTING. IF <ls_e1idb02>-fiiquali = 'BB'. <ls_e1idb02>-fiibkont = `01`. ENDIF. ENDLOOP.
缺点:逻辑清晰但代码略显冗余,IF...ENDIF增加了不必要的缩进层级。
尝试过的无效写法
曾尝试直接通过内表条件访问,但因ABAP无法直接解析字符串字段的结构属性而失败:
FIELD-SYMBOLS: <ls_e1idb02> TYPE e1idb02. ASSIGN t_edidd[ segnam = 'E1IDB02' sdata-fiiquali = 'BB' ]-sdata TO <ls_e1idb02> CASTING. <ls_e1idb02>-fiibkont = `01`.
更优解决方案
优化方案:使用CHECK替代IF简化逻辑
保留结构字段判断的意图,同时让代码更紧凑:
FIELD-SYMBOLS: <ls_edidd> TYPE edidd, <ls_e1idb02> TYPE e1idb02. LOOP AT t_edidd ASSIGNING <ls_edidd> WHERE segnam = 'E1IDB02'. ASSIGN <ls_edidd>-sdata TO <ls_e1idb02> CASTING. CHECK <ls_e1idb02>-fiiquali = 'BB'. " 不满足条件则直接跳过当前循环 <ls_e1idb02>-fiibkont = `01`. ENDLOOP.
优势:
- 避免了字符串截取的风险,完全通过结构字段名判断
- 用
CHECK替代IF...ENDIF,减少缩进,代码更简洁易读 - 逻辑与方案二完全一致,但可读性更高
适配高版本ABAP的写法(7.54+)
如果使用ABAP 7.54及以上版本,可以结合内表过滤表达式进一步简化,但实际收益有限:
FIELD-SYMBOLS: <ls_e1idb02> TYPE e1idb02. LOOP AT VALUE #( FILTER #( t_edidd WHERE segnam = 'E1IDB02' ) ) ASSIGNING FIELD-SYMBOL(<ls_edidd>). ASSIGN <ls_edidd>-sdata TO <ls_e1idb02> CASTING. CHECK <ls_e1idb02>-fiiquali = 'BB'. <ls_e1idb02>-fiibkont = `01`. MODIFY t_edidd FROM <ls_edidd> INDEX sy-tabix. ENDLOOP.
验证单元测试
以下单元测试代码可验证上述方案的正确性:
METHOD test. DATA: ls_e1idb02 TYPE e1idb02, ls_edidd TYPE edidd, t_edidd TYPE TABLE OF edidd, t_edidd_exp TYPE TABLE OF edidd. ls_edidd-segnam = 'E1IDB02'. ls_e1idb02-fiiquali = 'BA'. ls_edidd-sdata = ls_e1idb02. APPEND ls_edidd TO t_edidd. APPEND ls_edidd TO t_edidd_exp. ls_edidd-segnam = 'E1IDB02'. ls_e1idb02-fiiquali = 'BB'. ls_edidd-sdata = ls_e1idb02. APPEND ls_edidd TO t_edidd. ls_e1idb02-fiibkont = `01`. ls_edidd-sdata = ls_e1idb02. APPEND ls_edidd TO t_edidd_exp. zclass->test( CHANGING t_edidd = t_edidd ). cl_abap_unit_assert=>assert_equals( act = t_edidd exp = t_edidd_exp ). ENDMETHOD.
内容的提问来源于stack exchange,提问作者schmelto
相关产品推荐
相关产品推荐

