1、分组
根据维度分组,处理内表中不同维度值的数据
TYPES:BEGIN OF ty_alv,
matnr TYPE marc-matnr, "物料
werks TYPE marc-werks, "工厂
bdmng TYPE resb-bdmng, "数量
zj TYPE resb-bdmng, "汇总
checkbox TYPE char1, "选择框
END OF ty_alv.
DATA: gt_alv TYPE TABLE OF ty_alv, "
gs_alv TYPE ty_alv.
gt_alv = VALUE #( ( matnr = 'AAA' werks = '1000' bdmng = '10.1' checkbox = 'X')
( matnr = 'BBB' werks = '2000' bdmng = '10.2' checkbox = 'X')
( matnr = 'AAA' werks = '1000' bdmng = '10.3' )
( matnr = 'BBB' werks = '2000' bdmng = '10.4' )
( matnr = 'AAA' werks = '2000' bdmng = '10.5' )
( matnr = 'BBB' werks = '2000' bdmng = '10.6' )
).
"根据物料和工厂维度分组
LOOP AT gt_alv INTO gs_alv GROUP BY ( matnr = gs_alv-matnr
werks = gs_alv-werks ).
WRITE: / '组 ',gs_alv-matnr,gs_alv-werks.
CLEAR:lv_item.
LOOP AT GROUP gs_alv ASSIGNING FIELD-SYMBOL(<fs_alv>).
lv_item = lv_item + 1.
WRITE: / ' ',lv_item,<fs_alv>-matnr,<fs_alv>-werks,<fs_alv>-bdmng.
ENDLOOP.
CLEAR:gs_alv.
ENDLOOP.
根据维度分组
2、同维度处理
比如在ALV中经常会将选中行的相同维度的行都选中,也可以通过该方法实现
比如勾选了两行数据
按照维度分组,直接更新选择框
"将选中行的相同维度的行都选中
LOOP AT gt_alv INTO gs_alv WHERE checkbox = 'X' GROUP BY ( matnr = gs_alv-matnr
werks = gs_alv-werks ).
MODIFY gt_alv FROM gs_alv TRANSPORTING checkbox WHERE matnr = gs_alv-matnr
AND werks = gs_alv-werks.
CLEAR:gs_alv.
ENDLOOP.
结果如下
3、分组行数
比如想知道每组的行数,用来在最后一行显示同维度数量总计,可以使用GROUP SIZE
DATA:lv_count TYPE i, "行计数器
lv_bdmng TYPE resb-bdmng. "数量
LOOP AT gt_alv INTO gs_alv GROUP BY ( matnr = gs_alv-matnr
werks = gs_alv-werks
size = GROUP SIZE )
INTO DATA(ls_key).
CLEAR:lv_bdmng,lv_count.
LOOP AT GROUP ls_key ASSIGNING FIELD-SYMBOL(<fs_alv>).
lv_count = lv_count + 1."计数器
lv_bdmng = lv_bdmng + <fs_alv>-bdmng."数量累加
IF ls_key-size = lv_count."最后一行
<fs_alv>-zj = lv_bdmng."总计
ENDIF.
ENDLOOP.
CLEAR:gs_alv.
ENDLOOP.
结果如下
再比如,进行数量分摊。将分摊数量,按照各行数量在本维度中的占比,根据比例进行分摊。分摊到最后一行,将最终剩余的分摊数量全部分摊到这一行中,避免因为比例计算而产生尾差
TYPES:BEGIN OF ty_alv,
matnr TYPE marc-matnr, "物料
werks TYPE marc-werks, "工厂
bdmng TYPE resb-bdmng, "数量
zftsl TYPE resb-bdmng, "分摊数量
END OF ty_alv.
DATA: gt_alv TYPE TABLE OF ty_alv, "
gs_alv TYPE ty_alv.
DATA:lv_count TYPE i, "行计数器
lv_ftzs TYPE resb-bdmng, "分摊总数
lv_syftsl TYPE resb-bdmng, "剩余分摊数量
lv_bdmng TYPE resb-bdmng. "数量
"只用同一维度的数据来简单举例
gt_alv = VALUE #( ( matnr = 'AAA' werks = '1000' bdmng = '1' )
( matnr = 'AAA' werks = '1000' bdmng = '2' )
( matnr = 'AAA' werks = '1000' bdmng = '3' )
( matnr = 'AAA' werks = '1000' bdmng = '4' )
).
"按照物料工厂分组
LOOP AT gt_alv INTO gs_alv GROUP BY ( matnr = gs_alv-matnr
werks = gs_alv-werks
size = GROUP SIZE )
INTO DATA(ls_key).
lv_syftsl = lv_ftzs = 100."需要分摊的总数
"先计算同维度数量之和。这个也可以放在其他地方计算,写在此处是为了展示在LOOP中可以多次进行LOOP AT GROUP循环
CLEAR:lv_bdmng.
LOOP AT GROUP ls_key ASSIGNING FIELD-SYMBOL(<fs_alv>).
lv_bdmng = lv_bdmng + <fs_alv>-bdmng."数量累加
ENDLOOP.
"再次循环进行分摊
LOOP AT GROUP ls_key ASSIGNING <fs_alv>.
lv_count = lv_count + 1."计数器
IF ls_key-size = lv_count."最后一行
<fs_alv>-zftsl = lv_syftsl."分摊数量
ELSE."不是最后一行
"分摊数量 = 分摊总数 * 分配比例(分配比例 = 本行数量 / 该维度总数量)
<fs_alv>-zftsl = lv_ftzs * <fs_alv>-bdmng / lv_bdmng.
lv_syftsl = lv_syftsl - <fs_alv>-zftsl."剩余分摊数量 = 剩余分摊数量 - 分摊数量
ENDIF.
ENDLOOP.
CLEAR:gs_alv.
ENDLOOP.
最终结果