销售订单明细查询报表
业务目的:根据选择屏幕的筛选条件,使用 ALV 报表,显示销售订单详情
效果展示
用户的输入条件界面
用户的查询结果界面(部分截图)
完整代码如下所示
主程序(zsd001_437)
*&---------------------------------------------------------------------*
*& Report ZSD001_437
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zsd001_437.
INCLUDE zsd001_437_top. " 数据定义
INCLUDE zsd001_437_f01. " 子例程
*----------------------------------------------------------------------*
* DESC: INITIALIZATION 事件
*----------------------------------------------------------------------*
INITIALIZATION.
*----------------------------------------------------------------------*
* DESC: AT SELECTION-SCREEN OUTPUT 事件
*----------------------------------------------------------------------*
AT SELECTION-SCREEN OUTPUT.
*----------------------------------------------------------------------*
* DESC: AT SELECTION-SCREEN 事件
*----------------------------------------------------------------------*
AT SELECTION-SCREEN.
*----------------------------------------------------------------------*
* DESC: START-OF-SELECTION 事件
*----------------------------------------------------------------------*
START-OF-SELECTION.
PERFORM frm_get_data. " 获取数据
*---------------------------------------------------------------------*
* END-OF-SELECTION 事件
*---------------------------------------------------------------------*
END-OF-SELECTION.
PERFORM frm_display_data. " ALV呈现数据
INCLUDE程序(zsd001_437_top)
*&---------------------------------------------------------------------*
*& 包含 ZSD001_437_TOP
*&---------------------------------------------------------------------*
TABLES: vbak, vbap.
* 定义数据类型
TYPES: BEGIN OF ty_item,
sel(1), " 选择标志
vtext1 TYPE tvkot-vtext, " 销售组织名称
vtext2 TYPE tvtwt-vtext, " 分销渠道名称
bztxt TYPE t171t-bztxt, " 销售区域名称
ktext TYPE t151t-ktext, " 客户组
vtext3 TYPE tvktt-vtext, " 账户分配组
auart TYPE vbak-auart, " 订单类型
bezei TYPE tvakt-bezei, " 订单类型描述
vbeln TYPE vbak-vbeln, " 销售订单号
kunnr TYPE kna1-kunnr, " 客户编号
name1 TYPE kna1-name1, " 客户名称
audat TYPE vbak-audat, " 订单创建日期
posnr TYPE vbap-posnr, " 行项目号
matnr TYPE mara-matnr, " 物料编码
maktx TYPE makt-maktx, " 物料名称
kwmeng TYPE vbap-kwmeng, " 订单数量
vrkme TYPE vbap-vrkme, " 订单单位
werks TYPE vbap-werks, " 交货工厂
fevor TYPE marc-fevor, " 生产管理员
txt TYPE t024f-txt, " 生产主管姓名
mbdat TYPE vbbe-mbdat, " 订单预交日期
vbeln_fh TYPE c LENGTH 100, " 发货单单号
erdat TYPE likp-erdat, " 发货单创建日期
lfimg TYPE lips-lfimg, " 申请发货数
labst TYPE mard-labst, " 现有库存
vgbel TYPE vbap-vgbel, " 合同号
labor TYPE mara-labor, " 产品状态
delqty TYPE vbfa-rfmng, " 发货数量
END OF ty_item.
DATA: gt_item TYPE STANDARD TABLE OF ty_item, " 内表
gs_item TYPE ty_item. " 结构体变量
* ALV参数定义
DATA: gs_layout TYPE lvc_s_layo, " 用于定义ALV表单的相关格式、属性
gs_fcat TYPE lvc_s_fcat, " 字段目录工作区
gt_fcat TYPE STANDARD TABLE OF lvc_s_fcat. " 字段目录内表
* 选择屏幕(屏幕输入)
SELECT-OPTIONS:
s_vkorg FOR vbak-vkorg OBLIGATORY, " 销售组织(必输)
s_vtweg FOR vbak-vtweg, " 分销渠道
s_auart FOR vbak-auart, " 销售订单类型
s_vbeln FOR vbak-vbeln, " 销售订单编号
s_matnr FOR vbap-matnr. " 物料编码
INCLUDE程序(zsd001_437_f01)
*&---------------------------------------------------------------------*
*& 包含 ZSD001_437_F01
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Form frm_get_data
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_get_data.
SELECT tvkot~vtext AS vtext1, " 销售组织名称
tvtwt~vtext AS vtext2, " 分销渠道名称
t171t~bztxt, " 销售区域名称
t151t~ktext, " 客户组
tvktt~vtext AS vtext3, " 账户分配组
vbak~auart, " 订单类型
tvakt~bezei, " 订单描述类型
vbak~vbeln, " 销售订单号
vbak~kunnr, " 客户编号
kna1~name1, " 客户名称
vbak~audat, " 订单创建日期
vbap~posnr, " 行项目号
vbap~matnr, " 物料编码
makt~maktx, " 物料名称
vbap~kwmeng, " 订单数量
vbap~vrkme, " 订单单位
vbap~werks, " 交货工厂
marc~fevor, " 生产管理员
t024f~txt, " 生产主管姓名
vbap~vgbel, " 合同号
mara~labor " 产品状态
FROM vbak
INNER JOIN vbap
ON vbak~vbeln = vbap~vbeln
LEFT JOIN tvkot
ON vbak~vkorg = tvkot~vkorg
AND tvkot~spras = @sy-langu
LEFT JOIN tvtwt
ON vbak~vtweg = tvtwt~vtweg
AND tvtwt~spras = @sy-langu
LEFT JOIN vbkd
ON vbap~vbeln = vbkd~vbeln
AND vbap~posnr = vbkd~posnr
LEFT JOIN t171t
ON vbkd~bzirk = t171t~bzirk
AND t171t~spras = @sy-langu
LEFT JOIN t151t
ON vbkd~kdgrp = t151t~kdgrp
AND t151t~spras = @sy-langu
LEFT JOIN tvktt
ON vbkd~ktgrd = tvktt~ktgrd
AND tvktt~spras = @sy-langu
LEFT JOIN tvakt
ON vbak~auart = tvakt~auart
AND tvakt~spras = @sy-langu
LEFT JOIN kna1
ON vbak~kunnr = kna1~kunnr
LEFT JOIN makt
ON vbap~matnr = makt~matnr
AND makt~spras = @sy-langu
LEFT JOIN marc
ON vbap~werks = marc~werks
AND vbap~matnr = marc~matnr
LEFT JOIN t024f
ON marc~fevor = t024f~fevor
AND marc~werks = t024f~werks
LEFT JOIN mara
ON vbap~matnr = mara~matnr
INTO CORRESPONDING FIELDS OF TABLE @gt_item
WHERE vbak~vkorg IN @s_vkorg
AND vbak~vtweg IN @s_vtweg
AND vbak~auart IN @s_auart
AND vbak~vbeln IN @s_vbeln
AND vbap~matnr IN @s_matnr.
IF sy-subrc = 0.
PERFORM frm_edit_data. " 编辑处理内表数据
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_edit_data
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_edit_data.
IF gt_item IS NOT INITIAL. " 当gt_item内表不为空时,进行以下逻辑处理
* 订单预交日期字段查询处理
SELECT vbbe~vbeln, " 销售凭证
vbbe~posnr, " 销售凭证项目
vbbe~mbdat " 订单预交日期
FROM vbbe
INTO TABLE @DATA(lt_vbbe)
FOR ALL ENTRIES IN @gt_item
WHERE vbeln = @gt_item-vbeln
AND posnr = @gt_item-posnr.
IF sy-subrc = 0.
SORT lt_vbbe BY vbeln posnr mbdat. " 对内表lt_vbbe中的字段vbeln,posnr和mbdat进行升序排序
ENDIF.
* 发货单单号、发货单创建日期和申请发货数字段查询处理
SELECT lips~vgbel, " 参考单据的单据编号
lips~vgpos, " 参考项目的项目号
lips~vbeln, " 发货单单号
lips~posnr, " 交货项目
lips~lfimg, " 实际已交货量
likp~erdat " 记录建立日期
FROM lips
INNER JOIN likp
ON lips~vbeln = likp~vbeln
INTO TABLE @DATA(lt_lips)
FOR ALL ENTRIES IN @gt_item
WHERE vgbel = @gt_item-vbeln
AND vgpos = @gt_item-posnr.
IF sy-subrc = 0.
SORT lt_lips BY vbeln posnr erdat DESCENDING.
DATA(lt_max_erdat) = lt_lips. " 赋值
SORT lt_max_erdat BY vgbel vgpos erdat DESCENDING.
ENDIF.
* 现有库存字段查询处理
SELECT mard~werks, " 工厂
mard~matnr, " 物料编号
mard~labst " 非限制使用的估价的库存
FROM mard
INTO TABLE @DATA(lt_mard)
FOR ALL ENTRIES IN @gt_item
WHERE matnr = @gt_item-matnr
AND werks = @gt_item-werks.
ENDIF.
LOOP AT gt_item ASSIGNING FIELD-SYMBOL(<lfs_item>). " 一条一条处理
" 订单预交日期字段逻辑处理
" 取最小的订单预交日期
SELECT MIN( mbdat )
FROM vbbe
INTO <lfs_item>-mbdat
WHERE vbeln = <lfs_item>-vbeln
AND posnr = <lfs_item>-posnr.
LOOP AT lt_lips INTO DATA(ls_lips)
WHERE vgbel = <lfs_item>-vbeln AND vgpos = <lfs_item>-posnr .
" 发货单单号字段逻辑处理
IF ls_lips-vbeln IS NOT INITIAL.
ls_lips-vbeln = |{ ls_lips-vbeln ALPHA = OUT }|. " 去除vbeln字段中的前导零
<lfs_item>-vbeln_fh = <lfs_item>-vbeln_fh && ',' && ls_lips-vbeln. " 如果出现多个交货单,则将交货单拼接显示 DN1,DN2,DN3
ENDIF.
" 申请发货数字段逻辑处理
<lfs_item>-lfimg = <lfs_item>-lfimg + ls_lips-lfimg. " 根据订单号进行行项目累加
ENDLOOP.
SHIFT <lfs_item>-vbeln_fh LEFT DELETING LEADING ','. " 删除首端的逗号
" 发货单创建日期字段逻辑处理
READ TABLE lt_max_erdat WITH KEY vgbel = <lfs_item>-vbeln vgpos = <lfs_item>-posnr
INTO DATA(ls_max_erdat).
IF sy-subrc = 0.
<lfs_item>-erdat = ls_max_erdat-erdat. " 取最大日期
ENDIF.
" 现有库存字段逻辑处理
LOOP AT lt_mard INTO DATA(ls_mard)
WHERE werks = <lfs_item>-werks AND matnr = <lfs_item>-matnr.
<lfs_item>-labst = <lfs_item>-labst + ls_mard-labst. " 累加所有库位的数量
ENDLOOP.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_display_data
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_display_data.
PERFORM frm_alv_set_fields.
" 调用函数显示ALV数据
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
i_bypassing_buffer = abap_true
i_callback_program = sy-repid
it_fieldcat_lvc = gt_fcat " 设置ALV列属性
is_layout_lvc = gs_layout " 设置ALV布局
i_callback_pf_status_set = 'FRM_ALV_SET_STATUS' " 子例程(设置状态栏)
i_callback_user_command = 'FRM_ALV_USER_COMMAND' " 子例程(用户指令响应)
TABLES
t_outtab = gt_item " 内表数据
EXCEPTIONS
program_error = 1
OTHERS = 2.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_alv_set_fields
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_alv_set_fields .
DATA: lv_index LIKE sy-index.
CLEAR: gs_fcat,
gt_fcat,
gs_layout.
* 设置行的属性(ALV界面格式)
gs_layout-box_fname = 'SEL'. " 选择标识
gs_layout-zebra = 'X'. " 斑马条纹显示
gs_layout-cwidth_opt = 'X'. " 优化列宽设置
* ALV字段处理宏
DEFINE catalog.
lv_index = lv_index + 1.
gs_fcat-col_pos = lv_index.
gs_fcat-fieldname = &1. " 设置要输出的表格列的值,在内表中定义的字段名(必须大写)
gs_fcat-fix_column = &2. " 固定列
gs_fcat-ref_table = &3.
gs_fcat-edit = &4.
gs_fcat-colddictxt = 'L'.
gs_fcat-scrtext_l = &5. " 设置要输出的表格列的列名,即ALV报表显示的列名
gs_fcat-ref_field = &6.
gs_fcat-outputlen = &7.
gs_fcat-emphasize = &8. " 列颜色
gs_fcat-hotspot = &9. " 热点
APPEND gs_fcat TO gt_fcat.
END-OF-DEFINITION.
* &1 &2 &3 &4 &5 &6 &7 &8 &9
catalog:
'VTEXT1' 'X' '' '' '销售组织名称' '' '' 'C510' 'X', " 销售组织名称
'VTEXT2' 'X' '' '' '分销渠道名称' '' '' '' '', " 分销渠道名称
'BZTXT' '' '' '' '销售区域名称' '' '' '' '', " 销售区域名称
'KTEXT' '' '' '' '客户组' '' '' '' '', " 客户组
'VTEXT3' '' '' '' '账户分配组' '' '' '' '', " 账户分配组
'AUART' '' '' '' '订单类型' '' '' '' '', " 订单类型
'BEZEI' '' '' '' '订单类型描述' '' '' '' '', " 订单类型描述
'VBELN' '' '' '' '销售订单号' '' '' '' '', " 销售订单号
'KUNNR' '' '' '' '客户编号' '' '' '' '', " 客户编号
'NAME1' '' '' '' '客户名称' '' '' '' '', " 客户名称
'AUDAT' '' '' '' '订单创建日期' '' '' '' '', " 订单创建日期
'POSNR' '' '' '' '行项目号' '' '' '' '', " 行项目号
'MATNR' '' 'MARA' '' '物料编码' 'MATNR' '' '' '', " 物料编码
'MAKTX' '' '' '' '物料名称' '' '' '' '', " 物料名称
'KWMENG' '' '' '' '订单数量' '' '' '' '', " 订单数量
'VRKME' '' '' '' '订单单位' '' '' '' '', " 订单单位
'WERKS' '' '' '' '交货工厂' '' '' '' '', " 交货工厂
'FEVOR' '' '' '' '生产管理员' '' '' '' '', " 生产管理员
'TXT' '' '' '' '生产主管姓名' '' '' '' '', " 生产主管姓名
'MBDAT' '' '' '' '订单预交日期' '' '' '' '', " 订单预交日期
'VBELN_FH' '' '' '' '发货单单号' '' '' '' '', " 发货单单号
'ERDAT' '' '' '' '发货单创建日期' '' '' '' '', " 发货单创建日期
'LFIMG' '' '' '' '申请发货数' '' '' '' '', " 申请发货数
'LABST' '' '' '' '现有库存' '' '' '' '', " 现有库存
'VGBEL' '' '' '' '合同号' '' '' '' '', " 合同号
'LABOR' '' '' '' '产品状态' '' '' '' '', " 产品状态
'DELQTY' '' '' '' '交货数量' '' '' '' ''. " 交货数量
ENDFORM.
* 设置状态栏
FORM frm_alv_set_status USING ct_extab TYPE slis_t_extab.
SET PF-STATUS 'ZSTALV' EXCLUDING ct_extab.
ENDFORM.
* 设置用户指令响应
FORM frm_alv_user_command USING pv_ucomm LIKE sy-ucomm
ps_selfield TYPE slis_selfield.
ps_selfield-refresh = 'X'." 编辑完成保存后刷新alv页
CASE pv_ucomm. " pv_ucomm参数表示引发输入后处理的功能代码
WHEN '&DIS'. " 自定义按钮点击
READ TABLE gt_item INTO gs_item INDEX ps_selfield-tabindex.
* 事件触发时显示当前行的销售订单号
MESSAGE gs_item-vbeln TYPE 'I'.
WHEN '&IC1'. " 单击(热点)或者双击进行触发:单击和双击使用同一功能代码(用户命令执行)
READ TABLE gt_item INTO gs_item INDEX ps_selfield-tabindex.
* 事件触发时显示当前行的销售订单号
MESSAGE gs_item-vbeln TYPE 'I'.
ENDCASE.
ENDFORM.
补充扩展知识
调用REUSE_ALV_GRID_DISPLAY_LVC函数显示ALV,在调用该函数之前,需要先定义Layout和Fieldcat,该函数对应的Layout 类型为lvc_s_layo,Fieldcat类型为lvc_s_fcat
Layout主要用于设定 ALV的输出格式
Fieldcat主要用于ALV的结构定义,包括具体的栏位及名称、类型、格式等属性
本文涉及到的相关知识点
[SAP ABAP] ALV状态栏GUI STATUS的快速创建https://blog.csdn.net/Hudas/article/details/144565584?spm=1001.2014.3001.5502[SAP ABAP] ALV中的USER_COMMAN用户事件https://blog.csdn.net/Hudas/article/details/144588762?spm=1001.2014.3001.5502[SAP ABAP] INCLUDE程序创建https://blog.csdn.net/Hudas/article/details/142750537
[SAP ABAP] ALV基础开发https://blog.csdn.net/Hudas/article/details/135887821[SAP ABAP] 选择屏幕事件https://blog.csdn.net/Hudas/article/details/142894916[SAP ABAP] SELECTION-SCREENhttps://blog.csdn.net/Hudas/article/details/142623521