销售订单明细查询报表
业务目的:根据选择屏幕的筛选条件,使用 ALV 报表,显示销售订单详情
效果展示
用户的输入条件界面
用户的查询结果界面
涉及的主要功能点:
1.当在销售订单明细查询页面取不到任何数据时,在选择画面提示错误消息"不存在满足条件的数据,请确认选择条件"
2.点击ALV报表中的【编辑】按钮,可将'交货工厂'和'交货数量'字段变为可编辑状态,编辑完成并按回车键,即可及时更新ALV报表中的数据
3.ALV报表中的"物料号"设置成"HOTSPOT"热点,单击某物料号跳转到 MM03 的界面显示该物料详情
4.ALV报表中的"交货工厂"字段设置F4搜索帮助
完整代码如下所示
主程序(zsd002_437)
*&---------------------------------------------------------------------*
*& Report ZSD001_437
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zsd002_437.
INCLUDE zsd002_437_c01.
INCLUDE zsd002_437_top. " 数据定义
INCLUDE zsd002_437_f01. " 子例程
INCLUDE zsd002_437_o01.
INCLUDE zsd002_437_i01.
*----------------------------------------------------------------------*
* 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. " 获取数据
" 检查数据是否为空
IF gt_item IS INITIAL.
MESSAGE '不存在满足条件的数据,请确认选择条件' TYPE 'E'.
ENDIF.
*---------------------------------------------------------------------*
* END-OF-SELECTION 事件
*---------------------------------------------------------------------*
END-OF-SELECTION.
PERFORM frm_display_data. " ALV呈现数据
INCLUDE程序( zsd002_437_c01)
*&---------------------------------------------------------------------*
*& 包含 ZSD002_437_C01
*&---------------------------------------------------------------------*
*----------------------------------------------------------------------*
* CLASS book DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_handler DEFINITION FINAL.
PUBLIC SECTION.
METHODS:
handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid " 增设自定义按钮
IMPORTING e_object e_interactive,
after_user_command FOR EVENT after_user_command OF cl_gui_alv_grid " 按钮响应
IMPORTING e_ucomm,
handle_data_changed FOR EVENT data_changed OF cl_gui_alv_grid " 数据变更
IMPORTING er_data_changed
e_onf4
e_onf4_before
e_onf4_after
e_ucomm,
" 数据变更完成
handle_data_changed_finished FOR EVENT data_changed_finished OF cl_gui_alv_grid
IMPORTING e_modified et_good_cells,
" 单击
handle_hotspot_click FOR EVENT hotspot_click OF cl_gui_alv_grid
IMPORTING e_row_id e_column_id,
" 双击
double_click FOR EVENT double_click OF cl_gui_alv_grid
IMPORTING e_row e_column es_row_no,
" F4搜索帮助
handle_f4_help FOR EVENT onf4 OF cl_gui_alv_grid
IMPORTING e_fieldname
e_fieldvalue
es_row_no
er_event_data
et_bad_cells
e_display.
ENDCLASS.
*----------------------------------------------------------------------*
* CLASS book IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_handler IMPLEMENTATION.
METHOD handle_toolbar. " 增设自定义按钮
PERFORM frm_event_toolbar USING e_object.
ENDMETHOD.
METHOD after_user_command. " 按钮响应
PERFORM frm_user_command USING e_ucomm.
ENDMETHOD.
METHOD handle_data_changed. " 数据变更
PERFORM frm_data_changed USING er_data_changed
e_onf4
e_onf4_before
e_onf4_after e_ucomm.
ENDMETHOD.
METHOD handle_data_changed_finished. " 数据变更完成
PERFORM frm_changed_finished USING e_modified et_good_cells.
ENDMETHOD.
METHOD handle_hotspot_click. " 单击
PERFORM frm_hotspot_click USING e_row_id e_column_id.
ENDMETHOD.
METHOD double_click. " 双击
PERFORM frm_double_click USING e_row e_column es_row_no.
ENDMETHOD.
METHOD handle_f4_help. " F4搜索帮助
PERFORM frm_on_f4 USING e_fieldname
e_fieldvalue
es_row_no
er_event_data
et_bad_cells
e_display.
ENDMETHOD.
ENDCLASS.
INCLUDE程序( zsd002_437_top)
*&---------------------------------------------------------------------*
*& 包含 ZSD001_437_TOP
*&---------------------------------------------------------------------*
DATA: ok_code TYPE sy-ucomm.
DATA: go_grid TYPE REF TO cl_gui_alv_grid, " ALV对象
go_custom_container TYPE REF TO cl_gui_custom_container, " Container容器
go_event TYPE REF TO lcl_handler,
gv_valid_error TYPE boole_d,
gt_f4 TYPE lvc_t_f4.
CONSTANTS: go_container TYPE scrfname VALUE 'GO_CONT'. " 容器
* ALV参数定义
DATA: gs_layout TYPE lvc_s_layo, " 用于定义ALV表单的相关格式、属性
gs_fcat TYPE lvc_s_fcat, " 字段目录工作区
gt_fcat TYPE STANDARD TABLE OF lvc_s_fcat. " 字段目录内表
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, " 发货数量
style TYPE lvc_t_styl, " 单元格属性:是否可编辑
linecolor(4) TYPE c, " 指定行颜色的字段
cellcolor TYPE lvc_t_scol, " 单元格颜色
END OF ty_item.
DATA: gt_item TYPE STANDARD TABLE OF ty_item, " 内表
gs_item TYPE ty_item. " 结构体变量
* 选择屏幕(屏幕输入)
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程序( zsd002_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.
" '现有库存'字段值大于0,单元格显示绿色,否则行颜色显示为蓝色
IF <lfs_item>-labst > 0.
" 设置单元格颜色方式1
DATA:ls_cellcolor TYPE lvc_s_scol.
ls_cellcolor-fname = 'LABST'.
ls_cellcolor-color-col = '5'.
ls_cellcolor-color-int = '1'.
ls_cellcolor-color-inv = '0'.
APPEND ls_cellcolor TO <lfs_item>-cellcolor.
" 设置单元格颜色方式2
" APPEND VALUE #( fname = 'LABST' color-col = '5' color-int = '1' color-inv = '0') TO <lfs_item>-cellcolor.
ELSE.
<lfs_item>-linecolor = 'C110'. " 设置行颜色
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_display_data
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_display_data.
CALL SCREEN 9001.
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'. " 优化列宽设置
gs_layout-sel_mode = 'A'.
gs_layout-ctab_fname = 'CELLCOLOR'." 单元格颜色
gs_layout-stylefname = 'STYLE'. " 单元格编辑
gs_layout-info_fname = 'LINECOLOR'." 行颜色
* 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. " 热点
IF gs_fcat-fieldname = 'WERKS'.
gs_fcat-f4availabl = 'X'. " F4检索帮助设置
ENDIF.
APPEND gs_fcat TO gt_fcat.
END-OF-DEFINITION.
* &1 &2 &3 &4 &5 &6 &7 &8 &9
catalog:
'VTEXT1' 'X' '' '' '销售组织名称' '' '' 'C110' '', " 销售组织名称
'VTEXT2' 'X' '' '' '分销渠道名称' '' '' '' '', " 分销渠道名称
'BZTXT' '' '' '' '销售区域名称' '' '' '' '', " 销售区域名称
'KTEXT' '' '' '' '客户组' '' '' '' '', " 客户组
'VTEXT3' '' '' '' '账户分配组' '' '' '' '', " 账户分配组
'AUART' '' '' '' '订单类型' '' '' '' '', " 订单类型
'BEZEI' '' '' '' '订单类型描述' '' '' '' '', " 订单类型描述
'VBELN' '' '' '' '销售订单号' '' '' '' '', " 销售订单号
'KUNNR' '' '' '' '客户编号' '' '' '' '', " 客户编号
'NAME1' '' '' '' '客户名称' '' '' '' '', " 客户名称
'AUDAT' '' '' '' '订单创建日期' '' '' '' '', " 订单创建日期
'POSNR' '' '' '' '行项目号' '' '' '' '', " 行项目号
'MATNR' '' 'MARA' '' '物料编码' 'MATNR' '' '' 'X', " 物料编码
'MAKTX' '' '' '' '物料名称' '' '' '' '', " 物料名称
'KWMENG' '' '' '' '订单数量' '' '' '' '', " 订单数量
'VRKME' '' '' '' '订单单位' '' '' '' '', " 订单单位
'WERKS' '' '' '' '交货工厂' '' '' '' '', " 交货工厂
'FEVOR' '' '' '' '生产管理员' '' '' '' '', " 生产管理员
'TXT' '' '' '' '生产主管姓名' '' '' '' '', " 生产主管姓名
'MBDAT' '' '' '' '订单预交日期' '' '' '' '', " 订单预交日期
'VBELN_FH' '' '' '' '发货单单号' '' '' '' '', " 发货单单号
'ERDAT' '' '' '' '发货单创建日期' '' '' '' '', " 发货单创建日期
'LFIMG' '' '' '' '申请发货数' '' '' '' '', " 申请发货数
'LABST' '' '' '' '现有库存' '' '' '' '', " 现有库存
'VGBEL' '' '' '' '合同号' '' '' '' '', " 合同号
'LABOR' '' '' '' '产品状态' '' '' '' '', " 产品状态
'DELQTY' '' '' '' '交货数量' '' '' '' ''. " 交货数量
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_alv_init
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_alv_init.
DATA: ls_stable TYPE lvc_s_stbl.
DATA: ls_variant TYPE disvariant.
DATA: lt_toolbar_excluding TYPE ui_functions.
IF go_grid IS INITIAL.
" 实例化容器
CREATE OBJECT go_custom_container
EXPORTING
container_name = go_container " 9001屏幕界面中用户定义的容器名称
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5
OTHERS = 6.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
" 实例化ALV Grid
CREATE OBJECT go_grid
EXPORTING
i_parent = go_custom_container " 实例化的容器对象
EXCEPTIONS
error_cntl_create = 1
error_cntl_init = 2
error_cntl_link = 3
error_dp_create = 4
OTHERS = 5.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
PERFORM frm_alv_set_fields. " 设置Fieldcat以及Layout等属性(ALV格式化)
" 创建实例对象
CREATE OBJECT go_event.
" 指定字段注册F4搜索帮助
gt_f4 = VALUE #( ( fieldname = 'WERKS' register = abap_true getbefore = abap_true ) ).
CALL METHOD go_grid->register_f4_for_fields
EXPORTING
it_f4 = gt_f4.
" 注册事件
SET HANDLER go_event->handle_toolbar FOR go_grid. " 增设自定义按钮
SET HANDLER go_event->after_user_command FOR go_grid. " 按钮响应
SET HANDLER go_event->handle_data_changed FOR go_grid. " 数据变更
SET HANDLER go_event->handle_data_changed_finished FOR go_grid. " 数据变更完成
SET HANDLER go_event->handle_hotspot_click FOR go_grid. " 单击
SET HANDLER go_event->double_click FOR go_grid. " 双击
SET HANDLER go_event->handle_f4_help FOR go_grid. " F4搜索帮助
go_grid->set_ready_for_input( ). " 将ALV设置为可输入状态
" 为ALV报表注册编辑事件
CALL METHOD go_grid->register_edit_event
EXPORTING
i_event_id = cl_gui_alv_grid=>mc_evt_enter " Event Enter(回车)
EXCEPTIONS
error = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 .
ENDIF.
ls_variant-report = sy-repid. " 程序名称
ls_variant-handle = 1.
" 指定隐藏工具栏按钮
APPEND cl_gui_alv_grid=>mc_fg_sort TO lt_toolbar_excluding. " 排序按钮
" 执行ALV显示
CALL METHOD go_grid->set_table_for_first_display
EXPORTING
i_bypassing_buffer = 'X'
is_variant = ls_variant " 布局按钮设置
i_save = 'A'
is_layout = gs_layout
it_toolbar_excluding = lt_toolbar_excluding " 隐藏按钮
CHANGING
it_outtab = gt_item
it_fieldcatalog = gt_fcat
EXCEPTIONS
invalid_parameter_combination = 1
program_error = 2
too_many_lines = 3
OTHERS = 4.
ELSE.
ls_stable-row = 'X'.
ls_stable-col = 'X'.
" 刷新ALV内容
CALL METHOD go_grid->refresh_table_display
EXPORTING
is_stable = ls_stable
EXCEPTIONS
finished = 1
OTHERS = 2.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_event_toolbar
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> E_OBJECT
*&---------------------------------------------------------------------*
FORM frm_event_toolbar USING iv_object TYPE REF TO cl_alv_event_toolbar_set.
DATA: lv_quickinfo TYPE stb_button-quickinfo, " Toolbar quickinfo
lv_icon TYPE stb_button-icon. " Toolbar icon
PERFORM frm_set_toolbar USING 'ZBT01' lv_icon '' lv_quickinfo '编辑' '' 0 iv_object.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_set_toolbar
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> P_
*& --> LV_ICON
*& --> P_
*& --> LV_QUICKINFO
*& --> TEXT_B01
*& --> P_
*& --> P_0
*& --> IV_OBJECT
*&---------------------------------------------------------------------*
FORM frm_set_toolbar USING iv_function TYPE stb_button-function " 功能代码
iv_icon TYPE stb_button-icon " 图标名称
iv_disabled TYPE stb_button-disabled " 按钮是否禁用
iv_quickinfo TYPE stb_button-quickinfo " 图标的快捷信息
iv_text TYPE stb_button-text " 文本
iv_type TYPE stb_button-butn_type " 工具栏按钮类型
iv_pos TYPE i " 按钮插入的位置
iv_object TYPE REF TO cl_alv_event_toolbar_set.
DATA: ls_toolbar TYPE stb_button. " 存储按钮的相关信息(结构体)
CLEAR ls_toolbar.
MOVE iv_function TO ls_toolbar-function.
MOVE iv_icon TO ls_toolbar-icon.
MOVE iv_disabled TO ls_toolbar-disabled.
MOVE iv_quickinfo TO ls_toolbar-quickinfo.
MOVE iv_type TO ls_toolbar-butn_type.
MOVE iv_text TO ls_toolbar-text.
IF iv_pos EQ 0.
APPEND ls_toolbar TO iv_object->mt_toolbar.
ELSE.
INSERT ls_toolbar INTO iv_object->mt_toolbar INDEX iv_pos.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_user_command
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> E_UCOMM
*&---------------------------------------------------------------------*
FORM frm_user_command USING pv_ucomm TYPE sy-ucomm.
DATA: ls_stylerow TYPE lvc_s_styl.
CASE pv_ucomm.
WHEN 'ZBT01'.
LOOP AT gt_item ASSIGNING FIELD-SYMBOL(<lfs_item>).
" 对字段'WERKS'和'DELQTY'设置可编辑功能
IF <lfs_item>-style IS NOT INITIAL.
REFRESH:<lfs_item>-style.
ELSE.
ls_stylerow-fieldname = 'WERKS'.
ls_stylerow-style = cl_gui_alv_grid=>mc_style_enabled.
INSERT ls_stylerow INTO TABLE <lfs_item>-style.
ls_stylerow-fieldname = 'DELQTY'.
ls_stylerow-style = cl_gui_alv_grid=>mc_style_enabled.
INSERT ls_stylerow INTO TABLE <lfs_item>-style.
ENDIF.
ENDLOOP.
" ALV刷新
PERFORM frm_alv_grid_refresh USING go_grid.
WHEN OTHERS.
ENDCASE.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_alv_grid_refresh
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> GO_GRID
*&---------------------------------------------------------------------*
FORM frm_alv_grid_refresh USING io_grid TYPE REF TO cl_gui_alv_grid .
DATA: ls_stable TYPE lvc_s_stbl.
ls_stable-row = abap_true.
ls_stable-col = abap_true.
CALL METHOD io_grid->refresh_table_display
EXPORTING
is_stable = ls_stable
i_soft_refresh = abap_true
EXCEPTIONS
finished = 1
OTHERS = 2.
IF sy-subrc NE 0.
PERFORM frm_disp_sys_msg.
ENDIF.
CALL METHOD cl_gui_cfw=>flush
EXCEPTIONS
cntl_system_error = 1
cntl_error = 2.
IF sy-subrc NE 0.
PERFORM frm_disp_sys_msg.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_disp_sys_msg
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_disp_sys_msg .
MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 DISPLAY LIKE 'E'.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_data_changed
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> ER_DATA_CHANGED
*& --> E_ONF4
*& --> E_ONF4_BEFORE
*& --> E_ONF4_AFTER
*& --> E_UCOMM
*&---------------------------------------------------------------------*
FORM frm_data_changed USING pr_data_changed TYPE REF TO cl_alv_changed_data_protocol
iv_onf4 TYPE char01
iv_onf4_before TYPE char01
iv_onf4_after TYPE char01
iv_ucomm TYPE sy-ucomm.
DATA: lv_fieldname TYPE lvc_fname. " 字段名
FIELD-SYMBOLS:
<lv_modi_value> TYPE lvc_s_modi-value,
<lv_field_value> TYPE any.
LOOP AT pr_data_changed->mt_mod_cells INTO DATA(ls_mod_data).
READ TABLE gt_item ASSIGNING FIELD-SYMBOL(<lfs_output_item>) INDEX ls_mod_data-row_id.
IF sy-subrc = 0.
lv_fieldname = ls_mod_data-fieldname.
ASSIGN ls_mod_data-value TO <lv_modi_value>.
CASE lv_fieldname.
WHEN 'DELQTY'.
" 检查'DELQTY'字段修改后的值是否只包含数字、小数点和空格
IF <lv_modi_value> CO '0123456789. '.
ASSIGN COMPONENT ls_mod_data-fieldname OF STRUCTURE <lfs_output_item> TO <lv_field_value>.
IF sy-subrc = 0 .
<lv_field_value> = <lv_modi_value>.
ENDIF.
ELSE.
" 报错误信息
PERFORM frm_add_protocol_entry USING 'DELQTY' ls_mod_data-row_id pr_data_changed 'E' '000' '' '' '' ''.
ENDIF.
WHEN OTHERS.
ENDCASE.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_add_protocol_entry
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> P_
*& --> LS_MOD_DATA_ROW_ID
*& --> PR_DATA_CHANGED
*& --> P_
*& --> P_
*& --> P_
*& --> P_
*& --> P_
*& --> P_
*&---------------------------------------------------------------------*
FORM frm_add_protocol_entry USING iv_filedname TYPE lvc_fname
iv_rowid TYPE i
io_data_changed TYPE REF TO cl_alv_changed_data_protocol
iv_msgty TYPE syst_msgty
iv_msgno TYPE syst_msgno
iv_msgv1 TYPE syst_msgv
iv_msgv2 TYPE syst_msgv
iv_msgv3 TYPE syst_msgv
iv_msgv4 TYPE syst_msgv.
CALL METHOD io_data_changed->add_protocol_entry
EXPORTING
i_msgid = 'Z_MSG2025' " 消息文本所在的消息类
i_msgty = iv_msgty " 消息类型
i_msgno = iv_msgno " 消息号
i_msgv1 = iv_msgv1
i_msgv2 = iv_msgv2
i_msgv3 = iv_msgv3
i_msgv4 = iv_msgv4
i_row_id = iv_rowid
i_fieldname = iv_filedname.
gv_valid_error = abap_true. " 存在有效的错误
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_changed_finished
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> E_MODIFIED
*& --> ET_GOOD_CELLS
*&---------------------------------------------------------------------*
FORM frm_changed_finished USING pv_modified TYPE char01
pt_good_cells TYPE lvc_t_modi.
" 在满足特定条件刷新ALV
IF pv_modified = abap_true AND pt_good_cells IS NOT INITIAL.
PERFORM frm_alv_grid_refresh USING go_grid. " 刷新ALV
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_hotspot_click
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> E_ROW_ID
*& --> E_COLUMN_ID
*&---------------------------------------------------------------------*
FORM frm_hotspot_click USING ps_row_id TYPE lvc_s_row
ps_column_id TYPE lvc_s_col.
READ TABLE gt_item INTO DATA(ls_item) INDEX ps_row_id-index.
IF sy-subrc = 0.
SET PARAMETER ID 'MAT' FIELD ls_item-matnr.
CALL TRANSACTION 'MM03' AND SKIP FIRST SCREEN.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_double_click
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> E_ROW
*& --> E_COLUMN
*& --> ES_ROW_NO
*&---------------------------------------------------------------------*
FORM frm_double_click USING ps_row_id TYPE lvc_s_row
ps_column TYPE lvc_s_col
ps_row_no TYPE lvc_s_roid.
READ TABLE gt_item INTO gs_item INDEX ps_row_id-index.
" 事件触发时显示当前行的销售订单号
MESSAGE gs_item-vbeln TYPE 'I'.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_on_f4
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> E_FIELDNAME
*& --> E_FIELDVALUE
*& --> ES_ROW_NO
*& --> ER_EVENT_DATA
*& --> ET_BAD_CELLS
*& --> E_DISPLAY
*&---------------------------------------------------------------------*
FORM frm_on_f4 USING iv_fieldname TYPE lvc_fname
iv_fieldvalue TYPE lvc_value
is_row_no TYPE lvc_s_roid
io_event_data TYPE REF TO cl_alv_event_data
it_bad_cells TYPE lvc_t_modi
iv_display TYPE char01.
DATA: ls_modi TYPE lvc_s_modi,
lt_ret_tab TYPE STANDARD TABLE OF ddshretval, " 内表,存储用户在F4搜索帮助窗口中选择的结果
lv_dynprofield TYPE help_info-dynprofld.
FIELD-SYMBOLS: <itab> TYPE lvc_t_modi.
" 从字段目录gt_fcat内表中读取与触发F4帮助的字段名对应的字段目录项,存储在ls_fieldcat结构体中
READ TABLE gt_fcat INTO DATA(ls_fieldcat)
WITH KEY fieldname = iv_fieldname.
CHECK sy-subrc = 0. " 检查上述读取操作是否成功,如果失败则终止当前处理
CASE iv_fieldname.
WHEN 'WERKS'.
" 查询数据
SELECT werks,name1
FROM t001w
INTO TABLE @DATA(lt_t001w).
IF sy-subrc = 0.
SORT lt_t001w BY werks. " 排序
ENDIF.
CLEAR:lv_dynprofield.
lv_dynprofield = iv_fieldname.
" 调用函数显示F4搜索帮助窗口
CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
EXPORTING
retfield = 'WERKS'
value_org = 'S'
window_title = ls_fieldcat-reptext " 标题
dynprofield = lv_dynprofield " Screen Field name
TABLES
value_tab = lt_t001w
return_tab = lt_ret_tab
EXCEPTIONS
parameter_error = 1
no_values_found = 2
OTHERS = 3.
WHEN OTHERS.
ENDCASE.
" 更新ALV数据
ASSIGN io_event_data->m_data->* TO <itab>.
READ TABLE lt_ret_tab INTO DATA(ls_ret_tab) INDEX 1.
IF sy-subrc = 0.
ls_modi-row_id = is_row_no-row_id. " 行号
ls_modi-fieldname = iv_fieldname. " 字段名
ls_modi-value = ls_ret_tab-fieldval. " 选择的值
APPEND ls_modi TO <itab>.
ENDIF.
" 触发修改事件
CALL METHOD cl_gui_cfw=>flush.
io_event_data->m_event_handled = 'X'.
ENDFORM.
INCLUDE程序( zsd002_437_o01)
*----------------------------------------------------------------------*
***INCLUDE ZSD002_437_O01.
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Module STATUS_9001 OUTPUT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
MODULE status_9001 OUTPUT.
SET PF-STATUS '9001_STATUS'.
SET TITLEBAR '9001_TITLE'.
ENDMODULE.
*&---------------------------------------------------------------------*
*& Module ALV_INIT OUTPUT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
MODULE alv_init OUTPUT.
PERFORM frm_alv_init.
ENDMODULE.
INCLUDE程序( zsd002_437_i01)
*----------------------------------------------------------------------*
***INCLUDE ZSD002_437_I01.
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Module USER_COMMAND_9001 INPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
MODULE user_command_9001 INPUT.
CASE ok_code.
WHEN '&BACK' OR '&EXIT' OR '&CANCEL'.
SET SCREEN 0. " 返回上一个屏幕
ENDCASE.
ENDMODULE.
上述代码涉及的消息类、文本元素以及其他内容如下所示
![](https://i-blog.csdnimg.cn/direct/96202c7dcbf44e2d8fde04719e41516e.png)
![](https://i-blog.csdnimg.cn/direct/0e6768d47e3e4adbbb1a4733cb6e3228.png)
![](https://i-blog.csdnimg.cn/direct/f7d2fe53a9dc453bb80a70e6a526c428.png)
![](https://i-blog.csdnimg.cn/direct/1a021489a2d7445da01795f508d66d6f.png)
9001屏幕的元素清单,逻辑流以及布局如下所示
![](https://i-blog.csdnimg.cn/direct/3cc798f60d354bc591d5cf7296386621.png)
![](https://i-blog.csdnimg.cn/direct/0d17afdb12854b0cb8736bf346cb19df.png)
![](https://i-blog.csdnimg.cn/direct/24267f8581c1436ca4b2c9357bae6ced.png)
本文涉及到的具体相关操作可参考以下文章
[SAP ABAP] OOALV 报表练习1(操作讲解)https://blog.csdn.net/Hudas/article/details/145536473?spm=1001.2014.3001.5502