[SAP ABAP] ALV报表练习1
销售订单明细查询报表
业务目的:根据选择屏幕的筛选条件,使用 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 vbakINNER JOIN vbapON vbak~vbeln = vbap~vbelnLEFT JOIN tvkotON vbak~vkorg = tvkot~vkorgAND tvkot~spras = @sy-languLEFT JOIN tvtwtON vbak~vtweg = tvtwt~vtwegAND tvtwt~spras = @sy-languLEFT JOIN vbkdON vbap~vbeln = vbkd~vbelnAND vbap~posnr = vbkd~posnrLEFT JOIN t171tON vbkd~bzirk = t171t~bzirkAND t171t~spras = @sy-languLEFT JOIN t151tON vbkd~kdgrp = t151t~kdgrpAND t151t~spras = @sy-languLEFT JOIN tvkttON vbkd~ktgrd = tvktt~ktgrdAND tvktt~spras = @sy-languLEFT JOIN tvaktON vbak~auart = tvakt~auartAND tvakt~spras = @sy-languLEFT JOIN kna1ON vbak~kunnr = kna1~kunnrLEFT JOIN maktON vbap~matnr = makt~matnrAND makt~spras = @sy-languLEFT JOIN marcON vbap~werks = marc~werksAND vbap~matnr = marc~matnrLEFT JOIN t024fON marc~fevor = t024f~fevorAND marc~werks = t024f~werksLEFT JOIN maraON vbap~matnr = mara~matnrINTO CORRESPONDING FIELDS OF TABLE @gt_itemWHERE vbak~vkorg IN @s_vkorgAND vbak~vtweg IN @s_vtwegAND vbak~auart IN @s_auartAND vbak~vbeln IN @s_vbelnAND 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 vbbeINTO TABLE @DATA(lt_vbbe)FOR ALL ENTRIES IN @gt_itemWHERE vbeln = @gt_item-vbelnAND 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 lipsINNER JOIN likpON lips~vbeln = likp~vbelnINTO TABLE @DATA(lt_lips)FOR ALL ENTRIES IN @gt_itemWHERE vgbel = @gt_item-vbelnAND 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 mardINTO TABLE @DATA(lt_mard)FOR ALL ENTRIES IN @gt_itemWHERE matnr = @gt_item-matnrAND werks = @gt_item-werks.ENDIF.LOOP AT gt_item ASSIGNING FIELD-SYMBOL(<lfs_item>). " 一条一条处理" 订单预交日期字段逻辑处理" 取最小的订单预交日期SELECT MIN( mbdat )FROM vbbeINTO <lfs_item>-mbdatWHERE vbeln = <lfs_item>-vbelnAND 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,DN3ENDIF." 申请发货数字段逻辑处理<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>-posnrINTO 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'EXPORTINGi_bypassing_buffer = abap_truei_callback_program = sy-repidit_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' " 子例程(用户指令响应)TABLESt_outtab = gt_item " 内表数据EXCEPTIONSprogram_error = 1OTHERS = 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 &9catalog:'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-ucommps_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