原创 无峰 [ ABAP 技巧与实战 ](javascript:void\(0\);)
**点击蓝字** 关注我们
一
前言
最近项目上碰到一类需求,需要对两组数据进行比对,显示出差异.考虑这一类开发存在的共性: 对两个内表的内容进行比对,给出差异结果.
开发了一个类来完成两个内表的比较并呈现结果
**本文主要介绍两个内表比较的相关细节**
二
标准内表比较函数
系统有标准函数比较两个内表差异,通过输出参数显示结果
• TABLE_DEL 删除的行
• TABLE_ADD 新增的行
• TABLE_MOD 修改的行
. 三个函数功能差不多. 似乎后面的函数性能会更好些, 或者解决了前面函数的一些小BUG .
• CTVB_COMPARE_TABLES
• CTVB_COMPARE_TABLES_2
• CTVB_COMPARE_TABLES_3
三
内表比较说明
两个参与比较的内表需要符合下述条件
• 必须要相同的关键字
• 记录不能重复(需按关键字排序,删重) 如果重复, 哈希化处理时会报错
• 两个内表字段可以不一致,但至少有一个同名非关键字段
比较结果说明
• S 相同关键字同名字段内容一致(同名字段)
• D 相同关键字同名字段存在不一致(同名字段)
• A 只有A内表存在的条目(通过关键字判断)
• B 只有B内表存在的条目(通过关键字判断)
四
自定义内表比较类
开发类 ZCL_ITAB_COMPARE 完成内表比较及差异输出.
主要内容放在一个工作区中,如图一 该工作区包含了两个比较内表的所有用到信息及输出结果
• 内表内容
• 字段标签
• 哈希化内表:用于加速比较
• 相同内容及条目数
• 不同内容及条目数
• 仅A表的内容及条目数
• 仅B表的内容及条目数
• 比较结果表(双行/单行)
• 临时使用的工作区
• ……
为比较结果增加了两个字段
COMP_RESULT
• A 只有A表存在的记录
• B 只有B表存在的记录
• S 两个表都存在,且相同的记录
• D 两个表都存在,且不相同的记录
COMP_ITAB
• A 参与比较的A内表行
• B 参与比较的B内表行
• S A内表与B内表完全一致的行(双行模式完全一致的行只显示一行)
类中的代码比较简单, 比较逻辑通过循环A表, READ B(哈希化)表.来进行比较. 考虑了任意两个内表比较, 使用了很多动态语法. 满足所有内表比较的场景
图一
五
测试程序
ZTS_ZCL_ITAB_COMPARE
选择屏幕
• P_DIFF 只显示差异
• P_SINGLE 单行显示
• P_DISP 单行显示时相同字段在一起
_**01** _
**添加比较内容**
_**02** _
**调用类**
调用类比较,并输出比较结果
六
结果输出
• 单行模式:两个表的记录整合在一行中显示,字段顺序按P_DISP设置显示(如图二/图三)
• 双行模式:分两行显示两个内表不同的行(如图四)
输出结果中考虑了两个内表比较的所有细节
• 通过ALV标题输出关键统计信息
• 内表(第一个字段COMP_ITAB)显示记录来源,TOOLTIP 显示用户传输的两个内表的描述,单行模式该字段内容为空
• 比较结果(第二个字段COMP_RESULT)显示比较结果(S/D/A/B),TOOLTIP显示颜色说明: 深浅蓝-关键字,浅黄-A表专有字段,深黄-B表专有字段,深浅红-差异字段
• 记录按传入的带有顺序的关键字排序
• 关键字用深蓝,浅蓝交替显示,方便查看关键字相同的记录
• 有差异的字段用深红,浅红交替显示:方便查看字段内容差异
• 仅A表或仅B表存在的记录,不显示颜色. 通过比较结果字段识别
图二 单行模式 相同字段在一起
图三 单行模式 相同字段不在一起
图三 双行模式
七
总结
两个内表比较是一个比较简单的场景.很多项目中都会用到. 通过封装类把两个内表的细节充分体现出来.
避免项目中重复开发类似的逻辑.表ZTCOMPARE_C1配置比较字段
八
排版设计
*&---------------------------------------------------------------------**& Report ZTS_ZCL_ITAB_COMPARE*&---------------------------------------------------------------------**&*&---------------------------------------------------------------------*REPORT zts_zcl_itab_compare.PARAMETERS: p_single AS CHECKBOX.PARAMETERS: p_diff AS CHECKBOX.PARAMETERS: p_disp AS CHECKBOX.
DATA: gc_comp TYPE REF TO zcl_itab_compare.TYPES: BEGIN OF ty_key,"传递的关键字 fieldname(30), zsort(3) TYPE n, "关键字顺序
END OF ty_key .DATA: gt_key TYPE HASHED TABLE OF ty_key WITH UNIQUE KEY fieldname.
DATA: BEGIN OF gs_a, vbeln TYPE vbak-vbeln, auart TYPE vbak-auart, vkorg TYPE vbak-vkorg, kunnr TYPE vbak-kunnr, END OF gs_a.DATA: gt_a LIKE TABLE OF gs_a.
DATA: BEGIN OF gs_b, vbeln TYPE vbak-vbeln, auart TYPE vbak-auart, vtweg TYPE vbak-vtweg, kunnr TYPE vbak-kunnr, END OF gs_b.DATA: gt_b LIKE TABLE OF gs_b.
DATA: gt_c LIKE TABLE OF gs_a.START-OF-SELECTION. PERFORM frm_fill_data.
PERFORM frm_comp_data.*&---------------------------------------------------------------------**& Form frm_fill_data*&---------------------------------------------------------------------**& text*&---------------------------------------------------------------------**& --> p1 text*& <-- p2 text*&---------------------------------------------------------------------*FORM frm_fill_data . gt_key = VALUE #( ( fieldname = 'VBELN' ) ). gt_a = VALUE #( ( vbeln = '10010' auart = 'Z001' vkorg = '1000' kunnr = 'K001' ) ( vbeln = '10011' auart = 'Z001' vkorg = '1000' kunnr = 'K001' ) ( vbeln = '10020' auart = 'Z001' vkorg = '1000' kunnr = 'K001' ) ( vbeln = '10030' auart = 'Z001' vkorg = '1000' kunnr = 'K001' ) ( vbeln = '10040' auart = 'Z001' vkorg = '1000' kunnr = 'K001' ) ( vbeln = '10050' auart = 'Z001' vkorg = '1000' kunnr = 'K001' ) ). gt_b = VALUE #( ( vbeln = '10010' auart = 'Z001' vtweg = '10' kunnr = 'K001' ) ( vbeln = '10011' auart = 'Z001' vtweg = '10' kunnr = 'K001' ) ( vbeln = '10020' auart = 'Z002' vtweg = '10' kunnr = 'K001' ) ( vbeln = '10030' auart = 'Z002' vtweg = '10' kunnr = 'K002' ) ( vbeln = '10060' auart = 'Z002' vtweg = '10' kunnr = 'K002' ) ( vbeln = '10070' auart = 'Z002' vtweg = '10' kunnr = 'K002' ) ).ENDFORM.*&---------------------------------------------------------------------**& Form frm_comp_data*&---------------------------------------------------------------------**& text*&---------------------------------------------------------------------**& --> p1 text*& <-- p2 text*&---------------------------------------------------------------------*FORM frm_comp_data . "创建实例 CREATE OBJECT gc_comp EXPORTING it_a = gt_a it_b = gt_b iv_desc_a = '销售订单A' iv_desc_b = '销售订单B'* it_fcat_a =* it_fcat_b = it_keys = gt_key. "比较内表 gc_comp->compare_two_itab( EXPORTING iv_diff = p_diff iv_single = p_single iv_disp_method = p_disp ). "获取比较结果"显示比较结果 gc_comp->display_result( ).ENDFORM.
** THE **
** END **
**约定**
如果你对这篇文章感兴趣,请帮忙点赞,在看,分享.
( **如果你真的喜欢这篇文章,请记得回来打个赏,作为支持我继续下去的动力,这是一个正反馈过程.
越多的人打赏,作者越有动力分享,读者就能享受更多的福利.毕竟打赏的金额富不了我,穷不了你,却能支持这个公众号长久发文.** )
**公众号 : syjf1976_abap**
**ABAP开发技巧**
**微信号 : 392077**
syjf1976
sharry_xlp
Yannick_Duan
申请进入公众号讨论群提问或者参与话题讨论