如何基于ID及Origin多条件对ABAP内部表进行分类标记?
ABAP内部表分类处理方案
输入内部表
| ID | Text | Origin |
|---|---|---|
| 1 | Text1 | Word |
| 1 | Text1 | Word |
| 1 | Text1 | Excel |
| 1 | Text1 | PowerPoint |
| 2 | Text1 | Excel |
| 2 | Text1 | PowerPoint |
| 3 | Text1 | PowerPoint |
| 3 | Text1 | Excel |
| 3 | Text1 | Excel |
| 3 | Text1 | Excel |
期望结果
| ID | Origin | Classification |
|---|---|---|
| 1 | Word | Triple_Word_Excel_PowerPoint |
| 1 | Word | Triple_Word_Excel_PowerPoint |
| 1 | Excel | Triple_Word_Excel_PowerPoint |
| 1 | PowerPoint | Triple_Word_Excel_PowerPoint |
| 2 | Excel | Double_Excel_PowerPoint |
| 2 | PowerPoint | Double_Excel_PowerPoint |
| 3 | Word | Double_Excel_Word |
| 3 | Excel | Double_Excel_Word |
| 3 | Excel | Double_Excel_Word |
| 3 | Excel | Double_Excel_Word |
问题说明
现有上述ABAP内部表,需按ID分组生成统一的Classification字段:
- 前缀根据ID下不同Origin的数量确定:3种对应
Triple,2种对应Double,其他情况对应Single - 后缀为该ID下所有不同Origin的下划线拼接字符串
尝试循环筛选ID并检查Origin值未实现目标,寻求更优方案(包括SELECT语句处理方式)
用户尝试代码
DATA: lv_current_id TYPE string VALUE ' ', lv_origin_count TYPE i VALUE 0, lv_origin_text TYPE string VALUE ' '. LOOP AT lt_internal_table INTO DATA(ls_data). CLEAR: lv_origin_count, lv_origin_text. " Check, if origin is processed IF NOT ( ls_data-origin IN lt_origin ). " Save origin in temporary list APPEND ls_data-origin TO lt_origin. " Count occurrence of origin per id LOOP AT lt_data INTO DATA(ls_data2) WHERE id = ls_data-id AND origin = ls_data-origin. ADD 1 TO lv_origin_count. ENDLOOP. " Create cext for classification columnText für die Anzahl_Herkunft erstellen CASE lv_origin_count. WHEN 1. lv_origin_text = 'Single' && ls_data-origin. WHEN 2. lv_origin_text = 'Double' && ls_data-origin && ls_data-origin. WHEN 3. lv_origin_text = 'Triple' && ls_data-origin && ls_data-origin && ls_data-origin. ENDCASE. " Save result in internal result table APPEND VALUE #( id = ls_data-id text = ls_data-text origin = ls_data-origin classification = lv_origin_text ) TO lt_result. ENDIF. ENDLOOP.
解决方案
方案一:ABAP内部表循环处理(适用于所有版本)
通过两次循环完成分组统计与结果生成,逻辑清晰且兼容低版本ABAP:
* 定义类型 TYPES: BEGIN OF ty_source, id TYPE i, text TYPE string, origin TYPE string, END OF ty_source. TYPES: BEGIN OF ty_id_meta, id TYPE i, origins TYPE STANDARD TABLE OF string WITH UNIQUE KEY table_line, class TYPE string, END OF ty_id_meta. * 声明变量 DATA: lt_source TYPE STANDARD TABLE OF ty_source, lt_id_metas TYPE STANDARD TABLE OF ty_id_meta WITH UNIQUE KEY id, lt_result TYPE STANDARD TABLE OF ty_source WITH EMPTY KEY. * 假设lt_source已填充输入数据 * 第一步:按ID收集所有唯一Origin LOOP AT lt_source INTO DATA(ls_source). READ TABLE lt_id_metas INTO DATA(ls_id_meta) WITH KEY id = ls_source-id. IF sy-subrc <> 0. ls_id_meta-id = ls_source-id. INSERT ls_source-origin INTO ls_id_meta-origins INDEX 1. INSERT ls_id_meta INTO lt_id_metas. ELSE. " 仅添加未存在的Origin READ TABLE ls_id_meta-origins TRANSPORTING NO FIELDS WITH KEY table_line = ls_source-origin. IF sy-subrc <> 0. INSERT ls_source-origin INTO ls_id_meta-origins INDEX 1. MODIFY lt_id_metas FROM ls_id_meta INDEX sy-tabix. ENDIF. ENDIF. ENDLOOP. * 第二步:生成每个ID对应的Classification LOOP AT lt_id_metas INTO ls_id_meta. SORT ls_id_meta-origins. " 确保Origin拼接顺序一致 DATA(lv_origin_count) = lines(ls_id_meta-origins). " 拼接Origin字符串 DATA(lv_origin_str) = REDUCE string( INIT res = '' FOR <origin> IN ls_id_meta-origins NEXT res = res && COND( WHEN res IS NOT INITIAL THEN '_' ) && <origin> ). " 生成分类前缀 CASE lv_origin_count. WHEN 2. ls_id_meta-class = `Double_` && lv_origin_str. WHEN 3. ls_id_meta-class = `Triple_` && lv_origin_str. WHEN OTHERS. ls_id_meta-class = `Single_` && lv_origin_str. ENDCASE. MODIFY lt_id_metas FROM ls_id_meta INDEX sy-tabix. ENDLOOP. * 第三步:关联原表生成最终结果 LOOP AT lt_source INTO ls_source. READ TABLE lt_id_metas INTO ls_id_meta WITH KEY id = ls_source-id. APPEND VALUE #( id = ls_source-id origin = ls_source-origin classification = ls_id_meta-class ) TO lt_result. ENDLOOP.
方案二:SELECT语句处理(适用于ABAP 7.50+,数据来自数据库表)
利用ABAP 7.50支持的STRING_AGG函数直接在数据库层面完成分组与字符串聚合,性能更优:
SELECT id, origin, CASE COUNT(DISTINCT origin) WHEN 2 THEN 'Double_' || STRING_AGG( DISTINCT origin, '_' ORDER BY origin ) WHEN 3 THEN 'Triple_' || STRING_AGG( DISTINCT origin, '_' ORDER BY origin ) ELSE 'Single_' || STRING_AGG( DISTINCT origin, '_' ORDER BY origin ) END AS classification FROM your_database_table " 替换为实际数据库表名 GROUP BY id, origin ORDER BY id, origin.
内容的提问来源于stack exchange,提问作者christhebliss
相关产品推荐
相关产品推荐

